From a932f78a3a569e06d0c75d5ebdf3546cd88d920e Mon Sep 17 00:00:00 2001 From: hulto <7121375+hulto@users.noreply.github.com> Date: Sat, 24 Feb 2024 03:31:30 +0000 Subject: [PATCH 1/7] Add cidr to IP --- implants/lib/eldritch/src/sys/get_ip_impl.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/implants/lib/eldritch/src/sys/get_ip_impl.rs b/implants/lib/eldritch/src/sys/get_ip_impl.rs index 11ce17dcc..97e2a8327 100644 --- a/implants/lib/eldritch/src/sys/get_ip_impl.rs +++ b/implants/lib/eldritch/src/sys/get_ip_impl.rs @@ -58,7 +58,11 @@ fn create_dict_from_interface(starlark_heap: &Heap, interface: NetInterface) -> let mut tmp_value2_arr = Vec::::new(); for ip in interface.ips { - tmp_value2_arr.push(starlark_heap.alloc_str(&ip.to_string()).to_value()); + tmp_value2_arr.push( + starlark_heap + .alloc_str(&ip.network().to_string()) + .to_value(), + ); } insert_dict_kv!(tmp_res, starlark_heap, "ips", tmp_value2_arr, Vec<_>); insert_dict_kv!(tmp_res, starlark_heap, "mac", &interface.mac, String); @@ -72,10 +76,13 @@ fn create_dict_from_interface(starlark_heap: &Heap, interface: NetworkInterface) let mut tmp_res = Dict::new(res); insert_dict_kv!(tmp_res, starlark_heap, "name", &interface.name, String); - let mut tmp_value2_arr = Vec::::new(); for ip in interface.ips { - tmp_value2_arr.push(starlark_heap.alloc_str(&ip.to_string()).to_value()); + tmp_value2_arr.push( + starlark_heap + .alloc_str(&format!("{}/{}", ip.ip(), ip.prefix())) + .to_value(), + ); } insert_dict_kv!(tmp_res, starlark_heap, "ips", tmp_value2_arr, Vec<_>); insert_dict_kv!( From e0f68ef4fa3ec33d89844239a16c1a9f1928eaf8 Mon Sep 17 00:00:00 2001 From: hulto <7121375+hulto@users.noreply.github.com> Date: Sat, 24 Feb 2024 04:13:43 +0000 Subject: [PATCH 2/7] Remove OS specific pnet dep. --- implants/lib/eldritch/Cargo.toml | 17 ++-- implants/lib/eldritch/src/sys/get_ip_impl.rs | 84 +++++++------------- 2 files changed, 36 insertions(+), 65 deletions(-) diff --git a/implants/lib/eldritch/Cargo.toml b/implants/lib/eldritch/Cargo.toml index 48819374c..f937f8956 100644 --- a/implants/lib/eldritch/Cargo.toml +++ b/implants/lib/eldritch/Cargo.toml @@ -35,10 +35,10 @@ notify = { workspace = true } object = { workspace = true } openssl = { workspace = true, features = ["vendored"] } pretty_env_logger = { workspace = true } -prost = { workspace = true} +prost = { workspace = true } prost-types = { workspace = true } regex = { workspace = true } -reqwest = { workspace = true , features = ["blocking", "stream"] } +reqwest = { workspace = true, features = ["blocking", "stream"] } russh = { workspace = true } russh-sftp = { workspace = true } russh-keys = { workspace = true } @@ -54,7 +54,7 @@ sysinfo = { workspace = true } tar = { workspace = true } tempfile = { workspace = true } tera = { workspace = true } -tokio = { workspace = true , features = ["macros", "rt-multi-thread"] } +tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } tokio-stream = { workspace = true } tonic = { workspace = true, features = ["tls-roots"] } windows-sys = { workspace = true, features = [ @@ -65,12 +65,13 @@ windows-sys = { workspace = true, features = [ "Win32_System_Diagnostics_Debug", "Win32_Security", "Win32_System_SystemInformation", - "Win32_System_SystemServices" -]} + "Win32_System_SystemServices", +] } whoami = { workspace = true } +network-interface = { workspace = true } + [target.'cfg(windows)'.dependencies] -network-interface = { workspace = true } winreg = { workspace = true } [target.'cfg(not(windows))'.dependencies] @@ -80,11 +81,11 @@ pnet = { workspace = true } netstat2 = { workspace = true } [dev-dependencies] -transport = { workspace = true, features = ["mock"]} +transport = { workspace = true, features = ["mock"] } httptest = { workspace = true } uuid = { workspace = true, features = ["v4"] } [build-dependencies] tonic-build = { workspace = true } anyhow = { workspace = true } -which = { workspace = true } +which = { workspace = true } diff --git a/implants/lib/eldritch/src/sys/get_ip_impl.rs b/implants/lib/eldritch/src/sys/get_ip_impl.rs index 97e2a8327..162d59267 100644 --- a/implants/lib/eldritch/src/sys/get_ip_impl.rs +++ b/implants/lib/eldritch/src/sys/get_ip_impl.rs @@ -1,8 +1,7 @@ -use anyhow::Result; -#[cfg(target_os = "windows")] +use std::net::IpAddr; + +use anyhow::{Context, Result}; use network_interface::{NetworkInterface, NetworkInterfaceConfig}; -#[cfg(not(target_os = "windows"))] -use pnet::datalink::{interfaces, NetworkInterface}; use super::super::insert_dict_kv; use starlark::{ @@ -13,43 +12,47 @@ use starlark::{ const UNKNOWN: &str = "UNKNOWN"; -#[derive(Debug)] -#[cfg(target_os = "windows")] struct NetInterface { name: String, - ips: Vec, //IPv6 and IPv4 Addresses on the itnerface + ips: Vec, //IPv6 and IPv4 Addresses on the itnerface mac: String, } -#[cfg(target_os = "windows")] +fn netmask_to_cidr(netmask: IpAddr) -> Result { + let binding = netmask.to_string(); + let mut cidr_prefix = 0; + for octet in binding.split(".") { + cidr_prefix += octet.parse::()?.count_ones(); + } + + Ok(cidr_prefix as u8) +} + fn handle_get_ip() -> Result> { let mut res = Vec::new(); for network_interface in NetworkInterface::show()? { - let mac_addr = match network_interface.mac_addr { + let mac = match network_interface.mac_addr { Some(local_mac) => local_mac, None => UNKNOWN.to_string(), }; - let mut ips: Vec = Vec::new(); + let name = network_interface.name; + + let mut ips: Vec = Vec::new(); for ip in network_interface.addr { - ips.push(ip.ip()); + let ip_addr = ip.ip(); + let netmask = ip + .netmask() + .context(format!("Unable to get interface {} netmask", &name))?; + let cidr = netmask_to_cidr(netmask)?; + ips.push(format!("{}/{}", ip.ip().to_string(), cidr)); } - res.push(NetInterface { - name: network_interface.name, - ips: ips, - mac: mac_addr, - }); + res.push(NetInterface { name, ips, mac }); } Ok(res) } -#[cfg(not(target_os = "windows"))] -fn handle_get_ip() -> Result> { - Ok(interfaces()) -} - -#[cfg(target_os = "windows")] fn create_dict_from_interface(starlark_heap: &Heap, interface: NetInterface) -> Result { let res: SmallMap = SmallMap::new(); let mut tmp_res = Dict::new(res); @@ -58,11 +61,7 @@ fn create_dict_from_interface(starlark_heap: &Heap, interface: NetInterface) -> let mut tmp_value2_arr = Vec::::new(); for ip in interface.ips { - tmp_value2_arr.push( - starlark_heap - .alloc_str(&ip.network().to_string()) - .to_value(), - ); + tmp_value2_arr.push(starlark_heap.alloc_str(&ip.to_string()).to_value()); } insert_dict_kv!(tmp_res, starlark_heap, "ips", tmp_value2_arr, Vec<_>); insert_dict_kv!(tmp_res, starlark_heap, "mac", &interface.mac, String); @@ -70,35 +69,6 @@ fn create_dict_from_interface(starlark_heap: &Heap, interface: NetInterface) -> Ok(tmp_res) } -#[cfg(not(target_os = "windows"))] -fn create_dict_from_interface(starlark_heap: &Heap, interface: NetworkInterface) -> Result { - let res: SmallMap = SmallMap::new(); - let mut tmp_res = Dict::new(res); - - insert_dict_kv!(tmp_res, starlark_heap, "name", &interface.name, String); - let mut tmp_value2_arr = Vec::::new(); - for ip in interface.ips { - tmp_value2_arr.push( - starlark_heap - .alloc_str(&format!("{}/{}", ip.ip(), ip.prefix())) - .to_value(), - ); - } - insert_dict_kv!(tmp_res, starlark_heap, "ips", tmp_value2_arr, Vec<_>); - insert_dict_kv!( - tmp_res, - starlark_heap, - "mac", - &interface - .mac - .map(|mac| mac.to_string()) - .unwrap_or(UNKNOWN.to_string()), - String - ); - - Ok(tmp_res) -} - pub fn get_ip(starlark_heap: &Heap) -> Result> { let mut final_res: Vec = Vec::new(); for network_interface in handle_get_ip()? { @@ -117,6 +87,6 @@ mod tests { let starlark_heap = Heap::new(); let res = get_ip(&starlark_heap).unwrap(); println!("{:?}", res); - assert!(format!("{:?}", res).contains("127.0.0.1")); + assert!(format!("{:?}", res).contains("127.0.0.1/8")); } } From ad8fd1d3f1e3623739fa9ffe6d52765cb4526dfe Mon Sep 17 00:00:00 2001 From: hulto <7121375+hulto@users.noreply.github.com> Date: Sat, 24 Feb 2024 04:15:06 +0000 Subject: [PATCH 3/7] Small fixes --- implants/lib/eldritch/src/sys/get_ip_impl.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/implants/lib/eldritch/src/sys/get_ip_impl.rs b/implants/lib/eldritch/src/sys/get_ip_impl.rs index 162d59267..d76dc0b97 100644 --- a/implants/lib/eldritch/src/sys/get_ip_impl.rs +++ b/implants/lib/eldritch/src/sys/get_ip_impl.rs @@ -21,7 +21,7 @@ struct NetInterface { fn netmask_to_cidr(netmask: IpAddr) -> Result { let binding = netmask.to_string(); let mut cidr_prefix = 0; - for octet in binding.split(".") { + for octet in binding.split('.') { cidr_prefix += octet.parse::()?.count_ones(); } @@ -40,12 +40,12 @@ fn handle_get_ip() -> Result> { let mut ips: Vec = Vec::new(); for ip in network_interface.addr { - let ip_addr = ip.ip(); let netmask = ip .netmask() .context(format!("Unable to get interface {} netmask", &name))?; let cidr = netmask_to_cidr(netmask)?; - ips.push(format!("{}/{}", ip.ip().to_string(), cidr)); + + ips.push(format!("{}/{}", ip.ip(), cidr)); } res.push(NetInterface { name, ips, mac }); From fc12f030aebd24b67341f3e9f08e846f96a8f295 Mon Sep 17 00:00:00 2001 From: hulto <7121375+hulto@users.noreply.github.com> Date: Sat, 24 Feb 2024 04:33:16 +0000 Subject: [PATCH 4/7] Debug test --- implants/lib/eldritch/src/sys/get_ip_impl.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/implants/lib/eldritch/src/sys/get_ip_impl.rs b/implants/lib/eldritch/src/sys/get_ip_impl.rs index d76dc0b97..a7e36a3b3 100644 --- a/implants/lib/eldritch/src/sys/get_ip_impl.rs +++ b/implants/lib/eldritch/src/sys/get_ip_impl.rs @@ -22,7 +22,14 @@ fn netmask_to_cidr(netmask: IpAddr) -> Result { let binding = netmask.to_string(); let mut cidr_prefix = 0; for octet in binding.split('.') { - cidr_prefix += octet.parse::()?.count_ones(); + cidr_prefix += match octet.parse::() { + Ok(x) => x.count_ones(), + Err(_err) => { + #[cfg(debug_assertions)] + eprintln!("Failed to convert {} in netmask {}", octet, netmask); + 0 + } + } } Ok(cidr_prefix as u8) From 95baced2ad400e2bd8966fae1c61c56b9982b94e Mon Sep 17 00:00:00 2001 From: hulto <7121375+hulto@users.noreply.github.com> Date: Fri, 23 Feb 2024 21:16:37 -0800 Subject: [PATCH 5/7] Windows tests pass? --- implants/lib/eldritch/src/sys/get_ip_impl.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/implants/lib/eldritch/src/sys/get_ip_impl.rs b/implants/lib/eldritch/src/sys/get_ip_impl.rs index a7e36a3b3..e3231f2e4 100644 --- a/implants/lib/eldritch/src/sys/get_ip_impl.rs +++ b/implants/lib/eldritch/src/sys/get_ip_impl.rs @@ -47,12 +47,19 @@ fn handle_get_ip() -> Result> { let mut ips: Vec = Vec::new(); for ip in network_interface.addr { - let netmask = ip - .netmask() - .context(format!("Unable to get interface {} netmask", &name))?; - let cidr = netmask_to_cidr(netmask)?; - - ips.push(format!("{}/{}", ip.ip(), cidr)); + if ip.ip().is_ipv4() { + match ip.netmask() { + Some(netmask) => { + let cidr = netmask_to_cidr(netmask)?; + ips.push(format!("{}/{}", ip.ip(), cidr)); + }, + None => { + ips.push(ip.ip().to_string()) + } + } + } else { + ips.push(ip.ip().to_string()) + } } res.push(NetInterface { name, ips, mac }); From 2e3476bd55f231b11d64d8db2247f6bcf1b18691 Mon Sep 17 00:00:00 2001 From: hulto <7121375+hulto@users.noreply.github.com> Date: Fri, 23 Feb 2024 21:18:25 -0800 Subject: [PATCH 6/7] Update docs. --- docs/_docs/user-guide/eldritch.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/_docs/user-guide/eldritch.md b/docs/_docs/user-guide/eldritch.md index dd4779872..575412af4 100644 --- a/docs/_docs/user-guide/eldritch.md +++ b/docs/_docs/user-guide/eldritch.md @@ -804,14 +804,14 @@ The sys.get_ip method returns a list of network interfaces as a dictionar { "name": "eth0", "ips": [ - "172.17.0.2" + "172.17.0.2/24" ], "mac": "02:42:ac:11:00:02" }, { "name": "lo", "ips": [ - "127.0.0.1" + "127.0.0.1/8" ], "mac": "00:00:00:00:00:00" } From 937b9629e0b8cfd47d336b1014ad5aa9deda260a Mon Sep 17 00:00:00 2001 From: hulto <7121375+hulto@users.noreply.github.com> Date: Sat, 24 Feb 2024 18:20:34 +0000 Subject: [PATCH 7/7] nit --- implants/lib/eldritch/src/sys/get_ip_impl.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/implants/lib/eldritch/src/sys/get_ip_impl.rs b/implants/lib/eldritch/src/sys/get_ip_impl.rs index e3231f2e4..be8d7ad1c 100644 --- a/implants/lib/eldritch/src/sys/get_ip_impl.rs +++ b/implants/lib/eldritch/src/sys/get_ip_impl.rs @@ -14,7 +14,7 @@ const UNKNOWN: &str = "UNKNOWN"; struct NetInterface { name: String, - ips: Vec, //IPv6 and IPv4 Addresses on the itnerface + ips: Vec, //IPv6 and IPv4 Addresses on the interface mac: String, } @@ -51,7 +51,7 @@ fn handle_get_ip() -> Result> { match ip.netmask() { Some(netmask) => { let cidr = netmask_to_cidr(netmask)?; - ips.push(format!("{}/{}", ip.ip(), cidr)); + ips.push(format!("{}/{}", ip.ip(), cidr)); }, None => { ips.push(ip.ip().to_string())