这期内容当中小编将会给大家带来有关如何进行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分析了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/221718.html