Skip to content

Commit

Permalink
Resolve expect crashes (#311)
Browse files Browse the repository at this point in the history
  • Loading branch information
hulto authored Oct 9, 2023
1 parent e572473 commit 9283c23
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 69 deletions.
22 changes: 18 additions & 4 deletions implants/lib/eldritch/src/file/compress_impl.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{path::Path, fs::{OpenOptions, File}, io::{Read, Write}};

use anyhow::Result;
use anyhow::{Result, Context};
use flate2::{Compression};
use tar::{Builder, HeaderMode};
use tempfile::NamedTempFile;
Expand All @@ -18,7 +18,14 @@ fn tar_dir(src: String, dst: String) -> Result<String> {
HeaderMode::Deterministic
);

let src_path_obj = src_path.clone().file_name().unwrap().to_str().unwrap();
let src_path_obj = src_path
.file_name()
.context(
format!("Failed to get path file_name {}", src_path.display())
)?
.to_str().context(
format!("Failed to convert osStr to str {}", src_path.display())
)?;

// Add all files from source dir with the name of the dir.
match tar_builder.append_dir_all(src_path_obj.clone(), src_path.clone() ) {
Expand Down Expand Up @@ -47,7 +54,13 @@ pub fn compress(src: String, dst: String) -> Result<()> {
let src_path = Path::new(&tmp_src);

let tmp_tar_file_src = NamedTempFile::new()?;
let tmp_tar_file_src_path = String::from(tmp_tar_file_src.path().to_str().unwrap());
let tmp_tar_file_src_path = String::from(
tmp_tar_file_src
.path()
.to_str()
.context(
format!("Faild to get path str: {}", src)
)?);

// If our source is a dir create a tarball and update the src file to the tar ball.
if src_path.clone().is_dir() {
Expand All @@ -60,7 +73,8 @@ pub fn compress(src: String, dst: String) -> Result<()> {
}

// Setup buffered reader writer.
let f_src = std::io::BufReader::new(std::fs::File::open(tmp_src.clone()).unwrap());
let f_src = std::io::BufReader::new(
std::fs::File::open(tmp_src.clone())?);
let mut f_dst = std::io::BufWriter::new(
OpenOptions::new()
.create(true)
Expand Down
6 changes: 2 additions & 4 deletions implants/lib/eldritch/src/file/download_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ async fn handle_download(uri: String, dst: String) -> Result<()> {
pub fn download(uri: String, dst: String) -> Result<()> {
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();
.build()?;

let response = runtime.block_on(
handle_download(uri, dst)
Expand Down Expand Up @@ -75,8 +74,7 @@ mod tests {
download(url, path.clone())?;

// Read the file
let contents = read_to_string(path.clone())
.expect("Something went wrong reading the file");
let contents = read_to_string(path.clone())?;

// check file written correctly
assert_eq!(contents, "test body");
Expand Down
14 changes: 7 additions & 7 deletions implants/lib/eldritch/src/file/list_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,25 +129,25 @@ fn create_dict_from_file(starlark_heap: &Heap, file: File) -> Result<Dict>{
let mut tmp_res = Dict::new(res);

let tmp_value1 = starlark_heap.alloc_str(&file.name);
tmp_res.insert_hashed(const_frozen_string!("file_name").to_value().get_hashed().unwrap(), tmp_value1.to_value());
tmp_res.insert_hashed(const_frozen_string!("file_name").to_value().get_hashed()?, tmp_value1.to_value());

let file_size = file.size as i32;
tmp_res.insert_hashed(const_frozen_string!("size").to_value().get_hashed().unwrap(), starlark_heap.alloc(file_size));
tmp_res.insert_hashed(const_frozen_string!("size").to_value().get_hashed()?, starlark_heap.alloc(file_size));

let tmp_value2 = starlark_heap.alloc_str(&file.owner);
tmp_res.insert_hashed(const_frozen_string!("owner").to_value().get_hashed().unwrap(), tmp_value2.to_value());
tmp_res.insert_hashed(const_frozen_string!("owner").to_value().get_hashed()?, tmp_value2.to_value());

let tmp_value3 = starlark_heap.alloc_str(&file.group);
tmp_res.insert_hashed(const_frozen_string!("group").to_value().get_hashed().unwrap(), tmp_value3.to_value());
tmp_res.insert_hashed(const_frozen_string!("group").to_value().get_hashed()?, tmp_value3.to_value());

let tmp_value4 = starlark_heap.alloc_str(&file.permissions);
tmp_res.insert_hashed(const_frozen_string!("permissions").to_value().get_hashed().unwrap(), tmp_value4.to_value());
tmp_res.insert_hashed(const_frozen_string!("permissions").to_value().get_hashed()?, tmp_value4.to_value());

let tmp_value5 = starlark_heap.alloc_str(&file.time_modified);
tmp_res.insert_hashed(const_frozen_string!("modified").to_value().get_hashed().unwrap(), tmp_value5.to_value());
tmp_res.insert_hashed(const_frozen_string!("modified").to_value().get_hashed()?, tmp_value5.to_value());

let tmp_value6 = starlark_heap.alloc_str(&file.file_type.to_string());
tmp_res.insert_hashed(const_frozen_string!("type").to_value().get_hashed().unwrap(), tmp_value6.to_value());
tmp_res.insert_hashed(const_frozen_string!("type").to_value().get_hashed()?, tmp_value6.to_value());

Ok(tmp_res)
}
Expand Down
4 changes: 2 additions & 2 deletions implants/lib/eldritch/src/file/replace_all_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use std::fs::{write,read_to_string};
use regex::{Regex,NoExpand};

pub fn replace_all(path: String, pattern: String, value: String) -> Result<()> {
let file_contents = read_to_string(path.clone()).unwrap();
let re = Regex::new(&pattern).unwrap();
let file_contents = read_to_string(path.clone())?;
let re = Regex::new(&pattern)?;
let result = re.replace_all(&file_contents, NoExpand(&value));
write(path, String::from(result))?;
Ok(())
Expand Down
8 changes: 6 additions & 2 deletions implants/lib/eldritch/src/pivot/arp_scan_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ fn start_listener(
interface: NetworkInterface,
data: Arc<Mutex<HashMap<Ipv4Addr, Option<ArpResponse>>>>,
) -> Result<()> {
use anyhow::Context;

if interface.ips.iter().filter(|ip| ip.is_ipv4()).count() == 0 {
return Err(anyhow!("Interface does not have a v4 address"));
}
let mac = interface.mac.ok_or(anyhow!("Could not obtain MAC of interface"))?;
let mac = interface.mac.context("Could not obtain MAC of interface")?;
let (mut tx, mut rx) = match channel(&interface, Default::default()) {
Ok(Ethernet(tx, rx)) => (tx, rx),
Ok(_) => return Err(anyhow!("Unhandled channel type")),
Expand Down Expand Up @@ -156,14 +158,16 @@ fn start_listener(
pub fn handle_arp_scan(
target_cidrs: Vec<String>,
) -> Result<HashMap<Ipv4Addr, Option<ArpResponse>>> {
use anyhow::Context;

let listener_out: Arc<Mutex<HashMap<Ipv4Addr, Option<ArpResponse>>>> =
Arc::new(Mutex::new(HashMap::new()));
let target_cidrs = target_cidrs
.iter()
.map(|cidr| {
let (addr, prefix) = cidr.split_at(
cidr.find('/')
.ok_or(anyhow::anyhow!("Failed to find / in Network {}", cidr))?,
.context(format!("Failed to find / in Network {}", cidr))?,
);
let addr = match Ipv4Addr::from_str(addr) {
Ok(addr) => addr,
Expand Down
7 changes: 3 additions & 4 deletions implants/lib/eldritch/src/pivot/ncat_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ async fn handle_ncat(address: String, port: i32, data: String, protocol: String)

// We need to take a buffer of bytes, turn it into a String but that string has null bytes.
// To remove the null bytes we're using trim_matches.
result_string = String::from(String::from_utf8((&response_buffer).to_vec()).unwrap().trim_matches(char::from(0)));
result_string = String::from(String::from_utf8((&response_buffer).to_vec())?.trim_matches(char::from(0)));
Ok(result_string)

} else if protocol == "udp" {
Expand All @@ -44,7 +44,7 @@ async fn handle_ncat(address: String, port: i32, data: String, protocol: String)

// We need to take a buffer of bytes, turn it into a String but that string has null bytes.
// To remove the null bytes we're using trim_matches.
result_string = String::from(String::from_utf8((&response_buffer).to_vec()).unwrap().trim_matches(char::from(0)));
result_string = String::from(String::from_utf8((&response_buffer).to_vec())?.trim_matches(char::from(0)));
Ok(result_string)

} else {
Expand All @@ -57,8 +57,7 @@ async fn handle_ncat(address: String, port: i32, data: String, protocol: String)
pub fn ncat(address: String, port: i32, data: String, protocol: String) -> Result<String> {
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();
.build()?;

let response = runtime.block_on(
handle_ncat(address, port, data, protocol)
Expand Down
10 changes: 4 additions & 6 deletions implants/lib/eldritch/src/pivot/ssh_exec_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ pub fn ssh_exec(starlark_heap: &Heap, target: String, port: i32, command: String

let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();
.build()?;

let key_password_ref = key_password.as_deref();
let local_port: u16 = port.try_into()?;
Expand All @@ -45,10 +44,10 @@ pub fn ssh_exec(starlark_heap: &Heap, target: String, port: i32, command: String
let res = SmallMap::new();
let mut dict_res = Dict::new(res);
let stdout_value = starlark_heap.alloc_str(&cmd_res.stdout);
dict_res.insert_hashed(const_frozen_string!("stdout").to_value().get_hashed().unwrap(), stdout_value.to_value());
dict_res.insert_hashed(const_frozen_string!("stdout").to_value().get_hashed()?, stdout_value.to_value());

let status_value = starlark_heap.alloc(cmd_res.status);
dict_res.insert_hashed(const_frozen_string!("status").to_value().get_hashed().unwrap(), status_value);
dict_res.insert_hashed(const_frozen_string!("status").to_value().get_hashed()?, status_value);

Ok(dict_res)
}
Expand Down Expand Up @@ -123,8 +122,7 @@ mod tests {
}
let tmp_res = Command::new(command_string)
.args(command_args)
.output()
.expect("failed to execute process");
.output()?;
session.data(channel, CryptoVec::from(tmp_res.stdout));
session.close(channel); // Only gonna send one command.
Ok((self, session))
Expand Down
22 changes: 11 additions & 11 deletions implants/lib/eldritch/src/process/list_impl.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use anyhow::{Result};
use anyhow::{Result, Context};
use starlark::{values::{dict::Dict, Heap, Value}, collections::SmallMap, const_frozen_string};
use sysinfo::{ProcessExt,System,SystemExt,PidExt};
use sysinfo::{UserExt};
Expand All @@ -19,7 +19,7 @@ pub fn list(starlark_heap: &Heap) -> Result<Vec<Dict>> {
for (pid, process) in sys.processes() {
let mut tmp_ppid = 0;
if process.parent() != None {
tmp_ppid = process.parent().unwrap().as_u32();
tmp_ppid = process.parent().context(format!("Failed to get parent process for {}", pid))?.as_u32();
}
let tmp_username = match process.user_id() {
Some(local_user_id) => match sys.get_user_by_id(local_user_id){
Expand All @@ -34,21 +34,21 @@ pub fn list(starlark_heap: &Heap) -> Result<Vec<Dict>> {
// Create Dict type.
let mut tmp_res = Dict::new(res);

tmp_res.insert_hashed(const_frozen_string!("pid").to_value().get_hashed().unwrap(), starlark_heap.alloc(match pid.as_u32().try_into() {
tmp_res.insert_hashed(const_frozen_string!("pid").to_value().get_hashed()?, starlark_heap.alloc(match pid.as_u32().try_into() {
Ok(local_int) => local_int,
Err(_) => -1,
}));
tmp_res.insert_hashed(const_frozen_string!("ppid").to_value().get_hashed().unwrap(), starlark_heap.alloc(match tmp_ppid.try_into() {
tmp_res.insert_hashed(const_frozen_string!("ppid").to_value().get_hashed()?, starlark_heap.alloc(match tmp_ppid.try_into() {
Ok(local_int) => local_int,
Err(_) => -1,
}));
tmp_res.insert_hashed(const_frozen_string!("status").to_value().get_hashed().unwrap(), starlark_heap.alloc_str(&process.status().to_string()).to_value());
tmp_res.insert_hashed(const_frozen_string!("username").to_value().get_hashed().unwrap(), starlark_heap.alloc_str(&tmp_username).to_value());
tmp_res.insert_hashed(const_frozen_string!("path").to_value().get_hashed().unwrap(), starlark_heap.alloc_str(&String::from(process.exe().to_str().unwrap())).to_value());
tmp_res.insert_hashed(const_frozen_string!("command").to_value().get_hashed().unwrap(), starlark_heap.alloc_str(&String::from(process.cmd().join(" "))).to_value());
tmp_res.insert_hashed(const_frozen_string!("cwd").to_value().get_hashed().unwrap(), starlark_heap.alloc_str(&String::from(process.cwd().to_str().unwrap())).to_value());
tmp_res.insert_hashed(const_frozen_string!("environ").to_value().get_hashed().unwrap(), starlark_heap.alloc_str(&String::from(process.environ().join(" "))).to_value());
tmp_res.insert_hashed(const_frozen_string!("name").to_value().get_hashed().unwrap(), starlark_heap.alloc_str(&String::from(process.name())).to_value());
tmp_res.insert_hashed(const_frozen_string!("status").to_value().get_hashed()?, starlark_heap.alloc_str(&process.status().to_string()).to_value());
tmp_res.insert_hashed(const_frozen_string!("username").to_value().get_hashed()?, starlark_heap.alloc_str(&tmp_username).to_value());
tmp_res.insert_hashed(const_frozen_string!("path").to_value().get_hashed()?, starlark_heap.alloc_str(&String::from(process.exe().to_str().context("Failed to cast process exe to str")?)).to_value());
tmp_res.insert_hashed(const_frozen_string!("command").to_value().get_hashed()?, starlark_heap.alloc_str(&String::from(process.cmd().join(" "))).to_value());
tmp_res.insert_hashed(const_frozen_string!("cwd").to_value().get_hashed()?, starlark_heap.alloc_str(&String::from(process.cwd().to_str().context("failde to cast cwd to str")?)).to_value());
tmp_res.insert_hashed(const_frozen_string!("environ").to_value().get_hashed()?, starlark_heap.alloc_str(&String::from(process.environ().join(" "))).to_value());
tmp_res.insert_hashed(const_frozen_string!("name").to_value().get_hashed()?, starlark_heap.alloc_str(&String::from(process.name())).to_value());

final_res.push(tmp_res);
}
Expand Down
22 changes: 10 additions & 12 deletions implants/lib/eldritch/src/sys/exec_impl.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use anyhow::Result;
use anyhow::{Result, Context};
use starlark::{values::{Heap, dict::Dict}, collections::SmallMap, const_frozen_string};
use std::process::Command;
#[cfg(any(target_os = "linux", target_os = "macos"))]
Expand All @@ -17,13 +17,13 @@ pub fn exec(starlark_heap: &Heap, path: String, args: Vec<String>, disown: Optio
let res = SmallMap::new();
let mut dict_res = Dict::new(res);
let stdout_value = starlark_heap.alloc_str(cmd_res.stdout.as_str());
dict_res.insert_hashed(const_frozen_string!("stdout").to_value().get_hashed().unwrap(), stdout_value.to_value());
dict_res.insert_hashed(const_frozen_string!("stdout").to_value().get_hashed()?, stdout_value.to_value());

let stderr_value = starlark_heap.alloc_str(cmd_res.stderr.as_str());
dict_res.insert_hashed(const_frozen_string!("stderr").to_value().get_hashed().unwrap(), stderr_value.to_value());
dict_res.insert_hashed(const_frozen_string!("stderr").to_value().get_hashed()?, stderr_value.to_value());

let status_value = starlark_heap.alloc(cmd_res.status);
dict_res.insert_hashed(const_frozen_string!("status").to_value().get_hashed().unwrap(), status_value);
dict_res.insert_hashed(const_frozen_string!("status").to_value().get_hashed()?, status_value);

Ok(dict_res)
}
Expand All @@ -37,24 +37,23 @@ fn handle_exec(path: String, args: Vec<String>, disown: Option<bool>) -> Result<
if !should_disown {
let res = Command::new(path)
.args(args)
.output()
.expect("failed to execute process");
.output()?;

let res = CommandOutput {
stdout: String::from_utf8(res.stdout)?,
stderr: String::from_utf8(res.stderr)?,
status: res.status.code().expect("Failed to retrive status code"),
status: res.status.code().context("Failed to retrieve status code")?,
};
return Ok(res);
}else{
#[cfg(target_os = "windows")]
return Err(anyhow::anyhow!("Windows is not supported for disowned processes."));

#[cfg(any(target_os = "linux", target_os = "macos"))]
match unsafe{fork().expect("Failed to fork process")} {
match unsafe{fork()?} {
ForkResult::Parent { child } => {
// Wait for intermediate process to exit.
waitpid(Some(child), None).unwrap();
waitpid(Some(child), None)?;
return Ok(CommandOutput{
stdout: "".to_string(),
stderr: "".to_string(),
Expand All @@ -63,7 +62,7 @@ fn handle_exec(path: String, args: Vec<String>, disown: Option<bool>) -> Result<
}

ForkResult::Child => {
match unsafe{fork().expect("Failed to fork process")} {
match unsafe{fork()?} {
ForkResult::Parent { child } => {
if child.as_raw() < 0 { return Err(anyhow::anyhow!("Pid was negative. ERR".to_string())) }
exit(0)
Expand All @@ -72,8 +71,7 @@ fn handle_exec(path: String, args: Vec<String>, disown: Option<bool>) -> Result<
ForkResult::Child => {
let _res = Command::new(path)
.args(args)
.output()
.expect("failed to execute process");
.output()?;
exit(0)
}
}
Expand Down
12 changes: 6 additions & 6 deletions implants/lib/eldritch/src/sys/get_ip_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,17 @@ fn create_dict_from_interface(starlark_heap: &Heap, interface: NetInterface) ->
let mut tmp_res = Dict::new(res);

let tmp_value1 = starlark_heap.alloc_str(&interface.name);
tmp_res.insert_hashed(const_frozen_string!("name").to_value().get_hashed().unwrap(), tmp_value1.to_value());
tmp_res.insert_hashed(const_frozen_string!("name").to_value().get_hashed()?, tmp_value1.to_value());

let mut tmp_value2_arr = Vec::<Value>::new();
for ip in interface.ips {
tmp_value2_arr.push(starlark_heap.alloc_str(&ip.to_string()).to_value());
}
let tmp_value2 = starlark_heap.alloc(tmp_value2_arr);
tmp_res.insert_hashed(const_frozen_string!("ips").to_value().get_hashed().unwrap(), tmp_value2);
tmp_res.insert_hashed(const_frozen_string!("ips").to_value().get_hashed()?, tmp_value2);

let tmp_value3 = starlark_heap.alloc_str(&interface.mac);
tmp_res.insert_hashed(const_frozen_string!("mac").to_value().get_hashed().unwrap(), tmp_value3.to_value());
tmp_res.insert_hashed(const_frozen_string!("mac").to_value().get_hashed()?, tmp_value3.to_value());


Ok(tmp_res)
Expand All @@ -72,17 +72,17 @@ fn create_dict_from_interface(starlark_heap: &Heap, interface: NetworkInterface)
let mut tmp_res = Dict::new(res);

let tmp_value1 = starlark_heap.alloc_str(&interface.name);
tmp_res.insert_hashed(const_frozen_string!("name").to_value().get_hashed().unwrap(), tmp_value1.to_value());
tmp_res.insert_hashed(const_frozen_string!("name").to_value().get_hashed()?, tmp_value1.to_value());

let mut tmp_value2_arr = Vec::<Value>::new();
for ip in interface.ips {
tmp_value2_arr.push(starlark_heap.alloc_str(&ip.to_string()).to_value());
}
let tmp_value2 = starlark_heap.alloc(tmp_value2_arr);
tmp_res.insert_hashed(const_frozen_string!("ips").to_value().get_hashed().unwrap(), tmp_value2);
tmp_res.insert_hashed(const_frozen_string!("ips").to_value().get_hashed()?, tmp_value2);

let tmp_value3 = starlark_heap.alloc_str(&interface.mac.map(|mac| mac.to_string()).unwrap_or(UNKNOWN.to_string()));
tmp_res.insert_hashed(const_frozen_string!("mac").to_value().get_hashed().unwrap(), tmp_value3.to_value());
tmp_res.insert_hashed(const_frozen_string!("mac").to_value().get_hashed()?, tmp_value3.to_value());


Ok(tmp_res)
Expand Down
Loading

0 comments on commit 9283c23

Please sign in to comment.