【破壳之路】​破壳平台多粒度漏洞查询实践

IoT 1个月前 admin
22 0 0

一、前 言

二、细粒度查询:TP-Link SR20命令执行

三、粗粒度查询:MikroTik CVE-2018-14847

四、总 结




前  言

“破壳之路”是破壳平台推出的一组系列文章,旨在通过复现多种漏洞挖掘过程,深入讲解破壳平台的使用方法。作为该系列的开篇之作,本文将通过两个具体漏洞的复现,展示在面对不同规模的目标时,如何巧妙运用破壳平台进行高效的漏洞挖掘。


细粒度查询:TP-Link SR20命令执行
01

漏洞介绍


该漏洞出现在TP-Link SR20在处理TDDP协议内容时,TDDP(TP-Link设备发现协议,TP-Link Device Discovery Protocol)是一种专有协议,用于在网络中发现和管理TP-Link设备。TDDP协议允许网络管理员通过网络自动发现并配置TP-Link的路由器、交换机和其他设备。其具备以下功能:

  • 设备发现:TDDP可以自动扫描网络,找到所有连接的TP-Link设备。这对于大规模网络管理非常有用,因为管理员不需要手动查找每个设备的IP地址;

  • 设备配置:通过TDDP协议,管理员可以远程配置设备的参数。这可以包括网络设置、安全设置、固件更新等;

  • 设备管理:TDDP还允许管理员监控设备的状态,如在线状态、设备负载等,以便及时进行维护和故障排除。


TDDP协议有两个版本:v1和v2。其中v1不支持身份验证和对数据包载荷的加密,而v2要求身份验证和加密。因此若TP-Link SR20 运行了 V1 版本的 TDDP 协议,在无需认证的情况下,向 SR20 设备的 UDP 1040 端口发送特定数据就可以造成命令注入漏洞。其原理如下:

【破壳之路】​破壳平台多粒度漏洞查询实践

图一

【破壳之路】​破壳平台多粒度漏洞查询实践

图二

【破壳之路】​破壳平台多粒度漏洞查询实践

图三


结合图一可知,recvfrom函数的第一个参数param_1接受信息,然后传递到FUN_00015E74(图二),再次传递到FUN_0000A580(图三)。在FUN_0000A580中,通sscanf(local_c,"%[^;];%s",local_68,local_a8) 语句对其内容以;进行分割,字符串中;前面的部分放入local_68中,;后面的部分放入local_a8中,随后进入FUN_000091dc函数处理流程(图四)。


【破壳之路】​破壳平台多粒度漏洞查询实践

图四


查看变量定义的位置, local_130 是一个指针数组,execve 函数的第二个参数就是指针数组(是 execve 执行程序的命令行参数),这里 execve("/bin/sh",(char **)local_130,(char **)0x0); 这个 local_130 也就是变量 local_68 ,由 vsprintf 函数拼接而成,原始的数据为 FUN_000091dc 函数中调用 sscanf(local_c,"%[^;];%s",local_68,local_a8)进行传递。

所以当控制 TDDP 协议的版本号为v1,然后输入任意命令以;结尾。这里虽然无法使用命令分隔符;,但是&&||并没有进行过滤,依然可以造成命令注入。

02

查询思路与流程


该漏洞的漏洞模式较为清晰,而且分析对象较为简单,可以直接在变量层追踪变量的数据流。这种查询方式较为底层,误报较少,所以在本文中,将这种方式称为细粒度查询。即其是一个典型的污点类型可检测的漏洞,只需要检测有没有从类似recvfrom这样可以被控制的数据引入点,传递到类似于execve这样的危险函数点的数据流。在静态漏洞挖掘中,这种检测方法被称作污点分析。


简单来说,污点分析要做的就是查询可控的数据源source点和危险函数sink点之间是否存在数据流关系。为了用户可以快速进行污点分析,破壳平台提供了VQL.taintPropagation函数给用户使用,其有以下的参数:

List<Long>source

List<Long>sink

Integer flag

List<Long>should

List<Long>shouldNot

  • source为source点ID集合;

  • sink为sink点ID集合;
  • should为期望经过的点ID集合;
  • shouldNot为排除点ID的集合;
  • flag为污点传播的标志位;默认为空,为从source和sink中数量较少的一方开始传递 ,flag=1时为从source到sink进行有向传播,flag=2时为从sink到source进行有向传播,flag=3时进行无向污点分析。

该漏洞的漏洞模式可以用以下的语句表示:

【破壳之路】​破壳平台多粒度漏洞查询实践

第一步:查询recvfrom的第一个参数作为source点集合

