对 libssh2 整数溢出破绽 (CVE-2019-17498)的剖析 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

对 libssh2 整数溢出破绽 (CVE-2019-17498)的剖析

申博_新闻事件 申博 36次浏览 未收录 0个评论

申博官方网

申博官方网是菲律宾申博娱乐的正版唯一官网,游戏界面流畅,游戏类别涉及内容丰富,申博开户简单,游戏教程全面,稳赚不赔,目前已有众多用户获得了良好的体验感,乐与利双收,除了申博别无他选。在玩乐中轻松投资就能拿到高收益,即刻加入,无需犹豫,这是一家来了你就不想走的娱乐网站!

,

0x01 破绽发掘

在2019年3月18日,Canonical Ltd.的Chris Coulson披露了libssh2中的九个破绽(CVE-2019-3855至CVE-2019-3863)。这些破绽已在libssh2 v1.8.1中修复。当时,我的同事Pavel Avgustinov注意到,修复破绽的报告在LGTM上引入了多个新告警。这些告警是由于像下面的代码:

 if((p_len = _libssh2_get_c_string(&buf, &p)) < 0)

题目出现在_libssh2_get_c_string返回 -1是一个error code,然则p_len没有标记,因而毛病前提将被疏忽。libssh2团队已在后面的的报告中修复了这些题目,然则它促使我们细致检察代码以检察其包含显著毛病的破绽。我们很快发明了这个用于边境搜检的函数:

 int _libssh2_check_length(struct string_buf *buf, size_t len)
 {
     return ((int)(buf->dataptr - buf->data) <= (int)(buf->len - len)) ? 1 : 0;
 }

此函数的题目在于强迫转换int可以会溢出。左边的强迫转换是平安的,由于的字段buf是受信托的值,然则右边的强迫转换是不平安的,由于的值len是不受信托的。建立破绽应用exp并不是难事,该破绽应用使值len大于绕过此溢出搜检buf->len + 0x80000000。可以在GitHub上找到PoC 。

我厥后相识到,该题目_libssh2_check_length是在1.8.2版宣布后在重要开辟分支上引入的,因而破绽局限搜检在1.8.2版中不存在。不幸的是,版本1.8.2不包含任何边境搜检,因而PoC依然有用。在1.8.2版中,破绽的源位置是kex.c:1675。题目在于个中p_len包含一个不受信托的值,因而后续的读取s可以会超出局限。由于_libssh2_check_length在1.8.2版中不存在,所以不须要将值p_len大于0x80000000触发破绽。这意味着较小的值len可以触发越界读取,该破绽更有可以被应用来完成长途信息泄漏。

0x02  negative error codes 转换为 unsigned

