Jump to content
Nytro

Dyre IE Hooks

Recommended Posts

Posted

Dyre IE Hooks

I recently wrapper up my analysis of Dyre. A PDF of document can be found in my papers repo. Most of the document focuses on the different stages that Dyre interacts with the operating system. There are still some areas that I'd like to dig deeper into. For now it should be a good resource for anyone trying to identify a machine infected with Dyre or wanting to know more about the family of malware.

During the reversing process I found one part of Dyre functionality worthy of a post. As with most banking trojans Dyre contains functionality to hook APIs to log browser traffic. Typically to get the addresses of the APIs the sample will call GetProcAddress or manually traverse the portable executable file format to resolve symbols. If you are unfamiliar with the later technique I'd highly recommend reading section 3.3 of "Understanding Windows Shellcode" by Skape [1]. Dyre attempts to hook APIs in firefox.exe, chrome.exe and iexplorer.exe. It uses the standard GetProcAddress approach for resolving symbols in firefox.exe, is unsuccessful in chrome.exe and uses the GetProcAddress approach for the APIs LoadLibraryExW and CreateProcessInternalW in iexplorer.exe. Dyre hooks two APIs in WinInet.dll but it does it in a unique way. Dyre will read the image header timedatestamp [2] from WinInet. This value contains the time and date from when Wininet was created by the linker during compiling. It will then compare the timedatestamp to a list of timedatestamps stored by Dyre. The list contains presumably every time stamp for WinInet.dll since '2004-08-04 01:53:22' to '2014-07-25 04:04:59'. Below is an example of the values that can be found in the list.

seg000:00A0C05F db 0

seg000:00A0C060 TimeStampList dd 4110941Bh ; DATA XREF: TimeStamp:_loopr

seg000:00A0C064 dword_A0C064 dd 0 ; DATA XREF: TimeStamp+1Cr

seg000:00A0C064 ; TimeStamp:loc_A07A0Dr ...

seg000:00A0C068 dd 411095F2h <- Time stamp

seg000:00A0C06C dd 0 <- WinInet index

seg000:00A0C070 dd 4110963Fh

seg000:00A0C074 dd 0

seg000:00A0C078 dd 4110967Dh

seg000:00A0C07C dd 0

seg000:00A0C080 dd 411096D4h

seg000:00A0C084 dd 0

seg000:00A0C088 dd 411096DDh

seg000:00A0C08C dd 0

seg000:00A0C090 dd 41252C1Bh

seg000:00A0C094 dd 0

.....

seg000:00A0C0AC dd 1

seg000:00A0C0B0 dd 435862A0h

seg000:00A0C0B4 dd 2

seg000:00A0C0B8 dd 43C2A6A9h

seg000:00A0C0BC dd 3

....

seg000:00A0D230 dd 4CE7BA3Fh

seg000:00A0D234 dd 78h

seg000:00A0D238 dd 53860FB3h

seg000:00A0D23C dd 79h

seg000:00A0D240 dd 53D22BCBh

seg000:00A0D244 dd 7Ah

Values converted to time

>>> datetime.datetime.fromtimestamp(0x411095F2).strftime('%Y-%m-%d %H:%M:%S')

'2004-08-04 01:53:22'

>>> datetime.datetime.fromtimestamp(0x53D22BCB).strftime('%Y-%m-%d %H:%M:%S')

'2014-07-25 04:04:59'

If the timedatestamp is not present or an error occurs Dyre will send the hash of WinInet to the attackers server. If the hash is not found it will send WinInet back to the attackers. Below are some of the strings responsible for displaying errors for the command and control.

'/%s/%s/63/file/%s/%s/%s/'

"Check wininet.dll on server failed"

"Send wininet.dll failed"

If the timedatestamp is found in the list the next value is used as an index into another list. For example if the timedatestamp was 4802A13Ah it would be found at the 49th entry and the next value would be 0x15 or 21.

Data

seg000:00A0C1E8 dd 4802A13Ah <- '2008-04-13 18:11:38'

seg000:00A0C1EC dd 15h <- 21 index

Assembly to read index value

seg000:00A07A0D movsx edx, word ptr ds:TimeStampIndex[eax*8] ; edx = 21

seg000:00A07A15 lea edx, [edx+edx*2] ; edx = 63

seg000:00A07A18 mov edx, ds:offset[edx*4]

seg000:00A07A1F mov [ecx], edx ; save off value

Python: calculate offset

Python>hex(0x0A0D3E0 + (21+21* 2) * 4)

0xa0d4dc

Read

seg000:00A0D4DC dw 0F3Ch 0x0f3C offset to inline hook in wininet

The value 0xF3C + the base address of WinInet is the function prologue for ICSecureSocket::Send_Fsm. Dyre uses this to know the address to place it's hooks.

ICSecureSocket::Send_Fsm(CFsm_SecureSend *)

77200F37 90 NOP

77200F38 90 NOP

77200F39 90 NOP

77200F3A 90 NOP

77200F3B 90 NOP

77200F3C - E9 C7F0398A JMP 015A0008 <- Inline hook

015A0008 68 4077A000 PUSH 0A07740

015A000D C3 RETN

00A07740 55 PUSH EBP

00A07741 8BEC MOV EBP,ESP

00A07743 83EC 08 SUB ESP,8

00A07746 894D FC MOV DWORD PTR SS:[EBP-4],ECX

00A07749 68 2077A000 PUSH 0A07720

00A0774E FF75 08 PUSH DWORD PTR SS:[EBP+8]

00A07751 FF75 FC PUSH DWORD PTR SS:[EBP-4]

00A07754 FF15 94DEA000 CALL DWORD PTR DS:[A0DE94]

00A0775A 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX

It will also hooks ICSecureSocket::Receive_Fsm in the same fashion.

Closing

Rather than calling GetProcAddress Dyre stores the timedatestamp and patch offset of every known version of WinInet to avoid triggering heuristic based scanners. Seems like an arduous approach but still kind of cool. Another interesting fact is Dyre has the ability to patch Trusteer's RapportGP.dll if found in the browser memory. Dyre is actually a family of malware worthy of a deep dive. At first glance I ignored it because everything looked pretty cut & paste. I'd recommend others to check it out. If you find anything useful please shoot me an email. Cheers.

Hash Analyzed 099c36d73cad5f13ec1a89d5958486060977930b8e4d541e4a2f7d92e104cd21

  1. http://www.nologin.org/Downloads/Papers/win32-shellcode.pdf
  2. IMAGE_FILE_HEADER structure (Windows)

Sursa: Hooked on Mnemonics Worked for Me: Dyre IE Hooks

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...