-
-
[原创] Ret2Libc实战之利用VirtualProtect
-
发表于:
2019-3-18 00:21
10014
-
[原创] Ret2Libc实战之利用VirtualProtect
说明:本实验来源于《0day安全:软件漏洞分析技术》(第二版)第12章
如有不当之处,还请各位前辈指正,谢谢!
这个实验的原理是通过调用VirtualProtect
函数来将某快内存的属性设置为可执行,这样就可以把shellcode插在这块内存并执行。
VirtualProtect()函数的原型为如下
各个参数分别表示:
lpAddress
:要修改访问保护属性的内存地址。
dwSize
:修改的内存大小(以字节计)。
flNewProtect
:要设置的访问保护属性(本次实验设为0X40)。
lpflOldProtect
:内存原始属性类型保存的地址(要是一个可写的内存)。
详细信息可以参考MSDN:VirtualProtect
VirtualProtect
函数的具体实现过程如下:
可以看出,VirtualProtect
会将EBP+8
~ EBP+0X14
十六个字节存放的数据作为四个参数调用VirtualProtectEx
函数。
操作系统:Windows XP SP3 (开启DEP保护)
编译器:VS2008(关闭GS,生成release版本、禁止优化)
由于VirtualProtect
函数的第二和第三个参数分别是0XFF(dwSize
)和0X40(lfNewProtect
)都含有0X00,所以不能用strcpy
函数来拷贝shellcode,而是要用memcpy
函数来指定一个比较大的字符串才能将shellcode复制到可执行区域。
首先用0X90909090覆盖test函数的EBP,用修正EBP的指令(PUSH ESP, POP EBP, RETN 4)地址来覆盖test函数的返回地址。shellcode布置如下:
编译后用OD打开调试,在执行完memcpy函数后停下观察此时stack的分布情况:
继续执行,当执行完PUSH ESP, POP EBP 后EBP的值如下:
可以发现0X12FEAC还没有被填充,接下来要将EBP+8
~ EBP+0X14
布置为VirtualProtect
函数的四个参数,但是第一个(lpAddress
)和第四个参数(lpflOldProtect
)需要动态确定,可以用PUSH ESP指令将stack中的地址分别压入EBP+8
和EBP+0X14
。执行第一次PUSH ESP前要保证ESP指向EBP+C
处,第二次执行PUSH ESP前ESP指向EBP+0X18
。执行完第一个PUSH ESP后让ESP 指向EBP+0X18
,可以使用4条POP指令,但是要想控制程序流程还需要有一个RETN指令来确保对程序流程的控制。因为执行RETN指令会使ESP加4,所以可以使用三条POP指令加一条RETN指令。这里选择用JMP EAX来跳到POP POP POP RETN指令处,所以还要再执行JMP EAX之前将EAX指向POP POP POPR ETN指令的地址。
重新布置shellcode:
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2019-3-18 09:31
被kanxue编辑
,原因: