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.
0 comments:
Post a Comment