作者:Joey@天玄安全实验室
最近开始分析Office漏洞,拿到CVE-2017-11826的样本后发现无法在Office2010上成功执行,打算分析并改造该EXP。参考了许多资料,结合自己的理解写了本文,供大家学习和参考。
在rtf文档中搜索object,发现嵌入了3个ole对象:
第一个对象的CLSID为D5DE8D20-5BB8-11D1-A1E3-00A0C90F2731
,在注册表搜索后发现该对象位于C:\Windows\SysWOW64\msvbvm60.dll
,而该dll是没有ASLR的。
通过ProcessExplorer发现word打开rtf文档后确实加载了msvbvm60.dll,且该dll无ASLR,说明该ole对象的作用是绕过ASLR。
使用rtfobj.py -s all
提取ole对象:
第一个对象经过上面的分析是用于绕过ASLR的,第二和第三个都是.doc文档,使用压缩软件直接打开第二个文档,文档结构如下:
可以看出使用了40个activeX.xml文件,文件内容如下:
40个xml文件内容一致,加载了CLSID为{00000000-0000-0000-0000-000000000001}的对象,然而系统中并没有这个对象,所以并不会加载任何对象,这么做是为了提高堆喷的效率,具体原理可查看SPRAYING THE HEAP IN SECONDS USING ACTIVEX CONTROLS IN MICROSOFT OFFICE一文。
而40个activeX.xml.rels的内容也完全一致:
都指向了activeX1.bin文件,因此会将activeX1.bin在内存中加载40次,以此达到堆喷的目的。
activeX1.bin文件结构如下:
看结构似乎是滑板指令加shellcode,待调试验证。
第三个文档结构如下:
document.xml的内容如下:
观测到<w:font 标签内有异常字符,且标签未正常闭合,预测漏洞触发于该处。
通过静态分析了解到RTF文档通过内嵌3个ole对象来实现ASLR绕过、堆喷射和漏洞触发,ASLR绕过是通过加载CLSID为D5DE8D20-5BB8-11D1-A1E3-00A0C90F2731
的COM对象,将msvbvm60.dll
加载到内存中。堆喷射利用40个activeX.xml.rels指向唯一的activeX1.bin文件,将activeX1.bin文件中的数据部分,即偏移为0x800后的内容加载到内存中实现堆喷射。而漏洞触发部分则利用document.xml中的异常字符和标签触发漏洞。
使用windbg附加word,打开漏洞文件:
可以看到异常因为ecx+4指向的内存无法访问导致错误。查看反汇编得知ecx的值来源于eax,此时eax的值为088888ec
。再次打开漏洞文件发现ecx的值改变,但是eax的值仍为088888ec
,说明eax的值为故意构造。
于是打算下断在函数wwlib!DllGetClassObject+0x42d4 (71ed98b0)
查看eax是如何生成的。查看wwlib的基地址,算出函数的偏移为wwlib+004da16b
。
重新打开漏洞文档,bp wwlib+004da16b
下断:
步过两次后执行到如图所示位置时,查看eax所在的内存:
发现和在文档3中的字符串一致,接着查看eax+44,对应的正是异常触发时eax的值088888ec
。
但在xml文件中,字符串中的异常字符的十六进制为e8a3ace0a288
:
在文件中显示的格式是Ascii,然而在内存中显示的是Unicode,于是将文件中的字符以utf-8格式转换为十六进制正是eax的值088888ec
:
说明通过修改该字符串可以控制eax的值,进而控制eip。
在ida中找到奔溃函数为sub_31A55CE6,发现变量v3是宽字节字符串,位于arg2+0x18,变量v4是一个长度,位于arg2+0x1c
在windbg设置崩溃函数起始点打印v3为字符串,长度为v4:bp wwlib+385ce6 "du poi(poi(esp+8)+18) Lpoi(poi(esp+8)+1c); g;"
可以看到v3就是xml文件中的标签,在解析到idmp标签后程序崩溃,然而并没有看到font标签,于是寻找到崩溃函数的父函数sub_3170FA5A
崩溃函数arg2的值为edi,而edi的值为父函数的arg2:
于是在父函数和崩溃函数同时下断,查看标签解析情况:
在父函数成功解析到font标签,猜测因为font标签未闭合而导致崩溃函数解析标签出错产生漏洞,修改了xml文件闭合了font标签:
将修改后的docx文件嵌入到新建的rtf文件中,在windbg中调试后发现eax的值改变了,并且没有异常,证实因为font标签未闭合导致的漏洞。
继续调试发现异常触发点的eax和ecx都是来自于esi,而esi为漏洞函数的arg1:
因此在漏洞函数打印标签以及[[esi+17f0]]、[[esi+17f0]+8]、[[esi+17f0]+c]和[esi+17f0]的值:
打印出的结构就是Taglist结构体,具体结构参考goabout2的office CVE-2017-11826杂谈一文。
接着调试异常触发点上的函数,发现函数功能为通过层级标签获取TagObject Array[Index-2]:
继续向上追溯,发现函数GetTagObject也调用了GetTagObjectByIndex,通过分析发现该函数获取的是TagObject Array[Index-1]的地址:
分析到这里,漏洞产生的原因也就出来了,由于word每解析一个标签,Current_Index的值就加一,当解析到闭合标签,Current_Index值会减1。由于构造了没有闭合的font标签,因此导致在解析idmap标签时比正常文件的Current_Index多一,导致原本应该获取OLEObject标签的TagObject变成获取了font的TagObject,因此造成了标签类型混淆导致漏洞的发生。
将标签层级和xml文件标签对应:
可以证实确实因为Current_Index值比正常文件的多一导致的类型混淆。
在内存中查看当解析idmap层级为6时Taglist的内存结构:
此时eax的值即为Taglist,因此查看eax指向的Taglist结构:
此时TagObject[4]+0x44的值为0x090b4000
,查看该值在内存中存储的数据:
发现[[TagObject[4]+0x44]+0x44]的值正是xml文件中font标签构造的固定地址,自此漏洞部分分析完毕。
先启动word然后使用windbg附加会导致堆喷无法成功,继而无法分析漏洞利用部分。因此使用gflags.exe让调试器直接加载winword.exe:
设置断点在异常触发点:
发现exc+4的值为activeX1.bin中shellcode下方的填充,说明已经成功堆喷。
步入[exc+4]后发现来到了msvbvm60.dll,已经进入了ROP链:
而第一条指令则是用来栈迁移,在之前已经将eax入栈,而eax的值正是构造好的0x088888ec
,执行指令后,esp的值已经变成了0x088888ec
:
而eax中的内容刚好位于shellcode的上方,此时ROP链为滑板指令,循环执行pop eax
和ret
,此时可以下断bp 729440cc ".if(esp=08888f48){}.else{gc}"
停在了滑板指令结束的位置:
当执行到最后一次滑板指令时,会将0x729410d0
放入eax中,而该值是msvbvm60.dll的IAT表中的数据,查看后存储的是VirtualProtect的地址:
紧接着通过ret跳转到ROP指令jmp [eax]
执行VirtualProtect,而此时栈中为构造好的VirtualProtect的参数:
再次跳转后进入到kernelbase.dll的VirtualProtect:
执行后会跳转到0x08888f70
执行shellcode:
然而VirtualProtect的修改的内存范围只有0x08888c90 - 0x08888e91
,而shellcode却位于0x08888f70
,因此会触发c0000005访问异常,shellcode执行失败:
activeX1.bin文件中布局如下:
由于原本VirtualProtect修改的范围为0x201不够,因此修改为0x1000确保能够覆盖shellcode,随后将shellcode替换为自己的shellcode即可。
将修改好的activeX1.bin文件替换到rtfobj.py提取出来进行堆喷的文档中,并修改为.docx,脚本参考Exploiting Word: CVE-2017-11826一文,替换脚本如下:
新建一个rtf文件,将替换好的docx文件添加到rtf文件中,保存后使用010Editor打开,搜索object,将{\object和{*\objdata的全部内容复制:
再新建一个rtf文件,按照堆喷射、Bypass ASLR和漏洞触发的顺序添加三个对象。堆喷射的内容就是上方复制好的内容,其他两个可以直接在原EXP中复制过来即可,最终EXP的结构如下所示:
最终成功执行了shellcode:
更多内容请前往微信公众号:天玄安全实验室
[1] CVE-2017-11826漏洞分析、利用及动态检测
[2] office CVE-2017-11826杂谈
[3] SPRAYING THE HEAP IN SECONDS USING ACTIVEX CONTROLS IN MICROSOFT OFFICE
[4] Exploiting Word: CVE-2017-11826
[5] Open XML标签解析类漏洞分析思路
OS: Win7 x64 SP1
Office: Ofiice
2010
x86
Image name: wwlib.dll
Timestamp: Sat Mar
27
23
:
37
:
07
2010
(
4BAE2623
)
CheckSum:
0127F568
ImageSize:
0127A000
File
version:
14.0
.
4762.1000
Product version:
14.0
.
4762.0
OS: Win7 x64 SP1
Office: Ofiice
2010
x86
Image name: wwlib.dll
Timestamp: Sat Mar
27
23
:
37
:
07
2010
(
4BAE2623
)
CheckSum:
0127F568
ImageSize:
0127A000
File
version:
14.0
.
4762.1000
Product version:
14.0
.
4762.0
│ [Content_Types].xml
│
├─docProps
│ app.xml
│ core.xml
│
├─word
│ │ document.xml
│ │ fontTable.xml
│ │ settings.xml
│ │ styles.xml
│ │ webSettings.xml
│ │
│ ├─activeX
│ │ │ activeX1.
bin
│ │ │ activeX1.xml
│ │ │ activeX2.xml
│ │ │ ······
│ │ │ activeX40.xml
│ │ │
│ │ └─_rels
│ │ activeX1.xml.rels
│ │ activeX2.xml.rels
│ │ ······
│ │ activeX40.xml.rels
│ │
│ ├─media
│ │ image1.wmf
│ │
│ ├─theme
│ │ theme1.xml
│ │
│ └─_rels
│ document.xml.rels
│
└─_rels
.rels
│ [Content_Types].xml
│
├─docProps
│ app.xml
│ core.xml
│
├─word
│ │ document.xml
│ │ fontTable.xml
│ │ settings.xml
│ │ styles.xml
│ │ webSettings.xml
│ │
│ ├─activeX
│ │ │ activeX1.
bin
│ │ │ activeX1.xml
│ │ │ activeX2.xml
│ │ │ ······
│ │ │ activeX40.xml
│ │ │
│ │ └─_rels
│ │ activeX1.xml.rels
│ │ activeX2.xml.rels
│ │ ······
│ │ activeX40.xml.rels
│ │
│ ├─media
│ │ image1.wmf
│ │
│ ├─theme
│ │ theme1.xml
│ │
│ └─_rels
│ document.xml.rels
│
└─_rels
.rels
<?xml version
=
"1.0"
encoding
=
"UTF-8"
standalone
=
"no"
?>
<ax:ocx ax:classid
=
"{00000000-0000-0000-0000-000000000001}"
ax:persistence
=
"persistStorage"
r:
id
=
"rId1"
xmlns:ax
=
"http://schemas.microsoft.com/office/2006/activeX"
xmlns:r
=
"http://schemas.openxmlformats.org/officeDocument/2006/relationships"
/
>
<?xml version
=
"1.0"
encoding
=
"UTF-8"
standalone
=
"no"
?>
<ax:ocx ax:classid
=
"{00000000-0000-0000-0000-000000000001}"
ax:persistence
=
"persistStorage"
r:
id
=
"rId1"
xmlns:ax
=
"http://schemas.microsoft.com/office/2006/activeX"
xmlns:r
=
"http://schemas.openxmlformats.org/officeDocument/2006/relationships"
/
>
<?xml version
=
"1.0"
encoding
=
"UTF-8"
standalone
=
"yes"
?>
<Relationships xmlns
=
"http://schemas.openxmlformats.org/package/2006/relationships"
>
<Relationship
Id
=
"rId1"
Type
=
"http://schemas.microsoft.com/office/2006/relationships/activeXControlBinary"
Target
=
"activeX1.bin"
/
>
<
/
Relationships>
<?xml version
=
"1.0"
encoding
=
"UTF-8"
standalone
=
"yes"
?>
<Relationships xmlns
=
"http://schemas.openxmlformats.org/package/2006/relationships"
>
<Relationship
Id
=
"rId1"
Type
=
"http://schemas.microsoft.com/office/2006/relationships/activeXControlBinary"
Target
=
"activeX1.bin"
/
>
<
/
Relationships>
activeX1.
bin
│
-
文件头
│
-
数据
│ │
-
-
-
CB
40
94
72
EC
83
88
08
CB
40
94
72
EC
83
88
08
│ │ ······
│ │
-
-
-
CB
40
94
72
EC
83
88
08
CB
40
94
72
EC
83
88
08
│ │
-
-
-
shellcode
│ │
-
-
-
2B
0E
98
72
2B
0E
98
72
2B
0E
98
72
2B
0E
98
72
│ │ ······
│ │
-
-
-
2B
0E
98
72
2B
0E
98
72
2B
0E
98
72
2B
0E
98
72
│ │ ······
│ │
-
-
-
CB
40
94
72
EC
83
88
08
CB
40
94
72
EC
83
88
08
│ │ ······
activeX1.
bin
│
-
文件头
│
-
数据
│ │
-
-
-
CB
40
94
72
EC
83
88
08
CB
40
94
72
EC
83
88
08
│ │ ······
│ │
-
-
-
CB
40
94
72
EC
83
88
08
CB
40
94
72
EC
83
88
08
│ │
-
-
-
shellcode
│ │
-
-
-
2B
0E
98
72
2B
0E
98
72
2B
0E
98
72
2B
0E
98
72
│ │ ······
│ │
-
-
-
2B
0E
98
72
2B
0E
98
72
2B
0E
98
72
2B
0E
98
72
│ │ ······
│ │
-
-
-
CB
40
94
72
EC
83
88
08
CB
40
94
72
EC
83
88
08
│ │ ······
│ [Content_Types].xml
│
├─docProps
│ app.xml
│ core.xml
│
├─word
│ │ document.xml
│ │ endnotes.xml
│ │ fontTable.xml
│ │ footnotes.xml
│ │ settings.xml
│ │ styles.xml
│ │ webSettings.xml
│ │
│ ├─theme
│ │ theme1.xml
│ │
│ └─_rels
│ document.xml.rels
│
└─_rels
.rels
│ [Content_Types].xml
│
├─docProps
│ app.xml
│ core.xml
│
├─word
│ │ document.xml
│ │ endnotes.xml
│ │ fontTable.xml
│ │ footnotes.xml
│ │ settings.xml
│ │ styles.xml
│ │ webSettings.xml
│ │
│ ├─theme
│ │ theme1.xml
│ │
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)