首页
社区
课程
招聘
[原创] Ret2Libc实战之利用VirtualProtect
发表于: 2019-3-18 00:21 10014

[原创] Ret2Libc实战之利用VirtualProtect

2019-3-18 00:21
10014

说明:本实验来源于《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+8EBP+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编辑 ,原因:
收藏
免费 4
支持
分享
最新回复 (3)
雪    币: 2282
活跃值: (426)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
前排支持下!
2019-3-22 10:19
0
雪    币: 314
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
大佬,我也要学
2019-3-22 10:29
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
请问,push esp jmp eax这条指令您是怎么找到的?书上也没有提到具体的方法,ollyfindaddr好像也没有对应的搜索指令吧?
2020-2-20 08:34
0
游客
登录 | 注册 方可回帖
返回
//