【破壳之路】​破壳平台多粒度漏洞查询实践

第二步:查询execve的第二个参数作为sink点集合

【破壳之路】​破壳平台多粒度漏洞查询实践

第三步:使用污点查询原语查询可达路径

【破壳之路】​破壳平台多粒度漏洞查询实践

最后产生的结果如图五所示,即通过污点分析最后定位了漏洞所在位置:

【破壳之路】​破壳平台多粒度漏洞查询实践

图五



粗粒度查询:MikroTik CVE-2018-14847
01

漏洞介绍


MikroTik作为网络基础设施供应商,RouterOS 是 MikroTik 的旗舰软件产品,在线运行RouterOS 系统的设备至少有 300 万台。


本次复现的漏洞是CVE-2018-14847的一个目录遍历漏洞,漏洞原理网络上,参考文献比较多,本文的重点需要理解这种漏洞模式,然后如何编写脚本。该漏洞的流程如图六所示:

【破壳之路】​破壳平台多粒度漏洞查询实践

图六


1. 首先nv::message::get_string函数的第一个参数v73是一个可控的变量,而sub_804FCFA函数是一个赋值作用的函数,其将v73的值传递给了p_path

2. 追寻p_path的来源,可见p_path的值来源于(string *)(v5+3)

3. 由于v5[3]v5+3指向同一块地址,而v5[3]的值又传递给了v11

4. v11的值最后传到了open的第一个参数,导致目录遍历漏洞形成。

02

供给面分析


使用ps -a 查看routeros中运行的进程,发现许多进程都是/nova/bin目录下的二进制文件所启动的。通过逆向分析可知,用户发送的数据通过80端口或8291端口进行处理后,会通过进程间通信的方式转发给对应的nova/bin目录下的二进制文件进行处理。因此,我们可以将nova/bin目录下的二进制文件一起打包上传到破壳平台上进行分析。

【破壳之路】​破壳平台多粒度漏洞查询实践
03

初步分析


在该漏洞案例中,因为分析的对象比较多,如果直接对所有分析对象使用污点传播,速度会非常慢,所以我们这里使用函数调用图(call-graph)来对疑似点进行过滤。与上文介绍的细粒度查询不同的是函数的抽象程度更高,是一种更上层的查询,所以在本文中称作粗粒度查询。


函数调用图是一种图形表示方式,用于描述程序中函数或方法之间的调用关系。在函数调用图中,每个函数或方法被表示为一个节点,函数或方法的调用关系被表示为边。


既然是图,那么一定有节点和边,由于该图还是一张有向图,那么就存在方向。在函数调用图中,节点的类型应该全是函数或方法,但是通过调用和被调用关系分为caller和callee,caller指的是调用其他函数的函数。‌在函数调用过程中,‌caller负责执行函数调用操作,‌即将控制权转移到被调用的函数(‌callee)‌中;callee则是指被调用的函数,‌即接收来自caller传递的参数并执行相应操作的函数。根据上面的关系caller有一条边函数调用边指向callee,代表在caller中调用了callee,在破壳中记作(caller)-[:cg]→(callee)。


如果大家希望通过自己变成来生成二进制文件的函数调用图,可以借助ghidra和其提供的API,具体实现代码可参考https://github.com/HackOvert/GhidraSnippets。

基础知识介绍完毕,下面就可以开始编写语句进行分析。


首先,需要明确该漏洞是一个目录遍历漏洞,那么其对应的危险参数是open,所以基本思想就是寻找哪些函数具有open函数的调用链。可以获得下面的语句:

【破壳之路】​破壳平台多粒度漏洞查询实践

这条语句是获得的一条较好的cg查询实践,下面将对其分解说明:

1. 首先我们查询函数调用关系p=((m:function)-[:cg*1..]->(n:function{name:"open"}))的含义是查询哪些函数调用了函数名为open的函数,记作m;同时通过(k:file)-[:own]->(m)查询函数m归属于哪个文件,记作k

2. 因为函数调用图cg会查询出来很多子路径,所以通过WHERE not ()-[:cg*]->(m)限制输出的路径path,使得查询出来的函数调用链是最长的,因为m是没有前继节点的;

3. 第三步是是将查询出来的路径p重命名为path_setk重命名为own_file

4. 由于查询出来的结果全是Path和Node这种特殊结构,不方方便查看,所以通过[p IN nodes(path_set)|p.name],提取函数调用路径path_set中所有节点集合,并提取出其中所有节点的名称,即函数调用名称;最后提取own_file的name来展示其位于哪个二进制。


通过上述语句查询出来的结果有80多条,通过人工审计还有一些难度。

