A faithful transposition of the key features/functionality of @itm4n's PPLDump project as a BOF.

Overview

PPLDump BOF

Who worked on this?

  • Justin Lucas (@the_bit_diddler)
  • Brad Campbell (@hackersoup)

What is this?

Jokingly, an exercise of my own personal sanity maintenance. In reality, this is a faithful porting of @itm4n's PPLDump project.

As one may imagine, this is a fully-fledged BOF to dump an arbitrary protected process.

But, why?

The goal isn't the destination, but the journey. Or that's what I told myself to make the endless suffering of this endeavor a bit less acute. :)

Cool, but what are the requirements?

  • An administrative session of some kind
  • Knowledge of the PPL process ID (PID) you wish to dump
  • Currently residing in a 64-bit process
  • Currently residing on a Windows 10 or greater endpoint

What is this massive fileheader.h header, why so sus?

This is a one-to-one dump of the original resource file created during building the PPLDump project DLL, and you're more than welcome and encouraged to fact-check this. As the original resource file was embedded (and therefore not usable due to a lack of linking for Beacon Object Files). This was a way around that. In the future, I may implement this ability to bring them arbitrarily, but use at your own risk.

What do I need to know before doing anything?

  • You MUST change the wcPID varaible, found in main.c to be the same as your desired process ID. Seriously.
  • As a result, you MUST build this project from source per endpoint you wish to do this on. There's a Makefile, just run it.
  • Optionally, you may change the location/name of the dmp file. This is DEFAULT_DUMP_FILE in src/headers/exploit.h

How do I run it?

  1. Build the project via the Makefile in the src directory, ensuring again, that you have ABSOLUTELY changed the variable mentioned above.
  2. Load the Aggressor CNA file in the dist directory.
  3. Within your Beacon of choice (and one that meets the criteria): ppldump YOUR_PROTECTED_PROCESS_PID

To-Do Items (if I have the time)

  • Port more function calls to syscalls, but this is a very time-consuming process.
  • Fix the unfortunate fail-pile of casting the desired process identifier to a wchar_t*. Nothing I tried worked.
  • Add support for a user-supplied DLL for other shenanigans.
You might also like...
Strstr with user-supplied needle and filename as a BOF.

Needle_Sift_BOF What is this? Strstr with user-supplied needle and filename as a BOF. Why? Why not? Supply what you want, and don't worry about downlo

BOF implementation of the research by @jonasLyk and the drafted PoC from @LloydLabs

Self_Deletion_BOF BOF implementation of the research by @jonasLyk and the drafted PoC from @LloydLabs Why? I didn't see that it currently existed (via

A BOF port of the research of @thefLinkk and @codewhitesec

HandleKatz_BOF What is this? This is a (mostly complete) port of the functionality presented by @thefLink and Code White GmbH. You guys deserve a larg

DLL Hijack Search Order Enumeration BOF
DLL Hijack Search Order Enumeration BOF

DLL Hijack Search Order BOF What is this? This is a Cobalt Strike BOF file, meant to use two arguments (path to begin, and a DLL filename of interest)

DLL Exports Extraction BOF with optional NTFS transactions.
DLL Exports Extraction BOF with optional NTFS transactions.

