Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve expect crashes #311

Merged
merged 5 commits into from
Oct 9, 2023
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
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