04

细化分析


通过初步分析查询出80多条结果,可以把重点放在认证前的逻辑上,routeros通过下面的set_policy函数对进程间通信的接口进行鉴权,其中第三个参数如果是0的话就说明这个接口是无需认证的,代码中的表示如图七所示:

【破壳之路】​破壳平台多粒度漏洞查询实践

图七


使用破壳平台对所有set_policy的第三个参数为0的调用处进行检测:

【破壳之路】​破壳平台多粒度漏洞查询实践

在这条查询语句中,(f:file)-[:own]->(:function)<-[:use]-(:operator)-[:ast]->(n:const)是指在文件f中找到归属于这个文件的常量n,这个常量n必须是set_policy函数的第三个参数,且值为0


如下图八所示,发现在众多进程中只有以下四个文件中拥有未鉴权接口:

【破壳之路】​破壳平台多粒度漏洞查询实践

图八


此时再针对这几个进程进行open函数的调用栈查询,并且保证open函数的参数为一个变量。查询命令如下:

【破壳之路】​破壳平台多粒度漏洞查询实践

1. 首先第一行是查询open的第一个参数是变量,同时避免进入plt表,所以这个变量所在的函数不是open,并将调用open的函数记作func_set

2. 后面两行和上述的代码初步分析的流程和思想一样,只不过,其中加入了限制,需要在[“console”,”mepty”, “mproxy”, “user”]这些文件里面。


这时函数调用栈的结构如图九所示,只剩22条,此时可以根据这个结果进行人工排除。

【破壳之路】​破壳平台多粒度漏洞查询实践

图九


经过人工确认,最后认证前目录穿越如下,此处open的路径没有经过检测。也即是查询到的[“FUN_0805016a”]这条函数调用栈,而这个地方就是CVE-2018-14847的漏洞位置。


如果还要进行细化分析,那就需要借助污点分析的能力了,将nv::message::get_string的第一个函数作为sourceSet,将open的第一个参数作为sinkSet,查看之间是否存在可达数据流。

【破壳之路】​破壳平台多粒度漏洞查询实践

运行完还剩下5条结果,如图十所示,除了已知漏洞,目标均在console二进制文件当中,经过人工识别,其余四条均认证后,且后续有拼接后缀,利用困难。

【破壳之路】​破壳平台多粒度漏洞查询实践

图十


第一处:

【破壳之路】​破壳平台多粒度漏洞查询实践


第二处:

【破壳之路】​破壳平台多粒度漏洞查询实践


第三处:

【破壳之路】​破壳平台多粒度漏洞查询实践


第四处:本文所述漏洞位置

【破壳之路】​破壳平台多粒度漏洞查询实践
【破壳之路】​破壳平台多粒度漏洞查询实践
【破壳之路】​破壳平台多粒度漏洞查询实践


第五处:

【破壳之路】​破壳平台多粒度漏洞查询实践
【破壳之路】​破壳平台多粒度漏洞查询实践

总  结

在实际漏洞挖掘过程中,面对不同的分析对象的时候,若需考虑时间成本,往往通过不同粒度的查询方式是一个不错的选择。


本文主要介绍了面对不同的目标时,在破壳平台上针对不同粒度的程序元素编写不同的语句,来快速地进行漏洞筛查。利用函数调用图进行粗粒度查询的优势就是在分析关系复杂的对象时能快速定位漏洞,相比于直接使用污点分析进行细粒度查询可以更换快速搜索获得结果,但劣势就显而易见,就是相较于污点分析,其精度较差,会有较多误报,需要更高的人工审计成本。


本文中提及的两个漏洞项目已在破壳平台示例项目中上线(https://poc.qianxin.com/example-project),感兴趣的同学可以注册破壳平台,进入示例项目,查看分析结果或者复制为私有项目进行破壳分析。

【破壳之路】​破壳平台多粒度漏洞查询实践






 破壳平 

POC.QIANXIN.COM

破壳平台(poc.qianxin.com),由奇安信天工实验室研发的交互式漏挖平台,是国内第一款在线查询式二进制漏洞挖掘工具。平台基于静态程序分析技术,帮助用户发现二进制代码零日漏洞。


【破壳之路】​破壳平台多粒度漏洞查询实践
每周三更新一篇技术文章  点击关注我们吧!


原文始发于微信公众号(奇安信天工实验室):【破壳之路】​破壳平台多粒度漏洞查询实践

版权声明:admin 发表于 2024年8月14日 上午11:34。
转载请注明:【破壳之路】​破壳平台多粒度漏洞查询实践 | CTF导航

相关文章