If you want to execute code stealthily on a machine and the antivirus stands in your way, you should think about avoiding the disk because this is the place where the antivirus reigns.
In this scenario, you might find it useful to execute a DLL directly inside the address space of a running process without touching the disk. This will bypass the AV in a stealthy and powerful way.
To achieve this, all you need to do is upgrade your DLL to Reflective DLL.
Introduction
The antivirus can sometimes be a significant problem during a penetration test in the post-exploitation phase. For dealing with this issue, several strategies have been proposed:
- making use of the command line / PowerShell
- executing a program (EXE) from memory
- executing a DLL from memory
Sometimes the command line interface is severely limited.
Also, by executing a program from memory you may still run into problems with the antivirus; you might get away with it by making use of a crypter (a tool that encrypts an executable, decrypting it during execution and executing it from memory) but most of them are detectable.
Thus, you may find it useful to use a DLL instead of an EXE to do your job.
Classic DLL Injection
The most popular way to inject a DLL is to follow the next steps:
- Open the target process with OpenProcess
- Find the address of the LoadLibrary function by making use of GetProcAddress
- Reserve memory for your DLL path in the remote process virtual address space by using VirtualAllocEx
- Write the DLL path in the previously reserved memory region with WriteProcessMemory
- Use CreateRemoteThread to create a new thread which will call the LoadLibrary function with the DLL path as a parameter
As it can be seen, the problem with this approach is that the DLL needs to be written to disk in order for it to be loaded with the LoadLibrary function. This presents a significant risk of being detected by the antivirus.
Executing DLLs from memory
An improvement to the previous approach is executing DLLs from memory. Manually, this can be achieved by following the next steps:
- Write the DLL headers into memory
- Write each section into memory by parsing the section table
- Optionally, you can set the protection flags for each section
- Do any relocation, if necessary
- Check imports and load any other imported DLLs
- Call the DllMain entry-point
You can find more information on this approach in these articles: Loading a DLL from memory and Loading Win32/64 DLLs “manually” without LoadLibrary().
Reflective DLL Injection
Executing DLLs from memory is not a simple task. Fortunately, you can use a technique called Reflective DLL injection. This approach was pioneered by Stephen Fewer of Harmony Security and allows you to easily inject a DLL from memory into a target process. Thus, there’s no need for the DLL to be written to disk.
The prominent feature of Reflective DLL injection is a function called ReflectiveLoader that takes care of all the details involved in manually executing DLLs from memory. All you have to do is include this function in your DLL. The DLL injector will then find and call this function and this will lead to a correct execution of the DLL.
This is how you can upgrade to Reflective DLL:
Step 1 – DLL Creation:
- Write the DLL code
- Add the ReflectiveLoader function (mentioned earlier) as an exported function
- Compile the DLL
Step 2 – DLL Injection
- Write the DLL into the virtual address space of the target process
- Find the address of the exported ReflectiveLoader function
- Call the ReflectiveLoader function
And that is all, the ReflectiveLoader function will correctly load itself and execute the DllMain entry-point.
Hello reflective world
Let’s upgrade a DLL to Reflective DLL.
After writing your DLL, your dllmain.cpp will have a structure similar to the following snippet
The next steps to upgrade to Reflective DLL consist of adding to your project the following files from ReflectiveDLLInjection project:
- ReflectiveDLLInjection.h
- ReflectiveLoader.h
- ReflectiveLoader.c
You should then modify “ReflectiveLoader.h” and add the following code (in order to compile for X86 architecture and use your own DllMain function):
#define WIN_X86 #define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
The last step is to add this include in your dllmain.cpp file:
#include "ReflectiveLoader.h"
Compile the DLL and congrats, you’ve built your first Reflective DLL!
For testing purposes, you can use the inject.exe binary, downloadable from here. For example, if the target process ID is 1336, injecting your DLL can be accomplished by issuing the command:
inject.exe 1336 C:\DLL\Reflective.dll
If your target process is PuTTY, the results should look similar to
Reflective DLL Injection – the Metasploit module
It’s useful to know that Metasploit includes a post exploitation module for Reflective DLL injection. It is located under
modules/post/windows/manage/reflective_dll_inject
To use this payload, you have to configure the following options:
- PATH: the path of the reflective DLL on your machine
- PID: the target process ID
- SESSION: the Meterpreter session
Then you can execute the exploit and “you’re in”
The sample DLL that we have injected opened a pop-up window on the target system:
Pleas note that the DLL did not touch the Windows system’s disk.
Conclusion
Although it may look difficult to inject a custom DLL, Reflective DLL Injection may be the perfect choice for bypassing the antivirus.
And it is also stealthy, because:
- There is no new process created, the DLL is injected into the address space of the target process
- The DLL is not present in the list of modules loaded by that process, because the DLL is not registered in the PEB (the PEB, or the Process Environment Block, is a process specific area of memory which, among others, contains information about the loaded modules)
Finally, you should know that the original Reflective DLL whitepaper is available here as a PDF.
Stay stealthy!
Reblogged this on Test.
LikeLike