码迷,mamicode.com
首页 > 其他好文 > 详细

Ret2Libc 练习(1) -- ZwSetInformationProcess

时间:2015-09-22 01:15:35      阅读:283      评论:0      收藏:0      [点我收藏+]

标签:

  花了两个小半晚上的时间将0day安全这本书的绕过DEP的第一个实验做了,这里做些笔记。

  Ret2libc 我现在自己的理解就是在开启DEP保护的情况下,在程序的其他的可执行位置找到可以满足我利用要求的指令,形成一个可执行的指令序列,达到成功执行shellcode的目的。

  那么利用Ret2libc的第一个方法就是通过ZwSetInformationProcess函数,这个API可以直接将进程中的DEP保护关闭,执行shellcode。

  首先需要了解的是一个进程的DEP标识是在KPROCESS结构中的_KEXECUTE_OPTIONS中,_KEXECUTE_OPTIONS的具体结构是这样子的:

  技术分享

  标识位的前4bit和DEP相关,当DEP开启Pos0置1,DEP关闭Pos1置1,Pos3置1表示标识位都不能修改,所以影响DEP状态的是前2位,只需要设置成00000010就可以。

  接下来是ZwSetInformationProcess函数:

  技术分享

  ZwSetInformationProcess函数的第一个参数显而易见是进程的句柄,设置为-1的时候标识当前进程,第3个参数是用来设置_KEXECUTE_OPTIONS的,只需要这个参数二进制值最后两位是01即可,第四个参数是第三个参数的长度。

  接下来是具体的实验步骤:

  根据书上的指导,用了OllyFindAddr这个插件,Disable DEP -> Disable DEP<==XP SP3搜索,不太清楚为什么是从这里开始而不是直接跳到ZwSetInformationProcess函数的入口,这里留个疑问,用了这个插件OD搜索到的地址同样是0x7c93cd24, 指向的汇编指令是CMP AL,1,所以为了满足这个判断条件,第一步是找到将AL赋值为1的指令,所有 的MOV EAX,0x1  ; MOV AL,1 理论上都可以,这里我用了ID的mona插件,查找到相应的指令的地址就ok,为了稳妥,选用了和书上一样的地址,所以我的ROP链现在是这样 :

"\x52\xe2\x92\x7c" // MOV AL,1
"\x24\xcd\x93\x7c" // 关闭DEP的起始地址

  当然ROP链会根据出现的情况进行调整,接下来正如同书上写的情况同样,运行到对EBP-4这个地址写数据的时候出现异常了,原因是之前的字节覆盖了EBP-4这个地址内容,所以程序写入了一个无效的地址,需要修正EBP,然后运行到此查看各个寄存器的值,发现ESP的值适合赋给EBP,所以查找PUSH ESP; POP EBP; RETN的指令,修正ROP是这样:

"\x52\xe2\x92\x7c"
"\x85\x8b\x1d\x5d" //修正EBP
"\x24\xcd\x93\x7c"

  继续运行,在CALL ZwSetInformationProcess处下断点,观察ZwSetInformationProcess的参数情况,也就是注意ZwSetInformationProcess用来设置_KEXECUTE_OPTIONS的第三个参数,这里刚刚好是0x22(00100010),最末两位是01,不需要对其进行修改。继续往下走,走到0x7c93cd6f, RETN 4 这个地方,此时ESP的值指向的地址是0x00000004, 这是之前ZwSetInformationProcess函数的参数压栈的结果,所以在修正EBP以后,要对ESP进行修正,防止影响ROP。

技术分享

  然后根据书上的方法找到RETN 0x28这个指令的地址,所以现在的ROP是这样:

"\x52\xe2\x92\x7c"
"\x85\x8b\x1d\x5d"
"\x19\x4a\x97\x7c" // 增大ESP
"\x24\xcd\x93\x7c"

  但是这样的问题是由于RETN 0x4的偏移的原因导致堆栈是这样的:

  技术分享

  ESP应该指向0x7c93cd24跳到关闭DEP的代码但是指向了堆栈的下一个,所以ROP修改为:

"\x52\xe2\x92\x7c"
"\x85\x8b\x1d\x5d"
"\x19\x4a\x97\x7c"
"\x90\x90\x90\x90"
"\x24\xcd\x93\x7c"

  这样就可以保证在增大ESP以后,程序进入关闭DEP代码的流程。

  接下来程序会顺利进入到关闭DEP代码,然后一直往下走,走到0x7c93cd6f这个地方,这时候发现ESP指向了之前用4个90填充的堆栈,这时候很显然,在执行0x0013febc这个指令地址以后,ESP会跳到0x0013fec4这个堆栈地址,显然,0x0013febc我们就可以放入jmp esp的指令地址,然后代码跳到0x0013fec4,这时候仔细观察堆栈我们可以发现有176个字节的shellcode离0x0013fec4这个地方有200个字节远,所以最后在0x0013fec4这个地方放上回跳200个字节的指令就可以了,因为此时DEP已经被关闭,所以堆栈可以放上可执行的代码。

技术分享

  最后的ROP链:

"\x52\xe2\x92\x7c"
"\x85\x8b\x1d\x5d"
"\x19\x4a\x97\x7c"
"\xc7\x31\x5a\x7d"
"\x24\xcd\x93\x7c"
"\xe9\x33\xff\xff"
"\xff\x90\x90\x90"

 

几个小tips:

1. 汇编中LEAVE指令相当于 mov esp,ebp ; pop ebp

2. 最后的回跳指令在VC6中提取出回跳200字节的机器码

 

                                                                                                                          2015/9/21

                                                                                                           23:41

 

Ret2Libc 练习(1) -- ZwSetInformationProcess

标签:

原文地址:http://www.cnblogs.com/bongbongbong/p/4824799.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!