Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 28 additions & 31 deletions implants/lib/eldritch/src/sys/exec_impl.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -57,28 +55,35 @@ fn handle_exec(path: String, args: Vec<String>, disown: Option<bool>) -> 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)
}
},
}
}
}
}
Expand Down Expand Up @@ -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")
Expand All @@ -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));
Expand Down
15 changes: 15 additions & 0 deletions tavern/tomes/get_registry/main.eldritch
Original file line number Diff line number Diff line change
@@ -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()

14 changes: 14 additions & 0 deletions tavern/tomes/get_registry/metadata.yml
Original file line number Diff line number Diff line change
@@ -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.