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"
}
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 11ce17dcc..be8d7ad1c 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,61 @@ 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 interface
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 += 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)
+}
+
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());
+ 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: 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);
@@ -66,32 +83,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(&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
- .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()? {
@@ -110,6 +101,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"));
}
}