Ionut Popescu, Senior Security Consultant @ KPMG Romania has been accepted as speaker at the prestigious DEFCON conference. He will present one of his projects: NetRipper tool, developed especially to be used in penetration testing projects.
The conference will be held in Las Vegas, Nevada, between 6-9 August 2015.
NetRipper – Short description
The post-exploitation activities in a penetration test can be challenging if the tester has low-privileges on a fully patched, well configured Windows machine. This work presents a technique for helping the tester to find useful information by sniffing network traffic of the applications on the compromised machine, despite his low-privileged rights. Furthermore, the encrypted traffic is also captured before being sent to the encryption layer, thus all traffic (clear-text and encrypted) can be sniffed. The implementation of this technique is the tool called NetRipper which uses API hooking to do the actions mentioned above and which has been especially designed to be used in penetration tests, but the concept can also be used to monitor network traffic of employees or to analyze a malicious application.
https://www.defcon.org/html/defcon-23/dc-23-speakers.html#Popescu
And we will be waiting to share his experience at the conference in the next article.
Saw your Defcon presentation, thought it was interesting. Had not heard of reflective DLL injection before but it makes sense, even though it is a bit of additional work. Kind of wondering though why did you use a Hook() function? Since each hook is unique I believe it would have been easier to give each hook the same function signature as the function being called then simply place your pointer in the IAT to perform the hook (or for dynamically loaded dll’s replace the address pointed to in the call with your hooked function address. Which can be found with a pointer search.) In both cases there is no need to copy any bytes as you are simply replacing the pointer to the intended function with your hook pointer. This works with any API call and most internal functions. Since you are already stepping through the IAT with your reflective loading it just seemed odd to me that you did not use this for your hooks. Is there a specific reason or just a prefrence?
LikeLike
Hi! There are multiple methods of hooking: EAT hooking, IAT hooking, Inline hooking (the method I used) and other. Each method have it’s own advantages and disadvantages. For example, IAT and EAT hooking are easy to implement, but Inline hooking is more powerful: I chose this because with inline hooking you make sure you catch all function calls. For example, an application may NOT import a function that will lately call. There are a lot of applications that use LoadLibrary and GetProcAddress in order to dynamically call functions. If I would use IAT hooking, I won’t be able to catch these functions.
Also, in this project, not all functions are exported or imported. So I cannot IAT hook a non-imported function, a function from a statically linked library.
As a preference, however, I used a generic function to hook all other functions because I wanted a simple and generic way to hook all the functions. So, all my hooks are a “call DLL!Hook” which will find from the stack the hooked function address.
Please let me know if this makes sense or if you have any other question. Also, any suggestion is appreciated.
Thank you!
LikeLike
Yes it makes sense, it’s been quite a while since I hooked using by modifying an API and I dismissed it for a few reasons. I know to a simple method to detect such hooks. (An old method of defeating softice breakpoints) and the copied bytes would be version dependent if statically added to your hook. But you avoided this issue by using a generic hook that dynamically copies the bytes. I don’t see how you detect if the call overwrites to the middle of an instruction? What I mean is how do you prevent overwriting half an instruction and leaving the other half untouched resulting in the 2 half being executed separately and potentially causing a crash?
Another question regarding your hooking technique. How do you ensure that the memory for your injected DLL is freed up when the application being hooked is closed? Do you rely on windows to free the memory which may cause a memory leak and just not worry about it, or do you have some clever method to free up the memory yourself?
LikeLike
“What I mean is how do you prevent overwriting half an instruction and leaving the other half untouched resulting in the 2 half being executed separately and potentially causing a crash?”
I don’t avoid this at this time, but I plan to fix this. This can happen only if the hook is active in a thread, and other thread tries to call the function “in the middle of the hook”.
For Windows APIs this is simple: Windows APIs starts like this:
nop
nop
nop
nop
nop
mov edi, edi
<>
This was designed for Windows hot-patching. What does the mov edi, edi do? Nothing. It is a two byte instruction that allows it to be replaced with a short jump (jmp -5) that will jump where the nops start. So, we have to replace the nops with a call/jmp 0xaddress and mov edi, edi with jmp -5. And this is thread safe.
Other application does not use this concept and it may be difficult to safely hook them. Most common tools for API hooking use “thread freezing” and get each thread context in order to make sure there is no thread in the middle of the hook that will crash the program.
I will implement the Windows hot-patching method, but I am not really sure what to do about the other function. I hope I will find a good way to avoid crashes.
“How do you ensure that the memory for your injected DLL is freed up when the application being hooked is closed?”
I don’t do anything. When a process is terminated, all it’s allocated memory is freed. The injection use “VirtualAllocEx” API that will alloc memory in the remote process memory and Windows will automatically free this memory when the process is terminated.
LikeLike
Good evening , from Germany from Romania . I am the Adrian and I have a blog Secuirty , Dotcom Security in Germany .
I am very grateful for the publication of the tools we’ve all been waiting for and I also reported . Many thanks!
LikeLike