Nytro Posted November 24, 2014 Report Posted November 24, 2014 Dyre IE HooksI 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 0seg000:00A0C060 TimeStampList dd 4110941Bh ; DATA XREF: TimeStamp:_looprseg000:00A0C064 dword_A0C064 dd 0 ; DATA XREF: TimeStamp+1Crseg000:00A0C064 ; TimeStamp:loc_A07A0Dr ...seg000:00A0C068 dd 411095F2h <- Time stampseg000:00A0C06C dd 0 <- WinInet indexseg000:00A0C070 dd 4110963Fhseg000:00A0C074 dd 0seg000:00A0C078 dd 4110967Dhseg000:00A0C07C dd 0seg000:00A0C080 dd 411096D4hseg000:00A0C084 dd 0seg000:00A0C088 dd 411096DDhseg000:00A0C08C dd 0seg000:00A0C090 dd 41252C1Bhseg000:00A0C094 dd 0.....seg000:00A0C0AC dd 1seg000:00A0C0B0 dd 435862A0hseg000:00A0C0B4 dd 2seg000:00A0C0B8 dd 43C2A6A9hseg000:00A0C0BC dd 3....seg000:00A0D230 dd 4CE7BA3Fhseg000:00A0D234 dd 78hseg000:00A0D238 dd 53860FB3hseg000:00A0D23C dd 79hseg000:00A0D240 dd 53D22BCBhseg000:00A0D244 dd 7AhValues 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 indexAssembly to read index value seg000:00A07A0D movsx edx, word ptr ds:TimeStampIndex[eax*8] ; edx = 21seg000:00A07A15 lea edx, [edx+edx*2] ; edx = 63seg000:00A07A18 mov edx, ds:offset[edx*4]seg000:00A07A1F mov [ecx], edx ; save off valuePython: calculate offset Python>hex(0x0A0D3E0 + (21+21* 2) * 4)0xa0d4dcRead seg000:00A0D4DC dw 0F3Ch 0x0f3C offset to inline hook in wininetThe 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 NOP77200F38 90 NOP77200F39 90 NOP77200F3A 90 NOP77200F3B 90 NOP77200F3C - E9 C7F0398A JMP 015A0008 <- Inline hook015A0008 68 4077A000 PUSH 0A07740015A000D C3 RETN00A07740 55 PUSH EBP00A07741 8BEC MOV EBP,ESP00A07743 83EC 08 SUB ESP,800A07746 894D FC MOV DWORD PTR SS:[EBP-4],ECX00A07749 68 2077A000 PUSH 0A0772000A0774E 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],EAXIt 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 099c36d73cad5f13ec1a89d5958486060977930b8e4d541e4a2f7d92e104cd21http://www.nologin.org/Downloads/Papers/win32-shellcode.pdf IMAGE_FILE_HEADER structure (Windows) Sursa: Hooked on Mnemonics Worked for Me: Dyre IE Hooks Quote