16

In the past few years, malware (and some pen-test tools like Metasploit's meterpreter payload) have begun to use reflective DLL injection (PDF) to load a DLL into the memory of a process. The benefit is that the file is never written to disk and is difficult to detect. Many examples I've seen are based on Joachim Bauch's work.

However, at DEF CON 20 Andrew King demonstrated that he was able to detect DLL's injected using reflective DLL injection. His presentation was called "Detecting Reflective Injection". Unfortunately, he has not released the source code (which he certainly is under no obligation to do).

UPDATE: Apparently I missed it, but Andrew did open-source this work a couple years ago: https://github.com/aking1012/dc20

In addition, a tool called "Antimeter" can detect the meterpreter engine when loaded using reflective dll injection. Again, closed source.

I understand that Andrew King's tool and Antimeter are both written in Python and use pydbg/pydasm in order to enumerate the memory of running executables.

Does anyone have some general source code (in Python or otherwise) that they are willing to share that demonstrates how to detect reflective DLL injection? There are memory forensic tools that can analyze a memory dump and find this, but I'm looking to execute an application on a running system (like antimeter does) and find processes with reflectively injected DLL's.

If you are interested in understanding how reflective DLL injection works, there is some open-source code written in Delphi that shows how to do this.

UPDATE: I tested and I can reflectively inject DLL's without admin rights (and as a regular user), but of course as a USER I can only inject into processes running at the same integrity level (and in my session)...but that still covers applications like the Office suite, Internet Explorer, etc.

Mick
  • 273
  • 1
  • 3
  • 11
  • 1
    it is the same as here: http://stackoverflow.com/questions/12697292/detecting-reflective-dll-injection You should update your question here too. – Hanan N. Dec 24 '12 at 10:22

4 Answers4

8

Consider what reflective DLL injection is: You exploit an application to get it to execute arbitrary code and this shell code loads a DLL into memory as a blob of data (all standard shell code stuff so far...) and then gives it execution such that the DLL loads itself properly as a DLL via a PE loader. The purpose of this whole idea: Let you write a full application that can compile to a DLL in a language of your choosing instead of writing the whole malware as assembly code with fixed memory offsets.

So to detect, you want to look for a PE file that exist only in memory and not on on disk and is running code in it. So scan through executable memory blobs for things that look like PE files, but aren't associated with any on disk file. That can be done as a post-exploitation forensics. Or if you want to detect real-time, hook calls normally associated with Reflective DLL Injection such as LoadLibrary, GetProcAddress and VirtualAlloc, and perform the previous step with more smarts. See ambuships.com

0xdabbad00
  • 1,065
  • 7
  • 5
  • Well, you don't exactly *exploit* an application to execute arbitrary code. As I understand it, reflective DLL injection is merely loading a DLL in another application without the use of the standard api calls like "CreateRemoteThread". So long as you have rights to write into another processes address space, you can do it. It doesn't require an exploit to accomplish it. See "BTMemoryModule" for a Delphi port of Joachim Bauch's work...complete with ready to compile example code: http://code.google.com/p/memorymodule/ – Mick Oct 01 '12 at 13:56
  • The whole purpose of reflective DLL injection is that you never write injected DLL file on disk so that you can avoid detection by AV. If you don't have the file on disk you can't use the regular injection technique (i.e CreateRemoteThread) hence you should use something as reflective DLL injection and that BTW makes the detection of the injected DLL harder. – Hanan N. Dec 24 '12 at 10:19
  • @Mick I don't think you are stating that clearly. You do _exploit_ an application to execute arbitrary code. However, if you are already ON the system, _post-exploitation_, then it is irrelevant... you can now write to memory in a process within your privilege rights, and then call the main in your injected DLL. – Jordan Hanna Jun 17 '14 at 15:26
2

I know this is quite old, but I am adding this for others that may come across this in the future.

Techniques, such as walking the VAD tree, can be useful for finding reflectively injected DLLs, as long as they haven't used specific anti-forensic techniques to cover their tracks in this area. There is a forensics paper on this from 2007 (PDF) that may be helpful towards future endeavors on detecting these.

Detection is not as straightforward as say looking at the loaded module list in a process' PEB (Process Environment Block, which reflective DLL doesn't get registered with); however, with good cross referencing and such tools could make a detection using the VAD tree instead. The VAD tree can be found in the EPROCESS block of the process (stored in system space).

Jordan Hanna
  • 378
  • 2
  • 5
0

I have done in in a big security product. With VAD walking in kernel mode but also with the help of a feature to detect remote thread.

First you detect remote thread to get the memory location. The injected thread will mostly have a start address that is not in any modules loaded by the application. This is not suppose to happen, after that you can go backward in memory and detect PE header or IAT/EAT section, this can help locate where the evil code is injected

Félix
  • 11
  • 1
  • So what do you do when you walk backwards from the start address and find you're at unallocated RAM? – Joshua Aug 22 '19 at 23:32
0

I wrote a tool (in C# and powershell using reflection) that walks thread stacks and reports where the function calls are loading from using GetMappedFile. Shows where all functions are executing from (i.e. which dll and where on disk) if the MappedFile property is blank, most likely reflectively loaded ;) https://github.com/secabstraction/PowerWalker