当我和我的同事正在检察破绽补丁报告时,我们注意到一种罕见的毛病模式,个中将negative error返回值强迫转换为unsigned。这是一个异常轻易犯的毛病,而且它没有被编译器正告所](https://godbolt.org/z/CvqwDm)捕捉。所以我写了这个简朴的查询来查找破绽实例:

 import cpp
 import semmle.code.cpp.dataflow.DataFlow
 import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
 
 from Function f, FunctionCall call, ReturnStmt ret, DataFlow::Node source, DataFlow::Node sink
 where call.getTarget() = f
 and ret.getEnclosingFunction() = f
 and ret.getExpr().getValue().toInt() < 0
 and source.asExpr() = call
 and DataFlow::localFlow(source, sink)
 and sink.asExpr().getFullyConverted().getType().getUnderlyingType().(IntegralType).isUnsigned()
 and lowerBound(sink.asExpr()) < 0
 select sink

查询代码以下:

 r_len = _libssh2_get_c_string(&buf, &r);
 if(r_len <= 0)
     return -1;

该查询会返回负整数常量的函数。比方,_libssh2_get_c_string在773行上实行此操纵,然后,它将查找对该函数的挪用,这些挪用返回值并将其转换为无标记范例。

0x03 触发破绽

破绽的源位置是packet.c:480:

 if(message_len < datalen-13) {

值datalen不受信托,由于它是由长途SSH服务器掌握的。比方,假如运用datalen == 11,则减法将溢出而且的边境搜检message_len无效。message_len是一个32位无标记整数,它也由长途SSH服务器掌握,因而这可以致使在第485行上越界读取:

 language_len =
     _libssh2_ntohu32(data + 9 + message_len);

越界读取一般只会致使分段毛病,然则LIBSSH2_DISCONNECT在 第499行的挪用中也有可以致使其他范例的题目:

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

取决于libssh2库的运用体式格局,由于session->ssh_msg_disconnect是一个回调函数,默许状况下为null,但可以由该库的用户设置(经由历程挪用libssh2_session_callback_set)。

红队渗透测试技术:如何通过鱼叉式网络钓鱼获得攻击机会?

关于红队在渗透测试中使用的网络钓鱼攻击的文章很多,不过大多数的介绍都是不完整的。在本文中,我们将对这个话题进行一次完整的梳理,包括域创建,制作网络钓鱼内容,绕过垃圾邮件过滤器和电子邮件网关,生成不可检测的有效载荷以及绕过Windows保护(例如AMSI)的注意事项。另外,我们还在这篇文章的末尾整理了一份参考文献,如果你感兴趣可以参考。 出于安全原因,渗透测试中的客户名称和相关信息已被匿名化。根据红色团队参与的复杂程度和持续时间,你需要衡量你在以下每个项目

我编写了一个 破绽PoC ,个中歹意SSH服务器运用datalen == 11和返回断开衔接音讯message_len == 0x41414141,会致使libssh2因分段毛病而崩溃。

0x04 libssh2中整数溢出的变体剖析

我在2019年6月尾之前写了关于libssh2的末了一篇博客文章。为了正确相识该博客文章的技术细节,我须要回过头来再看一下libssh2代码。我注意到很多大意的边境搜检代码,比方上述毛病。

变体剖析是关于破绽的一切变体,并在可以的状况下,建立可在多个代码库之间重用的查询。然则我的目标集合在libssh2和我发明的破绽上。

当我向供应商报告平安破绽时,一般会尝试在报告中包含两点:

1. 一个破绽的PoC。

2. 一个QL查询,它标识了我以为存在破绽的的一切代码位置。

QL查询和PoC有几个优点:

1. 假如代码中包含几个异常类似的毛病,那末我可以编写一个枚举一切破绽的查询。

2. 该查询使我可以轻松地搜检破绽是不是已修复(在90天的末了限期行将到期时,这异常轻易)。

3. 我可以将QL查询及其效果列表作为单个URL包含在内,这对我来讲很轻易,愿望对吸收者也很轻易。

编写PoC一般须要大批事情,因而,假如存在多个异常类似的破绽,那末我一般只为个中一个编写PoC。我的觉得是,一个PoC足以证实平安影响是实在的。下面的查询针对此用例进行了调解,该查询的目标不是在libssh2中找到一切整数溢出破绽,而且由于查询中编码了某些libssh2特定的细节,它也不会扩展到其他代码库。

 /**
  * @kind path-problem
  */
 
 import cpp
 import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
 import semmle.code.cpp.dataflow.TaintTracking
 import DataFlow::PathGraph
 
 class Config extends DataFlow::Configuration {
   Config() { this = "_libssh2_ntohl bounds check overflow" }
 
   override predicate isSource(DataFlow::Node source) {
     source.asExpr().(FunctionCall).getTarget().getName().matches("_libssh2_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 sink
 where cfg.hasFlowPath(source, sink)
 select sink, source, sink,
   "possible integer overflow of tainted expression in bounds check"

该查询与我的同事FermínSerna针对U-Boot NFS破绽编写的查询异常类似。该isSource可以找出_libssh2_ntohu32和_libssh2_ntohu64,用于收集主机字节递次转换。它查找包含可以会溢出的子表达式的比较操纵。比方,message_len < datalen-13是一个比较表达式,个中子表达式datalen-13可以会溢出。我的查询还覆盖了可选isAdditionalFlowStep,我对该谓词进行了调解,以生成准确的近似变体破绽列表。

0x05  减缓步伐

这不是openssh中的破绽,因而它不会影响ssh(https://linux.die.net/man/1/ssh)。 libssh2是客户端C库,使应用程序可以衔接到SSH服务器。其次,这不是libssh的破绽,后者是一个不相关的C库,供应与libssh2类似的功用。

该破绽存在于libssh2 1.8.2和更早版本中,已在libssh2版本1.9.0中获得修复。除了升级到1.9.0版以外,没有任何减缓此破绽的要领。

该破绽是越界读取,可以致使长途信息泄漏。运用libssh2衔接到歹意SSH服务器时将触发该事宜。溢出发生在Diffie Hellman密钥交流时期,可以在完成身份验证之前在衔接历程的初期触发破绽。libssh2吸收uint32_t来自歹意服务器的要求,而且对此没有任何限定。然后,libssh2从所指定的偏移量中读取uint32_t内存。我写了一个破绽PoC,个中歹意的SSH服务器返回异常大的偏移值,这会致使libssh2因分段毛病而崩溃。然则,我以为,更细致挑选的偏移量可以会致使信息泄漏,由于读取的内存随后会返回给服务器。可应用性将取决于客栈规划,由于libssh2只是一个库,因而将依据运用该库的应用程序而有所不同。

本文翻译自:https://blog.semmle.com/libssh2-integer-overflow-CVE-2019-17498/


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明对 libssh2 整数溢出破绽 (CVE-2019-17498)的剖析
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址