DLL Exports Extraction BOF What is this? This is a Cobalt Strike BOF file, meant to use two or three arguments (path to DLL, and/or a third argument [

POC tool to convert CobaltStrike BOF files to raw shellcode

BOF2Shellcode POC tool to convert a Cobalt Strike BOF into raw shellcode. Introduction This code was written as part of a blog tutorial on how to conv

A BOF to parse the imports of a provided PE-file, optionally extracting symbols on a per-dll basis.

PE Import Enumerator BOF What is this? This is a BOF to enumerate DLL files to-be-loaded by a given PE file. Depending on the number of arguments, thi

A BOF for enumerating version information for DLLs associated for a Beacon process.
A BOF for enumerating version information for DLLs associated for a Beacon process.

DLL Image Resource Version Enumeration BOF What is this? This is a Cobalt Strike BOF file (a mildly massaged port of @N4k3dTurtl3's existing PoC , mea

A BOF to interact with COM objects associated with the Windows software firewall.

Firewall_Enumerator_BOF What is this? This is meant as a supplement to interact with the Windows firewall via COM interfaces. Did you derive inspirati

Comments
  • Some code correctness and hygiene issues

    Some code correctness and hygiene issues

    Some code correctness issues in exploit.h

    These are hygiene issues. Some of these are low priority and edge cases.

    An OUT param is written to before the function succeeds leading to an edge case where memory is leaked if the function fails.

    BOOL TokenGetSid(HANDLE hToken, PSID* ppSid) {
        BOOL bReturnValue = TRUE;
        DWORD dwSize = 0;
        PTOKEN_USER pTokenUser = NULL;
    
        if ( !sFunctionPointerStruct.StructGetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize) ) {
            if ( sFunctionPointerStruct.StructGetLastError() != ERROR_INSUFFICIENT_BUFFER ) {
                BeaconPrintf(CALLBACK_ERROR, "We received an unexpected value from TokenGetSid's GetTokenInformation in utils.h.\n");
                goto end;
            }
        }
    
        // Second call to populate
        pTokenUser = (PTOKEN_USER)sFunctionPointerStruct.StructLocalAlloc(LPTR, dwSize);
        if (!pTokenUser) {
            goto end;
        }
    
        if ( !sFunctionPointerStruct.StructGetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize) ) {
            BeaconPrintf(CALLBACK_ERROR, "We received an unexpected value from TokenGetSid's GetTokenInformation in utils.h.\n");
            goto end;
        }
    
        *ppSid = (PSID)sFunctionPointerStruct.StructLocalAlloc(LPTR, SECURITY_MAX_SID_SIZE);
        if (!*ppSid) {
            BeaconPrintf(CALLBACK_ERROR, "Error in setting dereferenced value in utils.h TokenGetSid ppsid.\n");
            goto end;
        }
    
        if ( !sFunctionPointerStruct.StructCopySid(SECURITY_MAX_SID_SIZE, *ppSid, pTokenUser->User.Sid) ) {
            BeaconPrintf(CALLBACK_ERROR, "Error in setting copying SID in utils.h TokenGetSid ppsid.\n");
            goto end;
    ! bReturnValue is FALSE but OUT param *ppSid contains allocated memory which will be leaked in this case because the caller won't free it since the function failed
        }
    

    See https://github.com/EspressoCake/PPLDump_BOF/blob/0eed2e76f0031cfeaed0358c215d5b26e49b3f1b/src/headers/utils.h#L197

    Edge case leak if allocation fails

    BOOL TokenCompareSids(PSID pSidA, PSID pSidB) {
        BOOL bReturnValue = FALSE;
        LPWSTR pwszSidA   = NULL;
        LPWSTR pwszSidB   = NULL;
    
        if ( sFunctionPointerStruct.StructConvertSidToStringSidW(pSidA, &pwszSidA) && sFunctionPointerStruct.StructConvertSidToStringSidW(pSidB, &pwszSidB) ) {
            bReturnValue = MSVCRT$_wcsicmp(pwszSidA, pwszSidB) == 0;
            sFunctionPointerStruct.StructLocalFree(pwszSidA);
            sFunctionPointerStruct.StructLocalFree(pwszSidB);
        } else {
    ! it's possible one of the calls to sFunctionPointerStruct.StructConvertSidToStringSidW failed and this branch will leak the Sid for the success case
            BeaconPrintf(CALLBACK_ERROR, "We have encountered an error in TokenCompareSids within utils.h: 0x%08x\n", sFunctionPointerStruct.StructGetLastError());
        }
    
        return bReturnValue;
    }
    

    See: https://github.com/EspressoCake/PPLDump_BOF/blob/0eed2e76f0031cfeaed0358c215d5b26e49b3f1b/src/headers/utils.h#L231

    There is another case here:

    							if (TokenGetSid(hTokenDup, &pSidTmp) && TokenGetUsername(hTokenDup, &pwszUsername))
    

    https://github.com/EspressoCake/PPLDump_BOF/blob/0eed2e76f0031cfeaed0358c215d5b26e49b3f1b/src/headers/exploit.h#L755

    Consider calling ADVAPI32!IsTokenRestricted instead of rolling your own function here:

    BOOL TokenIsNotRestricted(HANDLE hToken, PBOOL pbIsNotRestricted) {
    
    ...
    

    See https://github.com/EspressoCake/PPLDump_BOF/blob/0eed2e76f0031cfeaed0358c215d5b26e49b3f1b/src/headers/utils.h#L366

    Fail to check if memory was successfully allocated for guid

    Check for failed allocation from MiscGenerateGuidString

        MiscGenerateGuidString(&pwszGuid);
    

    https://github.com/EspressoCake/PPLDump_BOF/blob/0eed2e76f0031cfeaed0358c215d5b26e49b3f1b/src/headers/exploit.h#L313

    Leak of token

      if (bCurrentUserIsSystem) {
            if ( !sFunctionPointerStruct.StructOpenProcessToken(NtCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ADJUST_PRIVILEGES, &hCurrentToken) ) {
                BeaconPrintf(CALLBACK_ERROR, "Failed to open process token in stage 6. Exiting.\n");
                goto end;
            }
        } else {
            if ( !sFunctionPointerStruct.StructOpenThreadToken(sFunctionPointerStruct.StructGetCurrentThread(), TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ADJUST_PRIVILEGES, FALSE, &hCurrentToken) ) {
                BeaconPrintf(CALLBACK_ERROR, "Failed to open thread token in stage 6. Exiting.\n");
                goto end;
            }
        }
    
        if ( !TokenCheckPrivilege(hCurrentToken, L"SeAssignPrimaryTokenPrivilege", TRUE) ) {
            BeaconPrintf(CALLBACK_ERROR, "Failed to alter token (SeAssignPrimaryTokenPrivilege) in stage 6. Exiting.\n");
            goto end;
        } else {
            BeaconPrintf(CALLBACK_OUTPUT, "Successfully assigned SeAssignPrimaryTokenPrivilege.\n");
        }
    
        if ( !sFunctionPointerStruct.StructDuplicateTokenEx(hCurrentToken, MAXIMUM_ALLOWED, NULL, SecurityAnonymous, TokenPrimary, &hNewProcessToken) ) {
            BeaconPrintf(CALLBACK_ERROR, "Failed DuplicateTokenEx call in stage 6. Exiting.\n");
            goto end;
        } else {
            BeaconPrintf(CALLBACK_OUTPUT, "Successfully duplicated token.\n");
        }
    ! No call to CloseHandle on hCurrentToken
    

    https://github.com/EspressoCake/PPLDump_BOF/blob/0eed2e76f0031cfeaed0358c215d5b26e49b3f1b/src/headers/exploit.h#L356

    possible wild NtClose call on hProcessToken in EnableRequisitePrivileges

    BOOL EnableRequisitePrivileges(void) {
        NTSTATUS judgement;   
    	DWORD dwFailCount = 0;
    	HANDLE hProcessToken; <<<<<<<<<<<<<<<<< not initialized to NULL
    	HANDLE hTargetProcess = NULL;
    	BOOL bIsSystem = FALSE;
    	DWORD dwProcessId = 0;
    	DWORD dwProcessProtectionLevel = 0;
    	LPWSTR pwszProcessProtectionName = NULL;
    	DWORD dwProcessIntegrityLevel = 0;
    	LPCWSTR ppwszRequiredPrivileges[2] = { L"SeDebugPrivilege", L"SeImpersonatePrivilege" };
    
        judgement = NtOpenProcessToken(NtCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hProcessToken);
        if (judgement != STATUS_SUCCESS) {
            dwFailCount++;
            BeaconPrintf(CALLBACK_OUTPUT, "Error in ascertaining current user token.\n");
    !        NtClose(hProcessToken);    <<<<<< if NtOpenProcessToken fails, hProcessToken won't be written to. This results in a wild close on hProcessToken because it was not initialized
    
            return FALSE;
    

    https://github.com/EspressoCake/PPLDump_BOF/blob/0eed2e76f0031cfeaed0358c215d5b26e49b3f1b/src/headers/exploit.h#L514

    Handle of hTransaction leaked in WritePayloadDllTransacted

    No call to CloseHandle for hTransaction

    https://github.com/EspressoCake/PPLDump_BOF/blob/0eed2e76f0031cfeaed0358c215d5b26e49b3f1b/src/headers/exploit.h#L996

    FindFileForTransaction leaks memory for pSidTarget

    Need a call to sFunctionPointerStruct.StructLocalFree(pTargetSid); at cleanup in FindFileForTransaction

    https://github.com/EspressoCake/PPLDump_BOF/blob/0eed2e76f0031cfeaed0358c215d5b26e49b3f1b/src/headers/exploit.h#L1049

    opened by JohnLaTwC 1
Owner
Somewhere, doing something.
null
Allows to swap the Fn key and left Control key and other tweaks on Macbook Pro and Apple keyboards in GNU/Linux

A patched hid-apple kernel module UPDATE August 2020: swap_fn_leftctrl is now built-in in Linux 5.8 ?? UPDATE Jun 2020: New feature added (swap_fn_f13

Zakhar Semenov 303 Nov 23, 2022
This project simulates the functionality of the Unix Bash shell.

Minishell This project simulates the functionality of the unix Bash shell. Description The project aim was to recreate the functionality of the unix B

Andreas Gebert 0 Jan 6, 2022
anthemtotheego 392 Dec 1, 2022
Cobalt Strike Beacon Object File (BOF) that takes the name of of a PE file as an argument and spawns the process in a suspended state

Beacon Object File (BOF) that spawns an arbitrary process from beacons memory. Supports Parent Process ID (PPID) spoofing & blocking non-MS signed DLLs from loading into the processes memory (some EDR DLLs).

boku 348 Nov 15, 2022
Cobalt Strike BOF - Bypass AMSI in a remote process with code injection.

Cobalt Strike BOF - Inject AMSI Bypass Cobalt Strike Beacon Object File (BOF) that bypasses AMSI in a remote process with code injection. Running inje

boku 304 Nov 15, 2022
EarlyBird process hollowing technique (BOF) - Spawns a process in a suspended state, inject shellcode, hijack main thread with APC, and execute shellcode

HOLLOW - Cobalt Strike BOF Authors: Bobby Cooke (@0xBoku) Justin Hamilton (@JTHam0) Octavio Paguaga (@OakTree__) Matt Kingstone (@n00bRage) Beacon Obj

Bobby Cooke 201 Nov 12, 2022
Proof of concept Beacon Object File (BOF) that attempts to detect userland hooks in place by AV/EDR

Detect-Hooks Detect-Hooks is a proof of concept Beacon Object File (BOF) that attempts to detect userland API hooks in place by AV/EDR. The BOF will r

anthemtotheego 120 Nov 19, 2022
Cobalt Strike BOF that uses a custom ASM HalosGate & HellsGate syscaller to return a list of processes

HalosGate Processlist Cobalt Strike BOF Cobalt Strike Beacon Object File (BOF) that uses a custom HalosGate & HellsGate syscaller, written in assembly

Bobby Cooke 50 Nov 9, 2022
Cobalt Strike Beacon Object File (BOF) that uses handwritten shellcode to return the process Environment strings without touching any DLL's.

Cobalt Strike "Where Am I?" Beacon Object File Cobalt Strike Beacon Object File (BOF) that uses handwritten shellcode to return the process Environmen

Bobby Cooke 92 Nov 30, 2022
CobaltStrike BOF - Inject ETW Bypass into Remote Process via Syscalls (HellsGate|HalosGate)

Cobalt Strike BOF - Inject ETW Bypass Inject ETW Bypass into Remote Process via Syscalls (HellsGate|HalosGate) Running InjectEtwBypass BOF from Cobalt

Bobby Cooke 235 Nov 18, 2022