Hello, this is Anthony from the Symantec Intelligence Analysis Team. Earlier this week we had the opportunity to analyze an interesting shellcode that is associated with the initial malicious exploit attempts against the Microsoft Internet Explorer XML Handling Remote Code Execution Vulnerability (BID 32721). Currently this vulnerability is not patched and there are several public exploits available to leverage the issue. The vulnerability exists due to a flaw in how Internet Explorer handles XML data bindings. Specially crafted XML can lead to object corruption and code execution. I am not going to go into describing the vulnerability in detail because this has already been done well elsewhere. However, I think that the shellcode is unique enough to warrant some discussion.
When the shellcode executes, it uses GlobalAlloc() to relocate itself into memory that is safe. This is to make sure that the shellcode is not corrupted by the Internet Explorer process before it can finish executing. This is a common technique in modern shellcode payloads. However, after this relocation, the shellcode begins installing hooks into several key functions:
• UnhandledExceptionFilter
• MessageBeep
• LdrShutdownThread
The hook is fairly straightforward. The shellcode gets the address of the target function and then uses VirtualProtect() to change the memory permissions for it. It then writes “mov eax, addr_of_new_code; jmp eax” into the function prelude. This has the affect of hijacking execution flow from the hooked function so that it executes code that the attacker supplies. This can be seen in the following disassembly of the hook for UnhandledExceptionFilter():
seg000:00000043 call get_addr_Kernel32_UnhandledExceptionFilter
seg000:00000048 mov edi, eax
seg000:0000004A call VirtualProtect_EDI_Mem_PAGE_EXECUTE_READWRITE
seg000:0000004F call HOOK_UnhandledExceptionFilter
EDI now points to target function and the target function memory is marked EXCUTE_READWRITE. This means that the shellcode can now overwrite parts of the target function prelude:
Hook_UnhandledExceptionFilter:
seg000:000001A1 call hook_function
The function below “
hook_function” writes “
mov eax, addr_of_new_code; jmp eax” into the target function prelude:
hook_function:
seg000:000000CE pop ebx ;ebx = addr_of_new_code
seg000:000000CF mov byte ptr [edi], 0B8h ; mov eax, addr_of_new_code seg000:000000D3 mov [edi+1], ebx
seg000:000000D7 mov word ptr [edi+5], 0E0FFh ; jmp eax
seg000:000000DE retn
In this case the hook makes the UnhandledExceptionFilter() function return a generic Windows error. This can be seen below:
addr_of_new_code:
seg000:000001A6 mov eax, 80040111h ; Make function return a ‘normal’ error.
seg000:000001AB retn 0Ch
Separate hooks are installed for the MessageBeep() and LdrShutdownThread() functions. These functions are redirected to a routine that uses EnumWindows() and GetClassName() to find the Internet Explorer window. After it finds the window it uses DestroyWindow() to kill the Internet Explorer window, and ExitProcess() to exit the process cleanly.
After all of these hooks are installed, the shellcode is very ordinary; it simply downloads a tertiary executable payload that acts as a vehicle to deliver a number of malicious binaries to install on the compromised system. So, I guess the question now is, why are these function hooks installed? I have not seen this type of behavior in shellcode before, and consequently I don’t think hooking these functions is a common technique. Though, I could be mistaken.
My best guess is that these hooks are designed to hide the malicious nature of the browser crash. A zero-day vulnerability loses its value in relation to the number of people that know about the vulnerability. It is most valuable when the vulnerability is not known by a large number of people. So, it makes sense that an attack using a zero-day would be as covert as possible. I am not intimately familiar with how this particular vulnerability affects the process memory of Internet Explorer yet, but perhaps it leaves the process in an unstable state. If this is the case, hooking functions that are likely to be triggered during a browser crash such as UnhandledExceptionFilter(), MessageBeep(), and LdrShutdownThread(), could be a covertness tactic. If the shellcode payload causes the process to exit cleanly with generic errors, the victim of an attack may not be suspicious of a crash and therefore less likely to investigate and discover the vulnerability.
Message Edited by Trevor Mack on 12-12-2008 04:55 PM