mirror of
https://github.com/trickster0/OffensiveRust
synced 2026-06-08 17:54:47 +00:00
@@ -0,0 +1,22 @@
|
||||
[package]
|
||||
name = "PEB_Walk"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
|
||||
[dependencies.windows-sys]
|
||||
version = "0.36.1"
|
||||
features = [
|
||||
"Win32_Foundation",
|
||||
"Win32_Security",
|
||||
"Win32_System_Threading",
|
||||
"Win32_UI_WindowsAndMessaging",
|
||||
"Win32_System_LibraryLoader",
|
||||
"Win32_System_Kernel",
|
||||
"Win32_System_WindowsProgramming",
|
||||
"Win32_System_SystemServices",
|
||||
"Win32_System_Diagnostics_Debug"
|
||||
]
|
||||
@@ -0,0 +1,105 @@
|
||||
use core::arch::asm;
|
||||
use windows_sys::Win32::UI::WindowsAndMessaging::MB_OK;
|
||||
use windows_sys::Win32::Foundation::*;
|
||||
use windows_sys::Win32::System::Threading::PEB;
|
||||
use windows_sys::Win32::System::WindowsProgramming::LDR_DATA_TABLE_ENTRY;
|
||||
use windows_sys::Win32::System::SystemServices::{IMAGE_DOS_HEADER, IMAGE_EXPORT_DIRECTORY};
|
||||
use windows_sys::Win32::System::Diagnostics::Debug::{IMAGE_NT_HEADERS64, IMAGE_DATA_DIRECTORY};
|
||||
|
||||
mod types;
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub unsafe fn __readgsqword(offset: types::DWORD) -> types::DWORD64 {
|
||||
let out: u64;
|
||||
asm!(
|
||||
"mov {}, gs:[{:e}]",
|
||||
lateout(reg) out,
|
||||
in(reg) offset,
|
||||
options(nostack, pure, readonly),
|
||||
);
|
||||
out
|
||||
}
|
||||
|
||||
fn get_module_base_addr(module_name: &str) -> HINSTANCE {
|
||||
unsafe {
|
||||
let peb_offset: *const u64 = __readgsqword(0x60) as *const u64;
|
||||
let rf_peb: *const PEB = peb_offset as * const PEB;
|
||||
let peb = *rf_peb;
|
||||
|
||||
let mut p_ldr_data_table_entry: *const LDR_DATA_TABLE_ENTRY = (*peb.Ldr).InMemoryOrderModuleList.Flink as *const LDR_DATA_TABLE_ENTRY;
|
||||
let mut p_list_entry = (*peb.Ldr).InMemoryOrderModuleList.Flink;
|
||||
|
||||
loop {
|
||||
let buffer = std::slice::from_raw_parts(
|
||||
(*p_ldr_data_table_entry).FullDllName.Buffer,
|
||||
(*p_ldr_data_table_entry).FullDllName.Length as usize);
|
||||
let dll_name = String::from_utf16_lossy(buffer);
|
||||
if dll_name.to_lowercase().starts_with(module_name) {
|
||||
let module_base: HINSTANCE = (*p_ldr_data_table_entry).Reserved2[0] as HINSTANCE;
|
||||
return module_base;
|
||||
}
|
||||
p_list_entry = (*p_list_entry).Flink;
|
||||
p_ldr_data_table_entry = (*p_list_entry).Flink as *const LDR_DATA_TABLE_ENTRY;
|
||||
|
||||
if p_list_entry == (*peb.Ldr).InMemoryOrderModuleList.Flink {
|
||||
println!("Module not found!");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_proc_addr(module_handle: HINSTANCE, function_name: &str) -> FARPROC {
|
||||
let mut address_array: types::UINT_PTR;
|
||||
let mut name_array: types::UINT_PTR;
|
||||
let mut name_ordinals: types::UINT_PTR;
|
||||
let nt_headers: *const IMAGE_NT_HEADERS64;
|
||||
let data_directory: *const IMAGE_DATA_DIRECTORY;
|
||||
let export_directory: *const IMAGE_EXPORT_DIRECTORY;
|
||||
let dos_headers: *const IMAGE_DOS_HEADER;
|
||||
unsafe {
|
||||
dos_headers = module_handle as *const IMAGE_DOS_HEADER;
|
||||
nt_headers = (module_handle as u64 + (*dos_headers).e_lfanew as u64) as *const IMAGE_NT_HEADERS64;
|
||||
data_directory = (&(*nt_headers).OptionalHeader.DataDirectory[0]) as *const IMAGE_DATA_DIRECTORY;
|
||||
export_directory = (module_handle as u64 + (*data_directory).VirtualAddress as u64) as *const IMAGE_EXPORT_DIRECTORY;
|
||||
address_array = (module_handle as u64 + (*export_directory).AddressOfFunctions as u64) as types::UINT_PTR;
|
||||
name_array = (module_handle as u64 + (*export_directory).AddressOfNames as u64) as types::UINT_PTR;
|
||||
name_ordinals = (module_handle as u64 + (*export_directory).AddressOfNameOrdinals as u64) as types::UINT_PTR;
|
||||
loop {
|
||||
let name_offest: u32 = *(name_array as *const u32);
|
||||
let current_function_name = std::ffi::CStr::from_ptr(
|
||||
(module_handle as u64 + name_offest as u64) as *const i8
|
||||
).to_str().unwrap();
|
||||
|
||||
if current_function_name == function_name {
|
||||
address_array = address_array + (*(name_ordinals as *const u16) as u64 * (std::mem::size_of::<types::DWORD>() as u64));
|
||||
let fun_addr: FARPROC = std::mem::transmute(module_handle as u64 + *(address_array as *const u32) as u64);
|
||||
return fun_addr;
|
||||
}
|
||||
name_array = name_array + std::mem::size_of::<types::DWORD>() as u64;
|
||||
name_ordinals = name_ordinals + std::mem::size_of::<u16>() as u64;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe{
|
||||
println!("[+] Getting base address of kernel32.dll");
|
||||
let kernel32_base_address: HINSTANCE = get_module_base_addr("kernel32.dll");
|
||||
|
||||
println!("[+] Dynamically resolving LoadLibraryA");
|
||||
let dn_load_library_a: types::LoadLibraryA = std::mem::transmute(get_proc_addr(kernel32_base_address, "LoadLibraryA"));
|
||||
|
||||
println!("[+] Load user32.dll");
|
||||
dn_load_library_a("user32.dll\0".as_ptr());
|
||||
|
||||
println!("[+] Getting base address of user32.dll");
|
||||
let user32_base_address: HINSTANCE = get_module_base_addr("user32.dll");
|
||||
|
||||
println!("[+] Dynamically resolve MessageBoxA");
|
||||
let dn_message_box_a: types::MessageBoxA = std::mem::transmute(get_proc_addr(user32_base_address, "MessageBoxA"));
|
||||
|
||||
dn_message_box_a(0, "Resolved dynamically\0".as_ptr(), "MessageBoxA\0".as_ptr(), MB_OK);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
use windows_sys::Win32::Foundation::HWND;
|
||||
use windows_sys::core::PCSTR;
|
||||
use std::os::raw::c_ulong;
|
||||
|
||||
pub type DWORD = c_ulong;
|
||||
pub type __uint64 = u64;
|
||||
pub type DWORD64 = __uint64;
|
||||
pub type UINT_PTR = __uint64;
|
||||
pub type MessageBoxA = unsafe extern "system" fn (HWND, PCSTR, PCSTR, u32) -> i32;
|
||||
pub type LoadLibraryA = unsafe extern "system" fn (PCSTR) -> i32;
|
||||
@@ -43,6 +43,7 @@ My experiments in weaponizing [Rust](https://www.rust-lang.org/) for implant dev
|
||||
| [Kernel_Driver_Exploit](../master/Kernel_Driver_Exploit/src/main.rs) | Kernel Driver exploit for a simple buffer overflow |
|
||||
| [Named_Pipe_Client](../master/Named_Pipe_Client/src/main.rs) | Named Pipe Client |
|
||||
| [Named_Pipe_Server](../master/Named_Pipe_Server/src/main.rs) | Named Pipe Server |
|
||||
| [PEB_Walk](../master/PEB_Walk/src/main.rs) | Dynamically resolve and invoke Windows APIs |
|
||||
| [Process_Injection_CreateThread](../master/Process_Injection_CreateThread/src/main.rs) | Process Injection in running process with CreateThread |
|
||||
| [Process_Injection_CreateRemoteThread](../master/Process_Injection_CreateRemoteThread/src/main.rs) | Process Injection in remote process with CreateRemoteThread |
|
||||
| [Process_Injection_Self_EnumSystemGeoID](../master/Process_Injection_Self_EnumSystemGeoID/src/main.rs) | Self injector that uses the EnumSystemsGeoID API call to run shellcode. |
|
||||
@@ -52,17 +53,17 @@ My experiments in weaponizing [Rust](https://www.rust-lang.org/) for implant dev
|
||||
| [http-https-requests](../master/http-https-requests/src/main.rs) | HTTP/S requests by ignoring cert check for GET/POST |
|
||||
| [patch_etw](../master/patch_etw/src/main.rs) | Patch ETW |
|
||||
| [ppid_spoof](../master/ppid_spoof/src/main.rs) | Spoof parent process for created process |
|
||||
| [tcp_ssl_client](../master/tcp_ssl_client/src/main.rs) | TCP client with SSL that ignores cert check (Requires openssl and perl to be installed for compiling) |
|
||||
| [tcp_ssl_client](../master/tcp_ssl_client/src/main.rs) | TCP client with SSL that ignores cert check (Requires openssl and perl to be installed for compiling) |
|
||||
| [tcp_ssl_server](../master/tcp_ssl_server/src/main.rs) | TCP Server, with port parameter(Requires openssl and perl to be installed for compiling) |
|
||||
| [wmi_execute](../master/wmi_execute/src/main.rs) | Executes WMI query to obtain the AV/EDRs in the host |
|
||||
| [Windows.h+ Bindings](../master/bindings.rs) | This file contains structures of Windows.h plus complete customized LDR,PEB,etc.. that are undocumented officially by Microsoft, add at the top of your file include!("../bindings.rs"); |
|
||||
| [UUID_Shellcode_Execution](../master/UUID_Shellcode_Execution/src/main.rs) | Plants shellcode from UUID array into heap space and uses `EnumSystemLocalesA` Callback in order to execute the shellcode. |
|
||||
| [AMSI Bypass](../master/amsi_bypass/src/main.rs) | AMSI Bypass on Local Process |
|
||||
| [Injection_AES_Loader](../master/Injection_AES_Loader/src/main.rs) | NtTestAlert Injection with AES decryption |
|
||||
| [Litcrypt_String_Encryption](../master/Litcrypt_String_Encryption/src/main.rs) | Using the [Litcrypt](https://github.com/anvie/litcrypt.rs) crate to encrypt literal strings at rest and in memory to defeat static AV. |
|
||||
| [Api Hooking](../master/apihooking/src/main.rs) | Api Hooking using detour library |
|
||||
| [memfd_create](../master/memfd_create/src/main.rs) | Execute payloads from memory using the memfd_create technique (For Linux) |
|
||||
| [RC4_Encryption](../master/Injection_Rc4_Loader/src/main.rs) | RC4 Decrypted shellcode |
|
||||
| [Litcrypt_String_Encryption](../master/Litcrypt_String_Encryption/src/main.rs) | Using the [Litcrypt](https://github.com/anvie/litcrypt.rs) crate to encrypt literal strings at rest and in memory to defeat static AV. |
|
||||
| [Api Hooking](../master/apihooking/src/main.rs) | Api Hooking using detour library |
|
||||
| [memfd_create](../master/memfd_create/src/main.rs) | Execute payloads from memory using the memfd_create technique (For Linux) |
|
||||
| [RC4_Encryption](../master/Injection_Rc4_Loader/src/main.rs) | RC4 Decrypted shellcode |
|
||||
|
||||
## Compiling the examples in this repo
|
||||
|
||||
|
||||
Reference in New Issue
Block a user