Ransomware DLL Hijacking & “The Canary DLL”

You might have seen in some of the security news sites, articles reporting about a security researcher discovering a method to stop certain ransomware samples from running, including Thanos, Conti, REvil etc. The method in question is known as DLL Hijacking and I thought it would be a great opportunity to talk about it in a little more detail, it’s limitations and how a blue team could leverage this in order to add another layer of security.

Technically, DLL Hijacking is not a vulnerability, rather used as an exploitation technique. The technique is used so code controlled by the attacker can be executed under the context of an application or a service, with the said application in this context being tricked into thinking this was the intended library that it was looking for. DLL hijacking works by dropping your DLL containing the code you want to execute into the “Standard Search Order” that you, as an attacker, have the ability to write to.

To illustrate this, take the below example which I stole and modified:

In the above example we can see the search order an application goes through in order to retrieve a DLL.

  1. First it will check to see if a DLL is already loaded into memory. If it finds a DLL that matches this, it will go no further
  2. If this fails it will look in the “Known DLLs” location to find the location of a known trusted DLL’s
  3. Next it will look in the applications directory. This is where the application is being executed from
  4. Then system directory (system32)
  5. Then the 16-bit system directory (system)
  6. Then the Windows directory (windows)
  7. The user’s current directory
  8. Then the directories listed in %PATH%

Knowing this we can manipulate the target application provided we meet the basic requirements:

  1. We have the ‘write’ ability to the applications directory or other subsequent search directories
  2. Know the name of the DLL that is being requested

Then in theory, all we need to do is simply rename our DLL containing our code to the same one the application requires. It’s as simple as that.

Why does this work?

The question is, why does this work? Simply put if you as a programmer are designing an application and requires a library, such as “unknown.dll”, you might program something like


But what if you don’t know where the library is located? What if the location of the library changes between versions of Windows? To combat this, you could simply write


and allow the application on execution to find the DLL instead.

Ransomware Testing

Ok so now for our testing. Malvuln has tested and provided a POC of the ransomware samples that are vulnerable to this. We’ve taken the C code and added a line (will explain later on) but essentially what this code is doing is checking to see if the process calling this DLL resides in the system32 directory. If it does not it will terminate the process.

//Original POC provided by @malvuln https://www.malvuln.com/advisory/be60e389a0108b2871dff12dfbb542ac.txt
//canary.DLL- AH


To Compile:
1) save the below as canarydll.c
2) gcc -c canarydll.c -m32
3) gcc -shared -o canary.dll canarydll.o -m32
4) Rename the DLL name based off the following lists:


#include "windows.h"
#include "stdlib.h"

BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason, LPVOID reserved){
  switch (reason) {
   system ("cmd /c nslookup token.canarytokens.com"); //a canary token triggered to notify the DLL has been used
   MessageBox(NULL, "This DLL has been called by ransomware and has been terminated.", "Ransomware POC", MB_OK);
   if(GetCurrentDirectory(MAX_PATH, buf))
   if(strcmp("C:\\Windows\\System32", buf) != 0){ //check to see if the process calling this DLL is located in system32
   	 HANDLE handle = OpenProcess(PROCESS_TERMINATE, FALSE, getpid());
     if (NULL != handle) {   //if not it will be terminated
        TerminateProcess(handle, 0);
  return TRUE;

We use gcc to compile our DLL and we are ready to test.

Two samples were tested, Conti and REvil. Renaming our DLL to a DLL the ransomware samples search for & placing our DLL in the same directory as to where the ransomware is being executed from, we can successfully stop the execution.

A simple technique but in this user case it worked well as we executed the application from the same directory as where our DLL was placed. So, for example, and as Malvuln discusses, placing this DLL on a network share would stop execution of the ransomware.

But this has some important caveats, the main one being that this works provided the ransomware was also executed from the same said network share. This however wouldn’t work if the ransomware was executed, let’s say anywhere like “C:\example” where our DLL isn’t located, as the legitimate DLL (CRYPTSP.dll) is located in system32. In other words, as soon as it reaches search order #2 in the above diagram the ransomware has found the DLL it was looking for.

The Canary DLL

To circle back to that extra line of code we added, all this does is make a simple DNS call to our canary token. When the DLL is executed a nslookup is done to our token which will then in turn email us a notification to say it has fired. This might be useful for blue teamers in other scenarios where it would be useful to track the use of DLL’s or executables being executed on the estate. The neat thing about it is that no external libraries were used in the code, but other libraries such as SMTP could be added for even more functionality.

Resources & Credit

To learn more I would absolutely read this fantastic guide on DLL Hijacking written by itm4n (a lot of fantastic diagrams that I stole from to write this):

Windows DLL Hijacking (Hopefully) Clarified: https://itm4n.github.io/windows-dll-hijacking-clarified/

Microsoft on Library Search Order: https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order

The security research that found the original exploit:

Site: https://www.malvuln.com/

GitHub Repo of Other searched for but NOT FOUND DLL’s: https://github.com/malvuln/RansomDLLs

Twitter: @maluvln @hyp3rlinx