I would like to announce the next two dates for iDefense malware training courses:
September 23 - 25 2009 (9am to 5pm) NYC
October 28-30 2009 (9am to 5pm) London
The cost is $3500/person. You'll get lots of hands-on technical training from myself and Greg Sinclair. As a pre-requisite, you should complete SANS GREM or a course of similar quality, or have 1-2 years experience with malware analysis. It would really help if you had your own license for IDA Pro (otherwise you can use the trial/limited 4.9 version), however almost all of the tools we use are free, very inexpensive, or home-made.
Here is a high-level description of the topics. If you want a more detailed agenda, or any other information about the course, please email me: michael (dot) ligh @ mnin (dot) org.
* Windows internals for reverse engineers
* Low level programming (reading/writing assembly)
* High level programming (Native and Win32 API, driver development, Python)
* Analyzing non-executable files (Javascript, MS Office documents, PDF, Flash)
* Dynamic analysis (Change detection, building a custom API monitor, pcap inspection)
* Static analysis (PE/COFF, working with IDA and plug-ins)
* Using a debugger to analyze malware (user programs with Immunity Debugger and kernel drivers with WinDbg)
* Packing and unpacking (dump and rebuild exes/dlls packed with both common and custom packers)
* Anti-RCE (ways to defeat debugger detection, VM detection, Emu detection)
* Code injection and rootkits (10+ injection techniques w/ source code, user mode rootkits, kernel mode rootkits)
* Stealth malware (methods to hide on disk, memory, and network - plus how to detect)
* Analyzing info stealers (HTML injection, key logging, password/credential theft)
* Memory forensics (hunting malware in memory, extending Volatility, case studies with new tools)
* Scripting debuggers (decrypting strings, computing CnC hostnames, decrypting configurations)
* Analyzing VB and Delphi malware
Also, just so you know, here are some topics that the class does NOT teach:
* OSX/Unix malware
* Mobile malware
* Hardware/firmware rootkits
* Investigating IPs, domains, etc
We will study specific families of malware (CoreFlood, Mebroot, Zeus, Laqma, Silent Banker, Kraken, Waledac, Gozi, Limbo, Tigger, and Conficker to name a few), as well as generic malware of Chinese descent and several home-made trojans that we built to demonstrate certain things.
Thursday, September 3, 2009
Saturday, August 1, 2009
Making Fun of Your Malware
The slides from my talk with Matt Richard at Defcon 17 have now been posted online. Unfortunately, its not one of those slide decks that you can just read and get the full benefit of the talk. If you missed it and want to LOL, wait for the audio/video to be released.

Here is the demo showing how we performed credential recovery for Silent Banker, because the authors forgot to seed the random number generator:
http://mhl-malware-scripts.googlecode.com/files/silentbanker_sbgold.mov.zip
Here is the demo showing a new Volatility plug-in that rebuilds the IAT for packed malware, even if the original PE header is wiped out of memory:
http://mhl-malware-scripts.googlecode.com/files/coreflood_fixiat.mov.zip
Here is the demo showing how to detect SSDT hooks, extract the malicious kernel driver, create an IDB of the driver, and automatically label the rootkit functions in the IDB - all in one step. This plug-in extends Brendan Dolan-Gavitt's ssdt.py for the additional features.
http://mhl-malware-scripts.googlecode.com/files/laqma_ssdt_ex.mov.zip
Enjoy. I will release the actual plug-ins later on.

