Recently I am doing some very interesting Pentester Academy courses. Thanks to them I am learning a lot, since they deal with very particular topics with clear examples. Today I am going to show you what I have learned about DLL Hijacking.
A DLL is a library of dynamic links. There are two types of DLLs: the system DLLs, which provide Windows itself, and the application DLLs, where the application developer divides its functionality into different DLLs.
The executables use these DLLs because it involves a modular design of the code and allows the code to be reused. In this way, dependencies are created, and depending on the importance of the DLL, if those dependencies fail to find the DLL, the program can continue to run if it is a DLL that implements a secondary functionality, or stop its execution if it is an essential DLL.
How does an application find the right DLL? By means of a specific search order:
- Search in the directory where the application was loaded.
- Search in the current directory.
- Search in the system directory using the GetSystemDirectory function.
- Search in the 16-bit system directory.
- Windows directory search using GetWindowsDirectory function.
- Search in all directories listed in the PATH environment variable.
If SafeDllSearchMode is active, option 2 becomes the second last one.
This provision allows you to perform some Hijacking DLL attacks, in which you create a malicious DLL and pass it off as one that an application needs. Next we are going to see a proof of concept of this type of attack.
First you need to download the Sysinternals Suite tool. Among all the tools offered by this package, we will run Procmon.exe.
As a test program we will use 7-zip.exe. When you open Procmon, you will see all the processes that are running right now in the system. First of all we must add a filter so that it only shows us the 7-zip processes, through the Filter tab:
We’ll add two more filters: one to indicate that the path contains the text “dll” (that way we’ll be shown only the dll) and another in which the Result field contains “NAME NOT FOUND”, which will indicate that you couldn’t find that dll. Finally, this is the result:
In order to find a suitable candidate to supplant, we will look for one whose operation is “CreateFile”, that has “Open” disposition and that has not found the DLL. “Bcrypt.dll” will work for us:
Next we’ll create a DLL that does some basic function, to make a first proof of concept, and then we’ll put it in the path where the exe is, with that name. This is the code that would have a basic DLL that shows a message when executed, is made in C:
We take advantage of the DllMain to run whatever we want. To compile it, we do it using the following command:
i686-w64-mingw32-gcc maliciousdll.c -o maliciousdll.dll -shared
Finally, we put it in the same folder where the 7-zip executable is, and rename it to “Bcrypt.dll”. And when you open it…
That’s great! Depending on the chosen dll, the application may or may not continue to run. In principle, we should be able to put a reverse shell instead of a message… Let’s try it.
Reverse Shell con DLL Hijacking
To get the payload from the shell, I used msfvenom. With -p I indicate the type of shell, a reverse shell tcp of windows, with lhost I indicate the ip of the attacking machine, with lport the port where I will be listening, with -a that the architecture is x86, with -platform that is for windows, and finally with -f I indicate that I want the payload in hexadecimal:
After getting the payload from the reverse shell of windows in hexadecimal, let’s create a new C script calling again the DllMain function:
We save this file and compile it as a dll using the command i686-w64-mingw32-gcc maliciousdll2.c -o maliciousdll2.dll -shared
Now we repeat the previous operation: we put the dll in the same place where the executable is, and we rename it as one of the dlls that the program uses and doesn’t find. For example, this time we can rename it as PROPSYS.dll. In our attacking machine we listen with nc -lvnp 1234. And when executing it…
However, a lot of antivirus detects this shell as a virus. Specifically, 12 of the 50 best known antivirus detects it. I am currently investigating how to avoid the antivirus. When I get it I will publish a new post of a more advanced version of this technique with antivirus evasion.