- INTRODUCTION
Duqu malware is a collection of malware components that together provide services to attackers. It may arrive as a Microsoft Word (.doc) that exploits Win32k TrueType font parsing engine and allows execution.
This document will be solely focused on the key logger component of Duqu.
- SUMMARY
The file in study is the info stealer/key logger component “a part” of what is known as an APT (Advance Persistent Threat) malware Duqu.
The MD5 hash of the file is 9749d38ae9b9ddd81b50aad679ee87ec. Vipre detects this as Trojan.Win32.Duqu.
The detailed analysis will be focused on three parts:
- 9749d38ae9b9ddd81b50aad679ee87ec – main executable
- f5ee03fed0133bb06d4cc52b0232fec0 – executable injector module
- 9a9e77d2b7792fbbddcd7ce05a4eb26e – dll infostealer module
The original executable 9749d38ae9b9ddd81b50aad679ee87ec (exe) has two components, f5ee03fed0133bb06d4cc52b0232fec0 (exe) and 9a9e77d2b7792fbbddcd7ce05a4eb26e (dll) which are originally encrypted within its body.
9749d38ae9b9ddd81b50aad679ee87ec is responsible for setting up the two. It acts as a command console in which command line arguments are expected to be entered. The usage is as follows:
9749d38ae9b9ddd81b50aad679ee87ec.exe xxx <optional parameters>
9749d38ae9b9ddd81b50aad679ee87ec.exe xxx <optional parameters>
optional parameters are:
- /delme - deletes the executable.
- /v - verbose logging for its own debugging purposes
- /quit - terminate spawned process (default lsass.exe) with injected .tmp file.
- /restart - restarts or spawns process (default lsass.exe) with injected .tmp file.
- /in <config file> - config file used for issuing commands on what data to steal and record to its log file, default config is loaded from one of its resource if not specified.
- /out <filename> - output file for its encrypted logs, default is ~DQx.tmp in %temp% folder if not specified.
It checks which process to inject its code to; either known antivirus processes or some known windows processes. When a target process is acquired, it spawns a suspended copy of that process in memory and manipulates its entry point to direct to its injector module’s (f5ee03fed0133bb06d4cc52b0232fec0 ) entry point before resuming.
f5ee03fed0133bb06d4cc52b0232fec0 is responsible for injecting the dll module (9a9e77d2b7792fbbddcd7ce05a4eb26e) to the newly spawned process as a thread. As a sign of infection, a “sortxxxx.nls” thread should be present (where “xxxx” can be any random hex number) within the process.
9a9e77d2b7792fbbddcd7ce05a4eb26e on the other hand steals information about the system and logs them to a tmp file. A total of 9 information stealing routines may be executed and these are the following:
- 65h: list running processes and get account details
- 66h: get available drives and information
- 68h: take a screenshot
- 69h: get various network information
- 67h: log keyboard strokes
- 6Ah: enumerate opened windows
- 6Bh: enumerate network shares
- 6Dh: list available files
- 6Eh: enumerate computers on the domain.
By default, it only executes 8 routines based on its configuration file, routine 6Eh: enumerate computers on the domain, is not executed.
All these data gathered are compressed using bzip2 algorithm and then stored in a temp file ~DQxx.tmp (where xx is any hex number) located in %TEMP% directory.
- FLOWCHART
Here is a diagram of the malware’s system infection routine.
- INITIAL ANALYSIS
At first glance, the file is a win32 executable with GUI subsystem and runs on an Intel 386 or later processors.
Figure 1: WIN32 executable with GUI subsystem.
PEID does not recognize the file structure of 9749d38ae9b9ddd81b50aad679ee87ec and shows “Nothing found *”.
Figure 2: PEID found nothing!
But based from my past experiences in debugging malwares and research, I find it to be compiled in Microsoft Visual C++ with /GS switch. I actually arrived at this conclusion from what I have seen in its entry point for it uses Cookie Generation Security check to avoid buffer overruns. More about cookie generation security can be found in http://msdn.microsoft.com/en-us/library/aa290051(v=vs.71).aspx.
- BLACK BOX TESTING
Simply running the malware produces nothing. It is because this infostealer needs to be supplied with the string “xxx” as argument; e.g. “9749d38ae9b9ddd81b50aad679ee87ec.exe xxx”. It also accepts other arguments as well which will be discussed further in the detailed analysis part.
Supplying the string “xxx” we can see that; by default, it creates a bzip2 encrypted file in %TEMP% folder as ~DQxx.tmp (where xx can be any random hex number) and is being used by lsass.exe as seen in Figure 4a.
Supplying the string “xxx” we can see that; by default, it creates a bzip2 encrypted file in %TEMP% folder as ~DQxx.tmp (where xx can be any random hex number) and is being used by lsass.exe as seen in Figure 4a.
Figure 4b: Another sign of infection, sort9760.nls thread is seen injected to lsass.exe
- DETAILED ANALYSIS
9749d38ae9b9ddd81b50aad679ee87ec – The Main Executable a.k.a “The Command Console”
Since this malware is Microsoft Visual C++ compiled, the entry point located at 0x00403C91 is not the actual code start of the malware but instead we have to look for its WinMain entry which is readily available to IDA Pro. (Yay thanks IDA!)
Figure 5: A Call to WinMain
This executable needs a specific command line argument in order for it to function. The usage is as follows:
malware.exe xxx <optional parameters>
malware.exe xxx <optional parameters>
By default, the executable spawns an lsass.exe process in which it injects a ~DQxx.tmp located in %TEMP% directory where “xx” can be any random hex number.
Other optional command line parameters are also available:
Figure 6a: “delme” parameter
- /v - verbose logging for its own debugging purposes, usage of printf() is visible here.
Figure 6c: “quit” parameter
Figure 6d: “restart” parameter
- /in <config file> - config file used for issuing commands on what data to steal and recorded to its log file, default input is loaded from one of its resource if not specified.
Figure 6f: “out” parameter, a ~DQxx.tmp file in %temp% folder is created if /out is not specified.
The executable has 2 resources in .rsrc section, #200 and #201. #200 is the encrypted DLL component while #201 is the encrypted configuration file to be used by the malware which specifies which stealing routines to execute later. Both of these resources are mapped in memory.
The executable then proceeds to decrypt its DLL module located in resource section (resource #200) embedded in a JPEG file. This DLL is detected by Vipre as Trojan.Win32.Duqu.d (v) and has a MD5 of 9a9e77d2b7792fbbddcd7ce05a4eb26e.
Figure 7: JPEG File Interchange Format as seen in the malware’s resource section
The decryption routine is just a simple NOT operator. You can also use XOR BYTE PTR [EAX],0FF as a substitute in decrypting.
Figure 8: Decrypting the DLL module.
The DLL module is compressed with UPX_LZMA and fakes its file properties to avoid suspicion as seen in Figure 9.
The malware APIs are found in hashes and their matching addresses are traversed to their corresponding DLLs. This is usually seen most in packers, encryptors and malwares nowadays. The hashes and the corresponding APIs are listed below:
- kernel32.dll
- 0x88444BE9: CreateToolhelp32Snapshot
- 0x92D66FBA: Process32FirstW
- 0xD1A588DB: Process32NextW
- 0xFCAA0AB8: OpenProcess
- 0xAE75A8DB: CreateProcessW
- 0xCF5350C5: GetNativeSystemInfo
- 0xDCAA4C9F: IsWow64Process
- 0x4BBFABB8: lstrcmpiW
- 0xA668559E: VirtualQuery
- 0x4761BB27: VirtualProtect
- 0xD3E360E9: GetProcAddress
- 0x6B3749B3: MapViewOfFile
- 0xD830E518: UnmapViewOfFile
- 0x78C93963: FlushInstructionCache
- 0xD83E926D: LoadLibraryW
- 0x19BD1298: FreeLibrary
- 0x6F8A172D: CreateThread
- 0xBF464446: WaitForSingleObject
- 0xAE16A0D4: GetExitCodeThread
- 0x3242AC18: GetSystemDirectoryW
- 0x479DE84E: CreateFileW
- 0xB67F8157: CreateRemoteThread
- psapi.dll
- 0xBCC7C0DA: GetModuleFileNameExW
- advapi32.dll
- 0x6012A950: RegOpenKeyExW
- 0xC6151DC4: RegQueryValueExW
- 0xF03A2554: RegCloseKey
- 0x9C6E14F8: CreateProcessAsUserW
- 0x702B6244: DuplicateTokenEx
- 0x2EDB7947: OpenProcessToken
- 0x557DBBB6: LookupPrivilegeValueW
- 0xE763A4A3: AdjustTokenPrivileges
- version.dll
- 0xD4DE04DA: GetFileVersionInfoW
- 0xCEF01246: VerQueryValueW
- userenv.dll
- 0x3E692063: CreateEnvironmentBlock
- 0xAFF5F91F: DestroyEnvironmentBlock
- ntdll.dll
- 0x40C4EC59: ZwQueryInformationProcess
- 0x5FC5AD65: ZwCreateSection
- 0x1D127D2F: ZwMapViewOfSection
- 0x468B8A32: ZwUnmapViewOfSection
- 0xDB8CE88C: ZwClose
- 0x8C6F89E1: ZwQuerySection
- 0x7BCE6E19: ZwQueryAttributesFile
A code snippet; complete with comments, on how the malware traverses its imported APIs in a specified DLL export table in Figure 10:
It then creates a system snapshot of running processes in memory and verifies if any software security related processes are running. It monitors the following:
- avp.exe - Kaspersky
- Mcshield.exe - McAfee
- avguard.exe - Avira
- bdagent.exe - BitDefender
- UmxCfg.exe - CA
- fsdfwd.exe - F-Secure
- rtvscan.exe - Symantec
- ccSvcHst.exe - Symantec
- ekrn.exe - Eset
- tmproxy.exe - Trend Micro
- RavMonD.exe - Rising
If any of the following processes listed above is present, it will attempt to get the complete file path and the file version info of the running security software and will inject its malicious code here. The malware does this in three possible ways:
First is by using GetModuleFileNameExW found in psapi.dll with GetFileVersionInfoW and VerQueryValueW in version.dll. GetModuleFileNameExW returns the complete file path of the targeted file.
Figure 11a: Using GetModuleFileNameExW to extract the complete file path of the matched running process.
Second is by using WMI querying technique with the format "SELECT ExecutablePath FROM Win32_Process WHERE ProcessID = %u". WMI also known as Windows Management Instrumentation is a core Windows management technology. WMI can give administrators a means to extract information about the operating system; can start a process on remote computer; and many more. More information on WMI can be found in http://technet.microsoft.com/en-us/library/ee692772.aspx.
Or third is by querying the installation path in registry pertinent to the matched executable process. The problem with this routine is that it can only support avp.exe (Kaspersky), Mcshield.exe (MacAfee) and tmproxy.exe (Trend Micro). The specified registry entries can be any of the following:
- SOFTWARE\KasperskyLab\protected\AVP80\environment
- SOFTWARE\KasperskyLab\protected\AVP11\environment
- SOFTWARE\KasperskyLab\protected\AVP10\environment
- SOFTWARE\KasperskyLab\protected\AVP9\environment
- SOFTWARE\KasperskyLab\protected\AVP8\environment
- SOFTWARE\KasperskyLab\protected\AVP7\environment
- SOFTWARE\kasperskylab\avp7\environment
- SOFTWARE\kasperskylab\avp6\environment
- SOFTWARE\McAfee\VSCore
- SOFTWARE\TrendMicro\NSC\TmProxy
- SOFTWARE\Rising\RIS
- SOFTWARE\Rising\RAV
Now if there are no security softwares installed or running in process, the malware will default to of any of the following files:
- For 32bit operating system:
- %SystemRoot%\system32\lsass.exe
- %SystemRoot%\system32\winlogon.exe
- %SystemRoot%\system32\svchost.exe
- For 64bit operating system:
- %SystemRoot%\syswow64\lsass.exe
- %SystemRoot%\syswow64\winlogon.exe
- %SystemRoot%\syswow64\svchost.exe
The executable verifies the image of the targeted file if it is Intel 386(32bit) or AMD 64(64bit). What’s interesting is that although the malware author may seem to check for 64bit systems, its procedure is actually empty and returns a NULL. It’s as if there is a plan to support 64bit but forgot to implement it.
It then creates a mutex name based on process ID of the targeted file and continues to decrypt once again another module file (with MD5 of f5ee03fed0133bb06d4cc52b0232fec0). This executable module file is detected by Vipre as Trojan.Win32.Generic!BT.
I have taken the liberty of inserting comments to its decryption routine for the interest of our readers.
The malware then spawns a suspended process of the targeted file in memory. If the file is running under a 64bit environment, it does nothing and proceeds to terminate itself.
The malware then proceeds to read the first 0x1000 bytes of the targeted file into memory using ReadProcessMemory function in order to parse the PE header and save the targeted file’s entry point in stack.
The targeted file’s entry point will be replaced with a jump offset to that of the injector module’s entry point (f5ee03fed0133bb06d4cc52b0232fec0) before resuming the suspended process. This is a technique used by the malware in order to pass the execution from targeted file to the malware’s component file. Remember that the targeted file is non-malicious in nature but the code that it jumps to is malicious. This is done to hide the component file and avoid detection by antivirus products. Also take note that NO component files were dropped nor created by the malware, all of these were done in memory.
Figure 15a: Bytes in targeted file’s entry point are overwritten to pass the execution to malware’s own entry point
f5ee03fed0133bb06d4cc52b0232fec0 – The Executable Module a.k.a. “The Injector”
When the code execution is passed to the injector module (f5ee03fed0133bb06d4cc52b0232fec0) in memory, the first thing it will do is to fill and rebuild its Import Address Table.
Figure 16: Rebuilding Import Address Table
Next is it will set up a file named “sortxxxx.nls” (where “xxxx” is a string generated by GetTickCount) where modules of the infostealer component (9a9e77d2b7792fbbddcd7ce05a4eb26e) will be copied afterwards.
Figure 17: Preparing “sortxxxx.nls”.
This is followed by decrypting more of its code at target location 0x00401080 using simple XOR EAX, 0x89719922 as key.
Figure 18: Decrypting more code, 0x89719922 as decryption key.
It will then call CreateRemoteThread API to create a thread leading to the execution of the newly decrypted code at 0x00401080. The newly created thread maps a copy of its malicious DLL component (9a9e77d2b7792fbbddcd7ce05a4eb26e) in memory (remember sortxxxx.nls?).
It also demonstrates rootkit capabilities by patching some functions of NTDLL.DLL in memory in order to route execution to the malware itself first before passing to the actual function(s). Some patched functions are:
- ZwMapViewOfSection
- ZwCreateSection
- ZwOpenFile
- ZwClose
- ZwQueryAttributesFile
- ZwQuerySection
Figures below demonstrate how code rerouting is done.
Figure 20a: Overwrites 6 bytes of ntdll.dll .7C90DC55 NtMapViewOfSection to jump to malware code instead.
It will then attempt to load “sortxxxx.nls” in memory using LoadLibraryW function and gets the function address of the 2nd exported function of the dll component using GetProcAddress. It will then pass the execution to export #2 by using call. This is better exemplified by Figure 21.
9a9e77d2b7792fbbddcd7ce05a4eb26e – The Dynamic Link Library Module a.k.a. “The InfoStealer”
The DLL component is the one responsible for stealing data from the infected system. It exports 5 functions which can be seen below:
- #1 .100026EF - same as #2, a call to entry point
- #2 .10002701 - main (entry point)
- #3 .1000276A - same as #2, create thread to entry point
- #4 .100025BF - infostealer
- #5 .100025C4 - quit infostealer
This DLL module has nine routines all in all:
- 65h @ 0x100032E9: List running processes, look up account details
- 66h @ 0x10002F34: List available disk drives including mounted network drives, get drive type (removable, fixed, CD-ROM, RAM disk, or network drive), get volume information (serial number and volume label), and free disk space.
- 68h @ 0x10003ED0: Take a screenshot
- 69h @ 0x10005248: Get network parameters (hostname, domain name, dns server, etc.), retrieves the interface–to–IPv4 address mapping table, retrieves the IPv4 routing table, retrieves the MIB-II interface table, retrieves the IPv4 to physical address mapping table, retrieves the IPv4 TCP connection table, retrieves the IPv4 User Datagram Protocol (UDP) listener table, display dns cache and enumerate network connections and resources.
- 67h @ 0x100052C3: Monitor keyboard strokes
- 6Ah @ 0x100057F5: Enumerate windows
- 6Bh @ 0x10005D06: Network file, shares and connection enumeration
- 6Dh @ 0x100069E5: List available files on all drives.
- 6Eh @ 0x10006CF5: Lists all servers that are visible in the domain.
Remember resource #201? Resource #201 is then decrypted in memory which serves as the default configuration file as to what stealing routines to be executed. The decryption routine used is clearly seen in Figure 23a.
The result of the decrypted configuration file can be seen in Figure 23b. The stealing routines are highlighted in red.
It uses 8 of the listed 9 routines based on its default configuration file. Routines used are 65h, 66h, 68h, 69h, 67h, 6Ah, 6Bh and 6Dh in that sequence. All stolen data are then compressed using bzip2 algorithm before writing to ~DQxx.tmp file. A string “AEh91AY&SY” is seen in the tmp file compared to the original bzip2 marker which is “BZh91AY&SY”.
A sample of the encrypted stolen data and decrypted counterpart is posted below. A list of running processes with corresponding PIDs with account id is seen when fully decrypted.
Analysis and Documentation Prepared By:
Christopher D. Del Fierro
0 comments:
Post a Comment