Here is the demo showing how we performed credential recovery for Silent Banker, because the authors forgot to seed the random number generator:
http://mhl-malware-scripts.googlecode.com/files/silentbanker_sbgold.mov.zip
Here is the demo showing a new Volatility plug-in that rebuilds the IAT for packed malware, even if the original PE header is wiped out of memory:
http://mhl-malware-scripts.googlecode.com/files/coreflood_fixiat.mov.zip
Here is the demo showing how to detect SSDT hooks, extract the malicious kernel driver, create an IDB of the driver, and automatically label the rootkit functions in the IDB - all in one step. This plug-in extends Brendan Dolan-Gavitt's ssdt.py for the additional features.
http://mhl-malware-scripts.googlecode.com/files/laqma_ssdt_ex.mov.zip
Enjoy. I will release the actual plug-ins later on.
Monday, July 20, 2009
New and Updated Volatility Plug-ins
Here is a Volatility plug-in for printing the Interrupt Descriptor Table (IDT) addresses:
http://mhl-malware-scripts.googlecode.com/files/idt.py
It only prints the IDT for one processor, so if anyone wants to update it to handle multiple processors, then feel free. Also if the system's KPCR is located at an address other than 0xFFDFF000 (see Brendan Dolan Gavitt's blog or Edgar Barbosa's paper), then you'll need to add the correct address to the script.
In order to test the script, I used Greg Hoglund's basic_interrupt.zip from rootkit.com. Below you can see that interrupt #46 (0x2E) is pointing inside the basic_int.sys driver.
# python volatility idt -f ../hooked_int.bin
IDT# ISR unused_lo segment_type system_segment_flag DPL P
0 0008:804df350 0 0e 0 0 1
1 0008:804df4cb 0 0e 0 0 1
[...]
46 0008:f8bcd550 0 0e 0 3 1
# python volatility modules -f ../hooked_int.bin
File Base Size Name
\WINDOWS\system32\ntoskrnl.exe 0x00804d7000 0x216700 ntoskrnl.exe
\WINDOWS\system32\hal.dll 0x00806ee000 0x020300 hal.dll
\??\C:\BASIC_INT.sys 0x00f8bcd000 0x001000 BASIC_INT.sys
Here is a Volatility plug-in for printing driver IRP function addresses:
http://mhl-malware-scripts.googlecode.com/files/driverirp.py
The script requires Andreas Schuster's driverscan.py plug-in. It works by over-riding the object_action method of the PoolScanDriver class. Thanks to Andreas for providing the framework. Thanks to AAron Walters for showing me how to over-ride the scanner methods.
In order to test the script, I used Jamie Butler's TCPIRPHook.zip from rootkit.com. Below you can see that the IRP_MJ_DEVICE_CONTROL function for Tcpip.sys is hooked by irphook.sys.
# python volatility driverirp -f ../irphook.bin
0x0218a830 0x823b45b8 7 0 0xb2ef3000 361600 Tcpip Tcpip \Driver\Tcpip
[0] [IRP_MJ_CREATE] => 0xb2ef94f9
[1] [IRP_MJ_CREATE_NAMED_PIPE] => 0xb2ef94f9
[2] [IRP_MJ_CLOSE] => 0xb2ef94f9
[3] [IRP_MJ_READ] => 0xb2ef94f9
[4] [IRP_MJ_WRITE] => 0xb2ef94f9
[5] [IRP_MJ_QUERY_INFORMATION] => 0xb2ef94f9
[6] [IRP_MJ_SET_INFORMATION] => 0xb2ef94f9
[7] [IRP_MJ_QUERY_EA] => 0xb2ef94f9
[8] [IRP_MJ_SET_EA] => 0xb2ef94f9
[9] [IRP_MJ_FLUSH_BUFFERS] => 0xb2ef94f9
[10] [IRP_MJ_QUERY_VOLUME_INFORMATION] => 0xb2ef94f9
[11] [IRP_MJ_SET_VOLUME_INFORMATION] => 0xb2ef94f9
[12] [IRP_MJ_DIRECTORY_CONTROL] => 0xb2ef94f9
[13] [IRP_MJ_FILE_SYSTEM_CONTROL] => 0xb2ef94f9
[14] [IRP_MJ_DEVICE_CONTROL] => 0xf8b615d0
# python volatility modules -f ../irphook.bin
File Base Size Name
\WINDOWS\system32\ntoskrnl.exe 0x00804d7000 0x216700 ntoskrnl.exe
\WINDOWS\system32\hal.dll 0x00806ee000 0x020300 hal.dll
\??\c:\irphook.sys 0x00f8b61000 0x001000 irphook.sys
I updated the usermode hook detection plug-in so that it uses pydasm in a cleaner, more reasonable method. Instead of checking the instruction string against a regex, it checks the opcode type and operand type using constants declared in the libdasm source code. Here is a copy of the new version:
http://mhl-malware-scripts.googlecode.com/files/usermode_hooks2.py
Also, as I mentioned in my original post about usermode hooks, it can be (and has now been) ported to kernel mode. Here is a copy of the version that detects IAT, EAT, and in-line hooks in kernel drivers instead of usermode modules:
http://mhl-malware-scripts.googlecode.com/files/kernel_hooks.py
I tested the script against a sample of the Skynet trojan. Below you can see that kernel_hooks.py detects the in-line hooks in ntoskrnl.exe functions.
# python volatility kernel_hooks -f ../skynet.bin -d outdir
Type: INLINE, Hooked driver: ntoskrnl.exe (0x804d7000 - 0x806ed780), Hooked function: IofCallDriver => jmp 0x8217f20b, Hooking driver:
Type: INLINE, Hooked driver: ntoskrnl.exe (0x804d7000 - 0x806ed780), Hooked function: IofCompleteRequest => jmp 0x820babc3, Hooking driver:
According to the write-up by McAfee, Skynet hooks two other functions using the in-line technique: NtFlushInstructionCache and NtEnumerateKey. The kernel_hooks.py does not currently detect these two, because they are not actually exported by ntoskrnl.exe, and the plug-in finds functions by walking the EAT. The addresses of the two functions are exposed through their corresponding SSDT entries, however, so its possible to find them that way and use the same check_inline function from kernel_hooks.py to inspect.
I also updated the "threads without modules" plug-in. As described in the original post on my blog, it detects hidden system/kernel threads. Using the new version, you don't have to make any adjustments to files in the Volatility core distribution anymore. Its more user-friendly now that it just over-rides the object_action method of the PoolScanThreadFast2 class in order to change the scanner's behavior.
http://mhl-malware-scripts.googlecode.com/files/orphan_threads.py
The output of this script still looks the same as before (sample shown for a memory dump of Tigger trojan):
# python volatility orphan_threads -f ../tigger.vmem
PID TID Offset StartAddress
------ ------ --------- ------------
4 248 0x2029da8 0xf623f54e
4 996 0x206fb90 0xf6240393
4 1372 0x2095700 0xf623ea46
4 564 0x209d3f8 0xf6240150
Last but not least, I updated the malfind plug-in for detecting hidden/injected code in usermode processes. You can find the latest version here:
http://mhl-malware-scripts.googlecode.com/files/malfind2.py
The new version includes the following changes:
# python volatility malfind2 -f ../zeus.vmem -d outdir
#
# svchost.exe (Pid: 972)
#
[!] Range: 0x00890000 - 0x008b7fff
Memory extracted to outdir2/malfind.972.890000-8b7fff.dmp
PE sections: {.odkx, .itiz, .ryd, .rsrc, }
#
# svchost.exe (Pid: 1064)
#
[!] Range: 0x01f00000 - 0x01f27fff
Memory extracted to outdir2/malfind.1064.1f00000-1f27fff.dmp
PE sections: {.odkx, .itiz, .ryd, .rsrc, }
Here's an example of what to see when processing a memory dump infected with Silent Banker. In this case, the suspicious memory is a trampoline for one of the trojan's API function hooks.
[!] Range: 0x01650000 - 0x01650fff
Memory extracted to outdir3/malfind.1876.1650000-1650fff.dmp
Hexdump:
0x01650000 58 68 05 00 66 01 68 00 00 00 00 68 00 00 80 7c Xh..f.h....h...|
0x01650010 68 68 18 0b 10 50 68 8f 9f 0a 10 c3 00 00 00 00 hh...Ph.........
0x01650020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x01650030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
Disassembly:
0x01650000 pop eax
0x01650001 push dword 0x1660005
0x01650006 push dword 0x0
0x0165000b push dword 0x7c800000
0x01650010 push dword 0x100b1868
0x01650015 push eax
0x01650016 push dword 0x100a9f8f
0x0165001b ret
Here's an example of what to see when processing a memory dump infected with CoreFlood. The suspicious memory in this case is the start of the code segment of the PE file (as mentioned in the original blog, CoreFlood strips its PE header).
[!] Range: 0x7ff80000 - 0x7ffadfff
Memory extracted to outdir4/malfind.248.7ff80000-7ffadfff.dmp
Hexdump:
0x7ff80000 81 ec 20 01 00 00 53 8b 9c 24 30 01 00 00 8b c3 .. ...S..$0.....
0x7ff80010 24 04 55 f6 d8 56 57 8b bc 24 34 01 00 00 68 05 $.U..VW..$4...h.
0x7ff80020 01 00 00 8d 4c 24 2c 51 1b c0 25 27 0c 00 00 33 ....L$,Q..%'...3
0x7ff80030 f6 8b ef 89 44 24 18 89 74 24 1c ff 15 b0 e1 f9 ....D$..t$......
Disassembly:
0x7ff80000 sub esp,0x120
0x7ff80006 push ebx
0x7ff80007 mov ebx,[esp+0x130]
0x7ff8000e mov eax,ebx
0x7ff80010 and al,0x4
0x7ff80012 push ebp
0x7ff80013 neg al
0x7ff80015 push esi
0x7ff80016 push edi
0x7ff80017 mov edi,[esp+0x134]
0x7ff8001e push dword 0x105
0x7ff80023 lea ecx,[esp+0x2c]
0x7ff80027 push ecx
0x7ff80028 sbb eax,eax
0x7ff8002a and eax,0xc27
0x7ff8002f xor esi,esi
0x7ff80031 mov ebp,edi
0x7ff80033 mov [esp+0x18],eax
0x7ff80037 mov [esp+0x1c],esi
0x7ff8003b call [0x7ff9e1b0]
Here 's an example of what to see when processing a memory dump infected with the Skynet trojan mentioned above. In this case, the suspicious memory holds a command and control IP address and the name of one of the files that it hides on disk using the rootkit.
#
# svchost.exe (Pid: 876)
#
[!] Range: 0x02410000 - 0x02414fff
Memory extracted to outdir5/malfind.876.2410000-2414fff.dmp
Hexdump:
0x02410000 18 00 00 00 68 74 74 70 73 3a 2f 2f 32 31 33 2e ....https://213.
0x02410010 31 33 33 2e 31 31 30 2e 32 31 2f 00 06 00 00 00 133.110.21/.....
0x02410020 31 30 31 32 30 00 02 00 00 00 30 00 00 4e 00 00 10120.....0..N..
0x02410030 4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00 MZ..............
[!] Range: 0x02430000 - 0x02434fff
Memory extracted to outdir5/malfind.876.2430000-2434fff.dmp
Hexdump:
0x02430000 00 00 00 10 00 00 00 00 53 4b 59 4e 45 54 63 6d ........SKYNETcm
0x02430010 64 2e 64 6c 6c 00 00 00 00 00 00 00 00 00 00 00 d.dll...........
0x02430020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x02430030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
Please let me know if you have questions or comments about these plug-ins, and if you're interested in helping to build several others.
http://mhl-malware-scripts.googlecode.com/files/idt.py
It only prints the IDT for one processor, so if anyone wants to update it to handle multiple processors, then feel free. Also if the system's KPCR is located at an address other than 0xFFDFF000 (see Brendan Dolan Gavitt's blog or Edgar Barbosa's paper), then you'll need to add the correct address to the script.
In order to test the script, I used Greg Hoglund's basic_interrupt.zip from rootkit.com. Below you can see that interrupt #46 (0x2E) is pointing inside the basic_int.sys driver.
# python volatility idt -f ../hooked_int.bin
IDT# ISR unused_lo segment_type system_segment_flag DPL P
0 0008:804df350 0 0e 0 0 1
1 0008:804df4cb 0 0e 0 0 1
[...]
46 0008:f8bcd550 0 0e 0 3 1
# python volatility modules -f ../hooked_int.bin
File Base Size Name
\WINDOWS\system32\ntoskrnl.exe 0x00804d7000 0x216700 ntoskrnl.exe
\WINDOWS\system32\hal.dll 0x00806ee000 0x020300 hal.dll
\??\C:\BASIC_INT.sys 0x00f8bcd000 0x001000 BASIC_INT.sys
Here is a Volatility plug-in for printing driver IRP function addresses:
http://mhl-malware-scripts.googlecode.com/files/driverirp.py
The script requires Andreas Schuster's driverscan.py plug-in. It works by over-riding the object_action method of the PoolScanDriver class. Thanks to Andreas for providing the framework. Thanks to AAron Walters for showing me how to over-ride the scanner methods.
In order to test the script, I used Jamie Butler's TCPIRPHook.zip from rootkit.com. Below you can see that the IRP_MJ_DEVICE_CONTROL function for Tcpip.sys is hooked by irphook.sys.
# python volatility driverirp -f ../irphook.bin
0x0218a830 0x823b45b8 7 0 0xb2ef3000 361600 Tcpip Tcpip \Driver\Tcpip
[0] [IRP_MJ_CREATE] => 0xb2ef94f9
[1] [IRP_MJ_CREATE_NAMED_PIPE] => 0xb2ef94f9
[2] [IRP_MJ_CLOSE] => 0xb2ef94f9
[3] [IRP_MJ_READ] => 0xb2ef94f9
[4] [IRP_MJ_WRITE] => 0xb2ef94f9
[5] [IRP_MJ_QUERY_INFORMATION] => 0xb2ef94f9
[6] [IRP_MJ_SET_INFORMATION] => 0xb2ef94f9
[7] [IRP_MJ_QUERY_EA] => 0xb2ef94f9
[8] [IRP_MJ_SET_EA] => 0xb2ef94f9
[9] [IRP_MJ_FLUSH_BUFFERS] => 0xb2ef94f9
[10] [IRP_MJ_QUERY_VOLUME_INFORMATION] => 0xb2ef94f9
[11] [IRP_MJ_SET_VOLUME_INFORMATION] => 0xb2ef94f9
[12] [IRP_MJ_DIRECTORY_CONTROL] => 0xb2ef94f9
[13] [IRP_MJ_FILE_SYSTEM_CONTROL] => 0xb2ef94f9
[14] [IRP_MJ_DEVICE_CONTROL] => 0xf8b615d0
# python volatility modules -f ../irphook.bin
File Base Size Name
\WINDOWS\system32\ntoskrnl.exe 0x00804d7000 0x216700 ntoskrnl.exe
\WINDOWS\system32\hal.dll 0x00806ee000 0x020300 hal.dll
\??\c:\irphook.sys 0x00f8b61000 0x001000 irphook.sys
I updated the usermode hook detection plug-in so that it uses pydasm in a cleaner, more reasonable method. Instead of checking the instruction string against a regex, it checks the opcode type and operand type using constants declared in the libdasm source code. Here is a copy of the new version:
http://mhl-malware-scripts.googlecode.com/files/usermode_hooks2.py
Also, as I mentioned in my original post about usermode hooks, it can be (and has now been) ported to kernel mode. Here is a copy of the version that detects IAT, EAT, and in-line hooks in kernel drivers instead of usermode modules:
http://mhl-malware-scripts.googlecode.com/files/kernel_hooks.py
I tested the script against a sample of the Skynet trojan. Below you can see that kernel_hooks.py detects the in-line hooks in ntoskrnl.exe functions.
# python volatility kernel_hooks -f ../skynet.bin -d outdir
Type: INLINE, Hooked driver: ntoskrnl.exe (0x804d7000 - 0x806ed780), Hooked function: IofCallDriver => jmp 0x8217f20b, Hooking driver:
Type: INLINE, Hooked driver: ntoskrnl.exe (0x804d7000 - 0x806ed780), Hooked function: IofCompleteRequest => jmp 0x820babc3, Hooking driver:
According to the write-up by McAfee, Skynet hooks two other functions using the in-line technique: NtFlushInstructionCache and NtEnumerateKey. The kernel_hooks.py does not currently detect these two, because they are not actually exported by ntoskrnl.exe, and the plug-in finds functions by walking the EAT. The addresses of the two functions are exposed through their corresponding SSDT entries, however, so its possible to find them that way and use the same check_inline function from kernel_hooks.py to inspect.
I also updated the "threads without modules" plug-in. As described in the original post on my blog, it detects hidden system/kernel threads. Using the new version, you don't have to make any adjustments to files in the Volatility core distribution anymore. Its more user-friendly now that it just over-rides the object_action method of the PoolScanThreadFast2 class in order to change the scanner's behavior.
http://mhl-malware-scripts.googlecode.com/files/orphan_threads.py
The output of this script still looks the same as before (sample shown for a memory dump of Tigger trojan):
# python volatility orphan_threads -f ../tigger.vmem
PID TID Offset StartAddress
------ ------ --------- ------------
4 248 0x2029da8 0xf623f54e
4 996 0x206fb90 0xf6240393
4 1372 0x2095700 0xf623ea46
4 564 0x209d3f8 0xf6240150
Last but not least, I updated the malfind plug-in for detecting hidden/injected code in usermode processes. You can find the latest version here:
http://mhl-malware-scripts.googlecode.com/files/malfind2.py
The new version includes the following changes:
- If it finds a PE file in the suspicious memory segment, it fixes up the ImageBase to match the address of the start of the memory region (in case you plan on opening the dumped EXE/DLL in IDA)
- If it finds shell code or non-executable data in the suspicious memory segment, it also prints a hexdump (aside from just a disassembly)
- It no longer makes external calls to volatility using the commands.getoutput() method. Instead, it accesses the desired functions using the volatility API, which greatly enhances speed. It went from 1 minute and 48 seconds down to just 4 seconds!! The change also makes it easier to use on Windows, because no path adjustments are needed.
# python volatility malfind2 -f ../zeus.vmem -d outdir
#
# svchost.exe (Pid: 972)
#
[!] Range: 0x00890000 - 0x008b7fff
Memory extracted to outdir2/malfind.972.890000-8b7fff.dmp
PE sections: {.odkx, .itiz, .ryd, .rsrc, }
#
# svchost.exe (Pid: 1064)
#
[!] Range: 0x01f00000 - 0x01f27fff
Memory extracted to outdir2/malfind.1064.1f00000-1f27fff.dmp
PE sections: {.odkx, .itiz, .ryd, .rsrc, }
Here's an example of what to see when processing a memory dump infected with Silent Banker. In this case, the suspicious memory is a trampoline for one of the trojan's API function hooks.
[!] Range: 0x01650000 - 0x01650fff
Memory extracted to outdir3/malfind.1876.1650000-1650fff.dmp
Hexdump:
0x01650000 58 68 05 00 66 01 68 00 00 00 00 68 00 00 80 7c Xh..f.h....h...|
0x01650010 68 68 18 0b 10 50 68 8f 9f 0a 10 c3 00 00 00 00 hh...Ph.........
0x01650020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x01650030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
Disassembly:
0x01650000 pop eax
0x01650001 push dword 0x1660005
0x01650006 push dword 0x0
0x0165000b push dword 0x7c800000
0x01650010 push dword 0x100b1868
0x01650015 push eax
0x01650016 push dword 0x100a9f8f
0x0165001b ret
Here's an example of what to see when processing a memory dump infected with CoreFlood. The suspicious memory in this case is the start of the code segment of the PE file (as mentioned in the original blog, CoreFlood strips its PE header).
[!] Range: 0x7ff80000 - 0x7ffadfff
Memory extracted to outdir4/malfind.248.7ff80000-7ffadfff.dmp
Hexdump:
0x7ff80000 81 ec 20 01 00 00 53 8b 9c 24 30 01 00 00 8b c3 .. ...S..$0.....
0x7ff80010 24 04 55 f6 d8 56 57 8b bc 24 34 01 00 00 68 05 $.U..VW..$4...h.
0x7ff80020 01 00 00 8d 4c 24 2c 51 1b c0 25 27 0c 00 00 33 ....L$,Q..%'...3
0x7ff80030 f6 8b ef 89 44 24 18 89 74 24 1c ff 15 b0 e1 f9 ....D$..t$......
Disassembly:
0x7ff80000 sub esp,0x120
0x7ff80006 push ebx
0x7ff80007 mov ebx,[esp+0x130]
0x7ff8000e mov eax,ebx
0x7ff80010 and al,0x4
0x7ff80012 push ebp
0x7ff80013 neg al
0x7ff80015 push esi
0x7ff80016 push edi
0x7ff80017 mov edi,[esp+0x134]
0x7ff8001e push dword 0x105
0x7ff80023 lea ecx,[esp+0x2c]
0x7ff80027 push ecx
0x7ff80028 sbb eax,eax
0x7ff8002a and eax,0xc27
0x7ff8002f xor esi,esi
0x7ff80031 mov ebp,edi
0x7ff80033 mov [esp+0x18],eax
0x7ff80037 mov [esp+0x1c],esi
0x7ff8003b call [0x7ff9e1b0]
Here 's an example of what to see when processing a memory dump infected with the Skynet trojan mentioned above. In this case, the suspicious memory holds a command and control IP address and the name of one of the files that it hides on disk using the rootkit.
#
# svchost.exe (Pid: 876)
#
[!] Range: 0x02410000 - 0x02414fff
Memory extracted to outdir5/malfind.876.2410000-2414fff.dmp
Hexdump:
0x02410000 18 00 00 00 68 74 74 70 73 3a 2f 2f 32 31 33 2e ....https://213.
0x02410010 31 33 33 2e 31 31 30 2e 32 31 2f 00 06 00 00 00 133.110.21/.....
0x02410020 31 30 31 32 30 00 02 00 00 00 30 00 00 4e 00 00 10120.....0..N..
0x02410030 4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00 MZ..............
[!] Range: 0x02430000 - 0x02434fff
Memory extracted to outdir5/malfind.876.2430000-2434fff.dmp
Hexdump:
0x02430000 00 00 00 10 00 00 00 00 53 4b 59 4e 45 54 63 6d ........SKYNETcm
0x02430010 64 2e 64 6c 6c 00 00 00 00 00 00 00 00 00 00 00 d.dll...........
0x02430020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x02430030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
Please let me know if you have questions or comments about these plug-ins, and if you're interested in helping to build several others.
iDefense Malware Analysis Training in Shanghai
I just returned home from a trip to Shanghai, China where I taught a 5-day course on malware analysis. Its the second time that iDefense offered this training course outside of the US (first time was at ICCYBER Brazil in 2008). The students ranged from professors at Chinese universities to forensic investigators from one of the very few forensic companies in China. A lot of the students came familiar with assembly language, debuggers, IDA, and basic unpacking, so we spent most of the time with more advanced topics and new tools. After the training, I spent a week in China with my wife, so it was a great trip altogether.
Our next training in the US will be held in NYC in late August. The next international training is scheduled for London in late October. If you're interested in either course, send me an email.
Our next training in the US will be held in NYC in late August. The next international training is scheduled for London in late October. If you're interested in either course, send me an email.
Friday, May 22, 2009
Volatility Plug-in for IAT/EAT/Inline Hook Detection
I released a new Volatility plug-in called usermode_hooks.py to detect IAT/EAT/Inline rootkit hooks in usermode processes.
To use it, make sure you have pydasm and pefile installed. Then place usermode_hooks.py in your memory_plugins directory. Call it like this:
# volatility usermode_hooks -d outputdir -p 1202 mem.dmp
# volatility usermode_hooks -d outputdir -f mem.dmp
The first only looks in the process with pid 1202 for hooks, whereas the second one looks in all processes.
Its normal for the script to generate a lot of "Memory Not Accessible" warnings. These messages come from executable.py in the Volatility core and are for auditing purposes. It happens because not every page is available when we try to extract the EXE and every loaded DLL. Just apply a command line filter like this:
# volatility usermode_hooks -d outputdir -f mem.dmp | egrep -v "Memory Not Accessible"
Since Windows has a lot of legit reasons for hooks, the script can generate a lot of false positives. The good news is, the most common ones are already whitelisted in the script and if you find others, its just Python, so you can add them yourself really quick. Here are some of the defaults:
* IAT hooks that point inside ntdll.dll
* IAT and Inline hooks that point inside Microsoft C runtime libraries
* IAT hooks of WMI.dll functions that point inside advapi32.dll
* IAT hooks of SCHANNEL.dll functions that point inside secur32.dll
* IAT hooks that point inside the Shim Engine (ShimEng.dll)
In order to demonstrate the IAT hook detection, I ran the script against a memory dump with Zeus installed. Zeus hooks the IAT of most processes and to be most effective - it also hooks the IAT of all DLLs loaded into the process. If you're interested in more Zeus details, check out my malware case study with Secure Science Corporation from 2006. Here is about 1/20th of the output from Zeus hooks:
From the output, you can see that usermode_hooks.py also prints an alert for any EXE or DLL with a TLS segment, which often indicates an anti-debugging mechanism. For the hooked IAT entries, the item to the left of the arrow (in square brackets) is the address of the IAT entry in the hooked module. The item to the right of the arrow is the address of the rootkit code. For the first line, 0x100130c in services.exe should store the address for ntdll.dll!NtQueryDirectoryFile. However, it points to 0x785388 instead, which is not inside ntdll.dll. In fact, its not in any module, just an allocated heap segment where the injected Zeus code exists.
For detecting suspicious executable heap segments and injected code, remember there is also the malfind plug-in for Volatility. By combining usermode_hooks.py and malfind.py, you can easily find out which functions a trojan hooks and extract the rootkit code (or rebuild the exe/dll) that exists at the hooked address in memory.
In order to demonstrate the inline hook detection, I ran usermode_hooks.py against a memory image with Silent Banker installed. Inline hooks (i.e. trampoline or detours) are the ones where the first few bytes of a function's prologue gets changed into a JMP that points to rootkit code. This is how most trojans work if they do inline hooking and also how most API hooking libraries work, such as Microsoft Detours, Mhook, and Devaire. Here is the output from Silent Banker:
For the inline hooks, the item to the left of the arrow is the virtual address of the hooked function in the process memory. To the right of the arrow is a dissassembly of the first instruction, which shows the rogue JMP to rootkit code. If you're interested in the purpose of each hook, with reverse engineered C source code of the rootkit functions, see Cyber Fraud: Tactics, Techniques, and Procedures by Rick Howard and other authors from the iDefense team.
Now let's take a look at Laqma - a Trojan that uses inline hooks but without the JMP instruction. Laqma uses a PUSH instruction followed by a RET. The 4 bytes PUSHed onto the stack is where the code resumes after the RET, so its just like a JMP but with a different instruction set. The iDefense book also includes a full chapter on Laqma. Here is the output:
CoreFlood is another big API hooking trojan (c'mon what trojan doesn't hook API functions - its the cool thing to do). CoreFlood likes IAT hooks.
If you just want to test out usermode_hooks.py without installing various malware, try downloading Hogfly's exemplar memory images (instructions on his Forensic Incident Response blog).
A few final notes:
* There are various ways for malware to evade hook detection (the best is to not use hooks ;-0) and still be malicious...
* Most of these hook detection methods can easily be ported to kernel drivers
* Aside from IAT/EAT/inline hooks, we'll have some other rootkit detection plug-ins released soon
* Big thanks to Brendan Dolan-Gavitt and AAron Walters for their help testing the script
If you find malware that hooks unusual API functions (or even if you find some common false positives), I'd love to hear about it.
To use it, make sure you have pydasm and pefile installed. Then place usermode_hooks.py in your memory_plugins directory. Call it like this:
# volatility usermode_hooks -d outputdir -p 1202 mem.dmp
# volatility usermode_hooks -d outputdir -f mem.dmp
The first only looks in the process with pid 1202 for hooks, whereas the second one looks in all processes.
Its normal for the script to generate a lot of "Memory Not Accessible" warnings. These messages come from executable.py in the Volatility core and are for auditing purposes. It happens because not every page is available when we try to extract the EXE and every loaded DLL. Just apply a command line filter like this:
# volatility usermode_hooks -d outputdir -f mem.dmp | egrep -v "Memory Not Accessible"
Since Windows has a lot of legit reasons for hooks, the script can generate a lot of false positives. The good news is, the most common ones are already whitelisted in the script and if you find others, its just Python, so you can add them yourself really quick. Here are some of the defaults:
* IAT hooks that point inside ntdll.dll
* IAT and Inline hooks that point inside Microsoft C runtime libraries
* IAT hooks of WMI.dll functions that point inside advapi32.dll
* IAT hooks of SCHANNEL.dll functions that point inside secur32.dll
* IAT hooks that point inside the Shim Engine (ShimEng.dll)
In order to demonstrate the IAT hook detection, I ran the script against a memory dump with Zeus installed. Zeus hooks the IAT of most processes and to be most effective - it also hooks the IAT of all DLLs loaded into the process. If you're interested in more Zeus details, check out my malware case study with Secure Science Corporation from 2006. Here is about 1/20th of the output from Zeus hooks:
From the output, you can see that usermode_hooks.py also prints an alert for any EXE or DLL with a TLS segment, which often indicates an anti-debugging mechanism. For the hooked IAT entries, the item to the left of the arrow (in square brackets) is the address of the IAT entry in the hooked module. The item to the right of the arrow is the address of the rootkit code. For the first line, 0x100130c in services.exe should store the address for ntdll.dll!NtQueryDirectoryFile. However, it points to 0x785388 instead, which is not inside ntdll.dll. In fact, its not in any module, just an allocated heap segment where the injected Zeus code exists.For detecting suspicious executable heap segments and injected code, remember there is also the malfind plug-in for Volatility. By combining usermode_hooks.py and malfind.py, you can easily find out which functions a trojan hooks and extract the rootkit code (or rebuild the exe/dll) that exists at the hooked address in memory.
In order to demonstrate the inline hook detection, I ran usermode_hooks.py against a memory image with Silent Banker installed. Inline hooks (i.e. trampoline or detours) are the ones where the first few bytes of a function's prologue gets changed into a JMP that points to rootkit code. This is how most trojans work if they do inline hooking and also how most API hooking libraries work, such as Microsoft Detours, Mhook, and Devaire. Here is the output from Silent Banker:
For the inline hooks, the item to the left of the arrow is the virtual address of the hooked function in the process memory. To the right of the arrow is a dissassembly of the first instruction, which shows the rogue JMP to rootkit code. If you're interested in the purpose of each hook, with reverse engineered C source code of the rootkit functions, see Cyber Fraud: Tactics, Techniques, and Procedures by Rick Howard and other authors from the iDefense team.Now let's take a look at Laqma - a Trojan that uses inline hooks but without the JMP instruction. Laqma uses a PUSH instruction followed by a RET. The 4 bytes PUSHed onto the stack is where the code resumes after the RET, so its just like a JMP but with a different instruction set. The iDefense book also includes a full chapter on Laqma. Here is the output:
CoreFlood is another big API hooking trojan (c'mon what trojan doesn't hook API functions - its the cool thing to do). CoreFlood likes IAT hooks.
If you just want to test out usermode_hooks.py without installing various malware, try downloading Hogfly's exemplar memory images (instructions on his Forensic Incident Response blog).A few final notes:
* There are various ways for malware to evade hook detection (the best is to not use hooks ;-0) and still be malicious...
* Most of these hook detection methods can easily be ported to kernel drivers
* Aside from IAT/EAT/inline hooks, we'll have some other rootkit detection plug-ins released soon
* Big thanks to Brendan Dolan-Gavitt and AAron Walters for their help testing the script
If you find malware that hooks unusual API functions (or even if you find some common false positives), I'd love to hear about it.
Feebs and CoreFlood Programs on Google Code
I recently uploaded copies of FindFeebs and DumpCore - two programs from past malware analysis projects.
Feebs is a DLL that hooks usermode API functions in order to hide processes, among other resources. The FindFeebs program is really just a fun example of how to use C++ vectors and process listing snapshots in order to determine what is hidden on the system. First, it takes a snapshot of the running processes. Then it queries the registry for the location of the Feebs DLL. Then it loads the Feebs DLL to "put on the blinders" of the API hooks. It gathers running processes again and then computes the difference. Here's a screen shot of the tool showing that Feebs is hiding an instance of svchost.exe on the machine.
DumpCore is a program to detect CoreFlood on systems by checking for the presense of the window class that is specific to this malware family. If it finds the window class, it takes the HWND and resolves the PID of the process that created it. This identifies the process that is infected with CoreFlood. DumpCore also uses some heuristics to find the CoreFlood DLL and data files on disk. It looks for any .dil files with a corresponding .dat file in the same directory with the same prefix (filename). The best part about DumpCore is it can also decrypt the configuration and stolen data files.
Both of these programs are over a year old. I posted them here for research/educational reasons and to encourage other people to write and share similar programs. Keep in mind, it might not always be a good idea to publicly post decryptors for cutting edge or prevalent malware.
Feebs is a DLL that hooks usermode API functions in order to hide processes, among other resources. The FindFeebs program is really just a fun example of how to use C++ vectors and process listing snapshots in order to determine what is hidden on the system. First, it takes a snapshot of the running processes. Then it queries the registry for the location of the Feebs DLL. Then it loads the Feebs DLL to "put on the blinders" of the API hooks. It gathers running processes again and then computes the difference. Here's a screen shot of the tool showing that Feebs is hiding an instance of svchost.exe on the machine.
DumpCore is a program to detect CoreFlood on systems by checking for the presense of the window class that is specific to this malware family. If it finds the window class, it takes the HWND and resolves the PID of the process that created it. This identifies the process that is infected with CoreFlood. DumpCore also uses some heuristics to find the CoreFlood DLL and data files on disk. It looks for any .dil files with a corresponding .dat file in the same directory with the same prefix (filename). The best part about DumpCore is it can also decrypt the configuration and stolen data files.
Both of these programs are over a year old. I posted them here for research/educational reasons and to encourage other people to write and share similar programs. Keep in mind, it might not always be a good idea to publicly post decryptors for cutting edge or prevalent malware.
Monday, April 13, 2009
Wedding Rings and Intel Core Two Duo?
I've previously reported when I lost my fingers and also when I miraculously benefited from backup fingers. Today I'm making my first blog posts with a wedding ring on my finger. I hope you enjoyed the update ;-)
It was also my birthday recently and due to my indecisiveness between an iMac and a Macbook pro, I bought both. Talk about core two duo!
It was also my birthday recently and due to my indecisiveness between an iMac and a Macbook pro, I bought both. Talk about core two duo!
Subscribe to:
Posts (Atom)