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
8 changes: 4 additions & 4 deletions implants/lib/eldritch/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ fn build_bin_create_file_dll() {

println!("Starting cargo build lib");
let res = Command::new("cargo")
.args(&["build", "--lib"])
.args(["build", "--lib"])
.current_dir(test_dll_path)
.stderr(Stdio::piped())
.spawn()
Expand All @@ -35,7 +35,7 @@ fn build_bin_create_file_dll() {
let reader = BufReader::new(res);
reader
.lines()
.filter_map(|line| line.ok())
.map_while(Result::ok)
.for_each(|line| println!("cargo dll build: {}", line));

let relative_path_to_test_dll_file =
Expand Down Expand Up @@ -65,7 +65,7 @@ fn build_bin_reflective_loader() {

println!("Starting cargo build lib");
let res_build = Command::new("cargo")
.args(&[
.args([
"build",
"--release",
"-Z",
Expand All @@ -83,7 +83,7 @@ fn build_bin_reflective_loader() {
let reader = BufReader::new(res_build);
reader
.lines()
.filter_map(|line| line.ok())
.map_while(Result::ok)
.for_each(|line| println!("cargo dll build: {}", line));

let relative_path_to_test_dll_file = "..\\..\\..\\bin\\reflective_loader\\target\\x86_64-pc-windows-msvc\\release\\reflective_loader.dll";
Expand Down
7 changes: 5 additions & 2 deletions implants/lib/eldritch/src/file/list_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,20 @@ use std::os::macos::fs::MetadataExt;
use std::os::unix::fs::PermissionsExt;
#[cfg(target_os = "windows")]
use std::os::windows::fs::MetadataExt;

use std::path::{Path, PathBuf};
#[cfg(not(target_os = "windows"))]
use sysinfo::UserExt;

use sysinfo::{System, SystemExt, UserExt};
use sysinfo::{System, SystemExt};
const UNKNOWN: &str = "UNKNOWN";

// https://stackoverflow.com/questions/6161776/convert-windows-filetime-to-second-in-unix-linux
#[cfg(target_os = "windows")]
fn windows_tick_to_unix_tick(windows_tick: u64) -> i64 {
const WINDOWS_TICK: u64 = 10000000;
const SEC_TO_UNIX_EPOCH: u64 = 11644473600;
return (windows_tick / WINDOWS_TICK - SEC_TO_UNIX_EPOCH) as i64;
(windows_tick / WINDOWS_TICK - SEC_TO_UNIX_EPOCH) as i64
}

fn create_file_from_pathbuf(path_entry: PathBuf) -> Result<File> {
Expand Down
41 changes: 22 additions & 19 deletions implants/lib/eldritch/src/pivot/arp_scan_impl.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
use super::super::insert_dict_kv;
use anyhow::{anyhow, Result};
use ipnetwork::{IpNetwork, Ipv4Network};
#[cfg(not(target_os = "windows"))]
use pnet::{
datalink::{self, channel, Channel::Ethernet, NetworkInterface},
packet::{
arp::{ArpOperations, ArpPacket, MutableArpPacket},
ethernet::{EtherType, EthernetPacket, MutableEthernetPacket},
Packet,
use {
super::super::insert_dict_kv,
starlark::collections::SmallMap,
starlark::const_frozen_string,
std::collections::HashMap,
std::net::{IpAddr, Ipv4Addr},
std::str::FromStr,
std::sync::{Arc, Mutex},
std::time::{Duration, SystemTime},
ipnetwork::{IpNetwork, Ipv4Network},
pnet::{
datalink::{self, channel, Channel::Ethernet, NetworkInterface},
packet::{
arp::{ArpOperations, ArpPacket, MutableArpPacket},
ethernet::{EtherType, EthernetPacket, MutableEthernetPacket},
Packet,
},
util::MacAddr,
},
util::MacAddr,
};
use starlark::collections::SmallMap;
use starlark::const_frozen_string;

use anyhow::{anyhow,Result};
use starlark::values::{dict::Dict, Heap};
use std::collections::HashMap;
use std::net::{IpAddr, Ipv4Addr};
use std::str::FromStr;
use std::sync::{Arc, Mutex};
use std::time::{Duration, SystemTime};

#[cfg(not(target_os = "windows"))]
#[derive(Debug, Clone, PartialEq)]
Expand Down Expand Up @@ -265,8 +268,8 @@ pub fn arp_scan(starlark_heap: &Heap, target_cidrs: Vec<String>) -> Result<Vec<D
}

#[cfg(target_os = "windows")]
pub fn arp_scan(starlark_heap: &Heap, target_cidrs: Vec<String>) -> Result<Vec<Dict>> {
Err(anyhow::anyhow!("ARP Scanning is not available on Windows."))
pub fn arp_scan(_starlark_heap: &Heap, _target_cidrs: Vec<String>) -> Result<Vec<Dict>> {
Err(anyhow!("ARP Scanning is not available on Windows."))
}

#[cfg(not(target_os = "windows"))]
Expand Down
15 changes: 6 additions & 9 deletions implants/lib/eldritch/src/sys/dll_inject_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub fn dll_inject(dll_path: String, pid: u32) -> Result<NoneType> {
// Allocate memory in the remote process that we'll copy the DLL path string to.
let target_process_allocated_memory_handle = VirtualAllocEx(
target_process_memory_handle,
0 as *const c_void,
std::ptr::null::<c_void>(),
dll_path_null_terminated.len() + 1,
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE,
Expand All @@ -51,13 +51,13 @@ pub fn dll_inject(dll_path: String, pid: u32) -> Result<NoneType> {
target_process_allocated_memory_handle,
dll_path_null_terminated.as_bytes().as_ptr() as *const c_void,
dll_path_null_terminated.len(),
0 as *mut usize,
std::ptr::null_mut::<usize>(),
);

// Kickoff our DLL in the remote process
let _remote_thread_return_val = CreateRemoteThread(
target_process_memory_handle,
0 as *const SECURITY_ATTRIBUTES,
std::ptr::null::<SECURITY_ATTRIBUTES>(),
0,
Some(
// Translate our existing function return to the one LoadLibraryA wants.
Expand All @@ -68,7 +68,7 @@ pub fn dll_inject(dll_path: String, pid: u32) -> Result<NoneType> {
),
target_process_allocated_memory_handle,
0,
0 as *mut u32,
std::ptr::null_mut::<u32>(),
);

CloseHandle(target_process_memory_handle);
Expand Down Expand Up @@ -124,11 +124,8 @@ mod tests {
// kill the target process notepad
let mut sys = System::new();
sys.refresh_processes();
match sys.process(Pid::from_u32(target_pid)) {
Some(res) => {
res.kill_with(Signal::Kill);
}
None => {}
if let Some(res) = sys.process(Pid::from_u32(target_pid)) {
res.kill_with(Signal::Kill);
}

Ok(())
Expand Down
40 changes: 16 additions & 24 deletions implants/lib/eldritch/src/sys/dll_reflect_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ fn virtual_alloc_ex(
) -> anyhow::Result<*mut c_void> {
let buffer_handle: *mut c_void =
unsafe { VirtualAllocEx(hprocess, lpaddress, dwsize, flallocationtype, flprotect) };
if buffer_handle == null_mut() {
if buffer_handle.is_null() {
let error_code = unsafe { GetLastError() };
if error_code != 0 {
return Err(anyhow::anyhow!(
Expand Down Expand Up @@ -253,6 +253,7 @@ fn get_export_address_by_name(
Err(anyhow::anyhow!("Function {} not found", export_name))
}

#[allow(dead_code)] // `function_offset` is never read in our code but does get passed to our remote process.
#[cfg(target_os = "windows")]
struct UserData {
function_offset: u64,
Expand Down Expand Up @@ -282,7 +283,7 @@ fn handle_dll_reflect(
let remote_buffer = virtual_alloc_ex(
process_handle,
null_mut(),
image_size as usize,
image_size,
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE,
)?;
Expand All @@ -291,7 +292,7 @@ fn handle_dll_reflect(
process_handle,
remote_buffer as _,
reflective_loader_dll.as_ptr() as _,
image_size as usize,
image_size,
)?;

// Allocate and write user data to the remote process
Expand All @@ -316,7 +317,7 @@ fn handle_dll_reflect(
let remote_buffer_target_dll: *mut std::ffi::c_void = virtual_alloc_ex(
process_handle,
null_mut(),
user_data_ptr_size + target_dll_bytes.len() as usize,
user_data_ptr_size + target_dll_bytes.len(),
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE,
)?;
Expand All @@ -337,7 +338,7 @@ fn handle_dll_reflect(
process_handle,
payload_ptr_in_remote_buffer as _,
target_dll_bytes.as_slice().as_ptr() as _,
target_dll_bytes.len() as usize,
target_dll_bytes.len(),
)?;

// Find the loader entrypoint and hand off execution
Expand Down Expand Up @@ -485,7 +486,7 @@ mod tests {
let target_pid = expected_process.unwrap().id();

// Run our code.
let _res = handle_dll_reflect(test_dll_bytes.to_vec(), target_pid, "demo_init")?;
handle_dll_reflect(test_dll_bytes.to_vec(), target_pid, "demo_init")?;

let delay = time::Duration::from_secs(DLL_EXEC_WAIT_TIME);
thread::sleep(delay);
Expand All @@ -500,11 +501,8 @@ mod tests {
// kill the target process notepad
let mut sys = System::new();
sys.refresh_processes();
match sys.process(Pid::from_u32(target_pid)) {
Some(res) => {
res.kill_with(Signal::Kill);
}
None => {}
if let Some(res) = sys.process(Pid::from_u32(target_pid)) {
res.kill_with(Signal::Kill);
}
Ok(())
}
Expand All @@ -524,24 +522,21 @@ mod tests {
.spawn();
let target_pid = expected_process.unwrap().id() as i32;

let test_eldritch_script = format!(
r#"
let test_eldritch_script = r#"
func_dll_reflect(input_params['dll_bytes'], input_params['target_pid'], "demo_init")
"#
);
"#.to_string();

let ast: AstModule;
match AstModule::parse(
let ast = match AstModule::parse(
"test.eldritch",
test_eldritch_script.to_owned(),
&Dialect {
enable_f_strings: true,
..Dialect::Extended
},
) {
Ok(res) => ast = res,
Ok(res) => res,
Err(err) => return Err(err.into_anyhow()),
}
};

#[starlark_module]
fn func_dll_reflect(builder: &mut GlobalsBuilder) {
Expand Down Expand Up @@ -599,11 +594,8 @@ func_dll_reflect(input_params['dll_bytes'], input_params['target_pid'], "demo_in
// kill the target process notepad
let mut sys = System::new();
sys.refresh_processes();
match sys.process(Pid::from_u32(target_pid as u32)) {
Some(res) => {
res.kill_with(Signal::Kill);
}
None => {}
if let Some(res) = sys.process(Pid::from_u32(target_pid as u32)) {
res.kill_with(Signal::Kill);
}
Ok(())
}
Expand Down
2 changes: 1 addition & 1 deletion implants/lib/eldritch/src/sys/get_ip_impl.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::net::IpAddr;

use anyhow::{Context, Result};
use anyhow::Result;
use network_interface::{NetworkInterface, NetworkInterfaceConfig};

use super::super::insert_dict_kv;
Expand Down
6 changes: 3 additions & 3 deletions implants/lib/eldritch/src/sys/get_reg_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,21 +70,21 @@ mod tests {
//Write something into temp regkey...
let hkcu = RegKey::predef(HKEY_CURRENT_USER);
let (nkey, _ndisp) =
hkcu.create_subkey(format!("SOFTWARE\\{}", id.to_string()).to_string())?;
hkcu.create_subkey(format!("SOFTWARE\\{}", id))?;
nkey.set_value("FOO", &"BAR")?;

let ares = get_reg(
&binding,
"HKEY_CURRENT_USER".to_string(),
format!("SOFTWARE\\{}", id.to_string()).to_string(),
format!("SOFTWARE\\{}", id),
);
let val2: Value<'_> = match ares?.get(const_frozen_string!("FOO").to_value()) {
Ok(v) => Ok(v),
Err(err) => Err(err.into_anyhow()),
}?
.unwrap();
//delete temp regkey
hkcu.delete_subkey(format!("SOFTWARE\\{}", id.to_string()).to_string())?;
hkcu.delete_subkey(format!("SOFTWARE\\{}", id))?;

assert_eq!(val2.unpack_str().unwrap(), "BAR");

Expand Down
Loading