如何进行libssh2整形溢出漏洞CVE-2019-17498分析

这期内容当中小编将会给大家带来有关如何进行libssh2整形溢出漏洞CVE-2019-17498分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

严重性与缓解方案

   该漏洞并不是一个Openssh漏洞,所以它不会影响ssh。Libssh3是一个客户端C代码库,它能够帮助应用程序与SSH服务器建立连接。而且该漏洞也不是一个libssh漏洞,因为libssh并非C代码库,只不过它的功能跟libssh3类似而已。

该漏洞存在于libssh3 v1.9.0及更早版本之中,目前该漏洞已经在libssh3的master分支成功修复,但是官方并没有发布包含漏洞修复方案的正式版。

该漏洞涉及到越界读取的问题,并有可能导致目标服务出现拒绝服务或远程信息披露的风险。当libssh3被用来跟恶意SSH服务器建立连接时,便有可能触发该漏洞。当SSH服务器发送一条断开连接消息时,便会发生溢出。这也就意味着,该漏洞可以在连接过程的开始阶段,及身份认证完成之前被触发。

触发漏洞

该漏洞的原始位置位于packet.c:480处:

if(message_len < datalen-13) {

datalen的值是一个不受信的值,它由远程SSH服务器控制。如果datalen==11,那么减法运算将会发生溢出,针对message_len的越界检测将会失效。Message_len是一个无符号的32位整型,它的值同样由远程SSH服务器控制,所以这将导致第485行代码发生越界读取:

language_len =_libssh3_ntohu32(data + 9 + message_len);

越界读取通常来说会导致分段错误,但是本文所描述的问题将有可能导致代码调用第499行的LIBSSH2_DISCONNECT:

if(session->ssh_msg_disconnect) {    LIBSSH2_DISCONNECT(session, reason, message,                       message_len, language, language_len);}

具体情况取决于libssh3库是如何被使用的,因为session->ssh_msg_disconnect是一个回调函数,默认为NULL,但是用户也可以通过调用libssh3_session_callback_set来自行设置。

我在这里专门写了一个漏洞利用PoC:【点我获取】。它模拟了一个恶意SSH服务器,可以返回包含datalen==11和message_len==0x41414141的断开连接消息,这将导致libssh3出现分段错误并发生崩溃。

Liibssh3整型溢出变种分析

当我在将一个安全漏洞报告给厂商时,我通常会在报告中包含两个内容:

1、漏洞的漏洞利用代码PoC;

2、QL查询,识别所有我认为需要修复的代码位置;

在PoC中包含QL查询,个人认为有以下好处:

1、如果代码包含多个相似的漏洞,那么我们就可以编写一个查询请求来枚举它们。

2、QL查询可以帮助我快速判断漏洞是否成功被修复。

3、QL查询可以将结果以单独URL的形式呈现给我,便于我们进行后续分析。

创建一个PoC通常涉及到大量的工作,如果某个目标存在多个非常相似的漏洞,那我一般会针对其中一个漏洞写一个PoC,因为一个PoC足以证明漏洞的影响了。这个查询的目的并不是找到libssh3中所有的整形溢出漏洞,它的主要目的是找出该PoC触发的漏洞以及其他的相似变种。

Semmle QL查询代码如下:

/** * @kind path-problem */import cppimport semmle.code.cpp.rangeanalysis.SimpleRangeAnalysisimport semmle.code.cpp.dataflow.TaintTrackingimport DataFlow::PathGraphclass Config extends DataFlow::Configuration {  Config() { this = "_libssh3_ntohl bounds check overflow" }  override predicate isSource(DataFlow::Node source) {    source.asExpr().(FunctionCall).getTarget().getName().matches("_libssh3_ntoh%")  }  override predicate isSink(DataFlow::Node sink) {    convertedExprMightOverflowNegatively(sink.asExpr()) and    exists(RelationalOperation cmp | cmp.getAnOperand() = sink.asExpr())  }  override predicate isAdditionalFlowStep(DataFlow::Node source,                                          DataFlow::Node target) {    exists(Field f |      source.asExpr() = f.getAnAssignedValue() and      target.asExpr() = f.getAnAccess())    or    target.asExpr().(AddExpr).getAnOperand() = source.asExpr()    or    target.asExpr().(SubExpr).getAnOperand() = source.asExpr()  }}from Config cfg, DataFlow::PathNode source, DataFlow::PathNode sinkwhere cfg.hasFlowPath(source, sink)select sink, source, sink,  "possible integer overflow of tainted expression in bounds check"

其中,isSource表示寻找到了针对_libssh3_ntohu32和 _libssh3_ntohu64的调用,它们主要用来进行网络至主机的字节顺序转义。这些函数一般都可以用来寻找那些“攻击者控制的数据”。但是我这里使用的isSink目的是寻找对比晕眩,其中包含可能发生溢出的子表达式。比如说,message_len < datalen-13是一个比较表达式,而datalen-13则有可能发生溢出。我的查询还会重写isAdditionalFlowStep选项,并自定义数据流边界集。

上述就是小编为大家分享的如何进行libssh2整形溢出漏洞CVE-2019-17498分析了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注蜗牛博客行业资讯频道。

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:niceseo99@gmail.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

评论

有免费节点资源,我们会通知你!加入纸飞机订阅群

×
天气预报查看日历分享网页手机扫码留言评论Telegram