0

According to this answer, DLL injection through CreateRemoteThread in conjunction with LoadLibraryA can be prevented by hooking LoadLibraryA. I went through the effort of doing an actual implementation of both the attacking side and defending side. I used this article as a baseline for creating both applications.

The defending side succesfully hooks LoadLibraryA and replaces it with a dummy function. The dummy function gets called whenever the defending process calls LoadLibraryA.

But why is it that the attacking process is still able to call the original LoadLibraryA after creating a remote thread in the defending process?

It's almost as if it does not access it through the IAT. Wouldn't it otherwise get forwarded to the dummy function?

1

It sounds like you might have already figured out what's going on (I'd have to look at the code in question, ideally running in a debugger, to say for sure though). However, I want to point out that this just doesn't actually work at all. At best, it's a speedbump that will break fragile payloads, but a knowledgeable attacker can bypass it easily. Here's a few ways, in roughly increasing complexity:

  • Use a different function, like LoadLibraryW or LoadLibraryExA (unless that internally calls LLA at some point, but I doubt it).
  • Use WriteProcessMemory (WPM) and VirtualProtectEx (VPX) to un-hook LLA, using the attacker's version of the function as the template.
  • Use WPM VirtualAllocEx to write the binary code of LLA into the target process, and inject your thread at that entry point.
  • Just dump the payload of whatever DLL you wanted to inject into the target's address space and enter that.
  • Do everything that LLA does (including stuff like ensuring new threads call the library's DllMain), but remotely to the target process, before even spawning a thread in it.

In other words, even if your hook prevent calling CreateRemoteThread to the address of LLA, it doesn't actually do anything significant against DLL injection in general.

| improve this answer | |
  • You're absolutely right. I was aware that it's quite difficult to protect against DLL injections, but I didn't understand it in as much detail as you have provided. Thanks for the explanation. The reason why I implemented this is because of a school assignment. I wanted to get some experience with DLL injections first hand because I recall using it as a scriptkiddie over a decade ago :P I had no prior experience with Windows API and the PE format, so this was really educational. – user1534664 May 9 at 14:59
0

I slept on it for a night and I found the answer. There are two reasons:

The attacking module finds the address of LoadLibraryA using GetProcAddress. This is based on the assumption that the address is the same between both processes, which happens to be the case for functions in kernel32.dll. But because only the IAT of the defending process is hooked, the IAT of the attacking module still has the address of the original LoadLibraryA call.

But besides that I also tested the behavior of GetProcAddress in my defending module, and it returns the same address for LoadLibraryA both before and after the IAT is hooked. I can only infer from this that the way GetProcAddress is implemented, it has some other way than searching the IAT.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.