首页
社区
课程
招聘
[原创]#30天写作挑战#双向进攻:分析tcpdump DOS漏洞成因
发表于: 2020-9-11 09:51 15143

[原创]#30天写作挑战#双向进攻:分析tcpdump DOS漏洞成因

2020-9-11 09:51
15143

这个漏洞k0shl有分析过,我也是看了他的分析才决定自己分析一遍的,最终得到的结论也有一些差异。此外,由于tcpdump本身就是有源码的,所以我是从源码和gdb动态调试两个方向同时进行分析,更加方便理解。

kali 2020.3 x86

该文件可以通过运行上面的python文件获得。

24字节pcap_file_header

16字节pcap_pkthdr

数据

更详细的介绍会在3.1 构建自己的poc中。

使用gdb执行tcpdump,然后执行run -r crash,因为访问未授权地址,程序停止执行:

执行bt命令查看函数调用栈:

从该命令的输出中,可以看到漏洞出现时的函数调用情况,以及每个函数所在的文件及其位置。总结如下表:

从上面的信息,我们知道漏洞的发生是由于打印时引用了非法地址,但究竟是如何做到这一点的,还需要进一步分析。

跟随文件名及行数信息,找到savefile.c中的pcap_offline_read函数源码,在该文件的400行,有一个函数调用status = p->next_packet_op(p, &h, &data);,从该代码无法确定究竟调用了哪个函数,所以回到gdb,在pcap_offline_read函数处下断点b pcap_offline_read,然后执行run -r crashn步进到该处函数调用,s步入:

发现该函数为sf-pcap.c文件399行的pcap_next_packet,打开该文件定位到函数位置,回到gdb步进查看函数执行流程。

根据上面对于执行流程的监控,可以发现pcap_next_packet函数根据数据包头部的caplen信息读入了8字节的数据0x0600ff40 0x007f72a0。也就是说,pcap_offline_read函数中的status = p->next_packet_op(p, &h, &data);语句,参数data最终指向的就是这8字节数据,参数地址为0x5ed560

回到pcap_offline_read函数,第409行,执行了(*callback)(user, &h, data);,即print_packet函数。

找到tcpdump.c文件中的print_packet函数:

其中h就是之前读取的头部信息,sp就是8字节的数据。

需要注意的地方来了!

这里调用的就是print-802_15_4.c 中的 ieee802_15_4_if_print函数,在该函数的最后,调用了ndo_default_print

之后的两个函数只是在添加参数的基础上调用新的函数,并没有什么内容:

直接查看hex_and_ascii_print_with_offset函数:

该函数使用参数length计算了一个长度用来控制循环,然后逐步访问参数cp(也就是从数据包读入的数据)指向的内存空间,也就是这里发生了越界访问,导致了拒绝服务。

现在我们需要回顾一下length参数究竟是什么了!

可能你会认为这个length就是之前读入的caplen,也就是0x8,但事实并非如此。

上一小节中有一个加粗字体不知道你有没有注意到,就是在 ieee802_15_4_if_print函数中,caplen的值发生了变化。

让我们在gdb中跟进一下这个函数,同时和源码对应,看一下这个函数做了一些什么:

根据上面的调试结果,该函数会对读取出来的数据中的前两个字节进行一些运算,计算出ieee802.15.4包的头部长度,这里计算出来的是0x12,而ieee802.15.4包的总长度也只有0x8,再减去前3个字节,最后得到的传入ndo_default_print的参数caplen就是一个负数了。

注:这里的计算涉及到了ZigBee包格式的问题,感兴趣的朋友可以参考这个网址

接下来我们直接在gdb中步进到hex_and_ascii_print_with_offset函数内,看一下长度计算那里的结果是什么。这里从汇编代码比较好:

注意到除法操作(右移一位)之后,原本的负数变成了极大的正数。

注意这里循环停止的判断方式,函数使用baseAddress+nshorts*2的方式计算截至地址,但是由于整数溢出,导出结果小于基地址。这就导致判断循环结束的条件无法到达,函数会一直从基地址0x5ed575开始遍历,最终访问到未授权的内存地址。

poc的python代码本身并没有什么需要分析的地方,就是把crash数据包的内容写入到了crash文>件中,所以主要是看一下crash文件的内容。再次贴一下它的内容:

0000h: D4 C3 B2 A1 02 00 04 00 | 00 00 00 F5 FF 00 00 00
0010h: 49 00 00 00 E6 00 00 00 | 00 80 00 00 00 00 00 00
0020h: 08 00 00 00 00 3C 9C 37 | 40 FF 00 06 A0 72 7F 00
0030h: 00 01 7F 00 00 EC 00 01 | E0 1A 00 17 67 2B 2B 2B
0040h: 2B 2B 2B 2B 85 C9 03 00 | 00 00 10 A0 26 80 18 27
0050h: 78 66 65 24 00 01 00 00 | 40 0C 04 02 08 0A 27 2C
0060h: 20 27 00 00 00 00 00 00 | 00 00 01 03 03 04

1.4 crash文件介绍中,我已经简单介绍了该数据包的内容和结构。根据上面对于漏洞的分析,产生漏洞的主要原因就是内容中加粗的两个部分,这两部分的内容导入最终代码计算出来的ieee802.15.4包内容的长度是负数,从而产生整数溢出。

所以该漏洞的出现和00 3C 9C 37没有关系,也和0030h-006Dh的内容没有关系。

那么下面这个数据包应该也会引发漏洞:

我使用上面的数据构建了一个crash1文件,在命令行执行tcpdump -r crash1,确实引发的漏洞:

所以如果想要自己构建一个针对该漏洞的poc,只要了解pcap文件的格式就可以了。

上面的数据中,凡是没有明确要求的全部设成了0。注意caplen字段,以及数据部分的前两个字节其实也不是固定的,只要最后能够计算出负数的长度就可以,可以根据源码自己选取字段内容。

最后组合成的数据包为:

使用tcpdump打开该数据包,也成功引发了漏洞。

把python代码中的buffer改成自己构建的crash文件内容,就是一个完整的poc了。

 
 
 
 
 
 
 
 
 
 
 

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 4
支持
分享
最新回复 (3)
雪    币: 292
活跃值: (810)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
2
感谢楼主指出我当时文章的错误之处,已将本文链接同步至我的博客供读者对比,当时我处于刚刚接触二进制入门时期,分析的不够细致之处以及一些错误请见谅,再次感谢楼主分享。
2020-9-11 10:08
0
雪    币: 26245
活跃值: (63287)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
3
感谢分享!
2020-9-11 10:10
0
雪    币: 12016
活跃值: (10399)
能力值: ( LV13,RANK:660 )
在线值:
发帖
回帖
粉丝
4
Keoyo 感谢楼主指出我当时文章的错误之处,已将本文链接同步至我的博客供读者对比,当时我处于刚刚接触二进制入门时期,分析的不够细致之处以及一些错误请见谅,再次感谢楼主分享。
2020-9-11 10:17
0
游客
登录 | 注册 方可回帖
返回
//