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
5 changes: 5 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
FROM mcr.microsoft.com/devcontainers/base:trixie

ARG ZIG_VERSION=0.16.0-dev.1326+2e6f7d36b

COPY library-scripts/*.sh library-scripts/*.env /tmp/library-scripts/

Expand All @@ -20,3 +21,7 @@ RUN apt-get update && apt-get install -y gnupg && echo "deb [arch=$(dpkg --print
tee /etc/apt/sources.list.d/hashicorp.list && wget -O- https://apt.releases.hashicorp.com/gpg | \
gpg --dearmor | tee /usr/share/keyrings/hashicorp-archive-keyring.gpg > /dev/null && \
apt update && apt-get install -y terraform

RUN wget "https://ziglang.org/builds/zig-$(uname -m)-linux-$ZIG_VERSION.tar.xz" -O /tmp/zig.tar.xz && \
mkdir /usr/local/bin/zig && tar -xvf "/tmp/zig.tar.xz" --strip-components=1 -C /usr/local/bin/zig && \
echo "export PATH=$PATH:/usr/local/bin/zig/" >> /etc/bash.bashrc
14 changes: 11 additions & 3 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"ghcr.io/devcontainers/features/rust:1": {
"version": "1.87",
"profile": "minimal",
"targets": "aarch64-unknown-linux-gnu,x86_64-unknown-linux-musl,x86_64-pc-windows-gnu"
"targets": "aarch64-unknown-linux-gnu,x86_64-unknown-linux-musl,x86_64-pc-windows-gnu,aarch64-apple-darwin,x86_64-apple-darwin"
},
"ghcr.io/devcontainers/features/node:1": {
"version": "lts"
Expand Down Expand Up @@ -53,9 +53,17 @@
"graphql.vscode-graphql",
"GraphQL.vscode-graphql-syntax",
"HashiCorp.terraform",
"rust-lang.rust-analyzer",
"rust-lang.rust-analyzer"
]
}
},
"remoteUser": "vscode"
"remoteUser": "vscode",
// Setup MacOS cross compilation first need to copy MacOS SDK:
// Rancher doesn't allow you to mount outside /tmp/ or /Users/ so we need to copy the SDK somewhere.
// sudo cp -r $(readlink -f $(xcrun --sdk macosx --show-sdk-path)) ~/MacOSX.sdk
// Uncomment the mount bellow to enable cross compilation on apple hardware.
// "mounts": [
// "source=${localEnv:HOME}${localEnv:USERPROFILE}/MacOSX.sdk,target=/MacOSX.sdk,readonly,type=bind"
// ],
"postAttachCommand": "cargo install cargo-zigbuild"
}
30 changes: 16 additions & 14 deletions docs/_docs/user-guide/eldritch.md
Original file line number Diff line number Diff line change
Expand Up @@ -903,20 +903,22 @@ The <b>sys.get_ip</b> method returns a list of network interfaces as a dictionar

```json
[
{
"name": "eth0",
"ips": [
"172.17.0.2/24"
],
"mac": "02:42:ac:11:00:02"
},
{
"name": "lo",
"ips": [
"127.0.0.1/8"
],
"mac": "00:00:00:00:00:00"
}
{
"name": "lo0",
"ip": "127.0.0.1"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the lack of cidr/mac a regression?

},
{
"name": "lo0",
"ip": "::1"
},
{
"name": "en0",
"ip": "fd5f:a709:7357:f34d:c8f:9bc8:ba40:db15"
},
{
"name": "en0",
"ip": "10.0.124.42"
}
]
```

Expand Down
52 changes: 41 additions & 11 deletions docs/_docs/user-guide/imix.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,38 +106,68 @@ rustup target add x86_64-unknown-linux-musl
sudo apt update
sudo apt install musl-tools
cd realm/implants/imix/
export IMIX_CALLBACK_URI="http://localhost"
# To get a servers pubkey:
# curl $IMIX_CALLBACK_URI/status | jq -r '.Pubkey'
IMIX_SERVER_PUBKEY="<SERVER_PUBKEY>" cargo build --release --bin imix --target=x86_64-unknown-linux-musl
export IMIX_SERVER_PUBKEY="<SERVER_PUBKEY>"

cargo build --release --bin imix --target=x86_64-unknown-linux-musl
```

### MacOS

**MacOS does not support static compilation**
<https://developer.apple.com/forums/thread/706419>

**Cross compilation is more complicated than we'll support**
Check out this blog a starting point for cross compiling.
<https://wapl.es/rust/2019/02/17/rust-cross-compile-linux-to-macos.html/>
[Apple's SDK and XCode TOS](https://www.apple.com/legal/sla/docs/xcode.pdf) require compilation be performed on apple hardware. Rust doesn't support cross compiling Linux -> MacOS out of the box due to dependencies on the above SDKs. In order to cross compile you first need to make the SDK available to the runtime. Below we've documented how you can compile MacOS binaries from the Linux devcontainer.

### Windows
#### Setup
Setup the MacOS SDK in a place that docker can access.
Rancher desktop doesn't allow you to mount folders besides ~/ and /tmp/
therefore we need to copy it into an accesible location.
Run the following on your MacOS host:

```bash
rustup target add x86_64-pc-windows-gnu
sudo cp -r $(readlink -f $(xcrun --sdk macosx --show-sdk-path)) ~/MacOSX.sdk
```

sudo apt update
sudo apt install gcc-mingw-w64
Modify .devcontainer/devcontainer.json by uncommenting the MacOSX.sdk mount. This will expose the newly copied SDK into the container allowing cargo to link against the MacOS SDK.
```json
"mounts": [
"source=${localEnv:HOME}${localEnv:USERPROFILE}/MacOSX.sdk,target=/MacOSX.sdk,readonly,type=bind"
],
```

#### Build
*Reopen realm in devcontainer*
```bash
cd realm/implants/imix/
# Tell the linker to use the MacOSX.sdk
export RUSTFLAGS="-Clink-arg=-isysroot -Clink-arg=/MacOSX.sdk -Clink-arg=-F/MacOSX.sdk/System/Library/Frameworks -Clink-arg=-L/MacOSX.sdk/usr/lib -Clink-arg=-lresolv"
export IMIX_CALLBACK_URI="http://localhost"
# To get a servers pubkey:
# curl $IMIX_CALLBACK_URI/status | jq -r '.Pubkey'
export IMIX_SERVER_PUBKEY="<SERVER_PUBKEY>"

cargo zigbuild --release --target aarch64-apple-darwin
```


### Windows

```bash
# Build imix
cd realm/implants/imix/

export IMIX_CALLBACK_URI="http://localhost"
# To get a servers pubkey:
# curl $IMIX_CALLBACK_URI/status | jq -r '.Pubkey'
export IMIX_SERVER_PUBKEY="<SERVER_PUBKEY>"

# Build imix.exe
IMIX_SERVER_PUBKEY="<SERVER_PUBKEY>" cargo build --release --target=x86_64-pc-windows-gnu
cargo build --release --target=x86_64-pc-windows-gnu
# Build imix.svc.exe
IMIX_SERVER_PUBKEY="<SERVER_PUBKEY>" cargo build --release --features win_service --target=x86_64-pc-windows-gnu
cargo build --release --features win_service --target=x86_64-pc-windows-gnu
# Build imix.dll
IMIX_SERVER_PUBKEY="<SERVER_PUBKEY>" cargo build --release --lib --target=x86_64-pc-windows-gnu
cargo build --release --lib --target=x86_64-pc-windows-gnu
```
2 changes: 1 addition & 1 deletion implants/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ lsp-types = "0.93.0"
log = "0.4.20"
md5 = "0.7.0"
mockall = "0.12.1"
network-interface = "1.0.1"
local-ip-address = "0.6.5"
nix = "0.26.1"
notify = "6.1.1"
object = "0.31.1"
Expand Down
2 changes: 1 addition & 1 deletion implants/lib/eldritch/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
tokio-stream = { workspace = true }
tokio-util = { workspace = true }
whoami = { workspace = true }
network-interface = { workspace = true }
local-ip-address = { workspace = true }
nix = { workspace = true }

# WINDOWS
Expand Down
83 changes: 11 additions & 72 deletions implants/lib/eldritch/src/sys/get_ip_impl.rs
Original file line number Diff line number Diff line change
@@ -1,90 +1,29 @@
use std::net::IpAddr;

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

use super::super::insert_dict_kv;
use anyhow::Result;
use local_ip_address::list_afinet_netifas;
use starlark::{
collections::SmallMap,
const_frozen_string,
values::{dict::Dict, Heap, Value},
};
use std::net::IpAddr;

const UNKNOWN: &str = "UNKNOWN";

struct NetInterface {
name: String,
ips: Vec<String>, //IPv6 and IPv4 Addresses on the interface
mac: String,
}

fn netmask_to_cidr(netmask: IpAddr) -> Result<u8> {
let binding = netmask.to_string();
let mut cidr_prefix = 0;
for octet in binding.split('.') {
cidr_prefix += match octet.parse::<u8>() {
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<Vec<NetInterface>> {
let mut res = Vec::new();
for network_interface in NetworkInterface::show()? {
let mac = match network_interface.mac_addr {
Some(local_mac) => local_mac,
None => UNKNOWN.to_string(),
};

let name = network_interface.name;

let mut ips: Vec<String> = Vec::new();
for ip in network_interface.addr {
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 });
}
Ok(res)
}

fn create_dict_from_interface(starlark_heap: &Heap, interface: NetInterface) -> Result<Dict> {
fn create_dict_from_interface(starlark_heap: &Heap, name: String, ip: IpAddr) -> Result<Dict> {
let res: SmallMap<Value, Value> = 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::<Value>::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, String);
insert_dict_kv!(tmp_res, starlark_heap, "name", name, String);
insert_dict_kv!(tmp_res, starlark_heap, "ip", ip.to_string(), String);

Ok(tmp_res)
}

pub fn get_ip(starlark_heap: &Heap) -> Result<Vec<Dict>> {
let network_interfaces = list_afinet_netifas()?;

let mut final_res: Vec<Dict> = Vec::new();
for network_interface in handle_get_ip()? {
let tmp_res = create_dict_from_interface(starlark_heap, network_interface)?;
for (name, ip) in network_interfaces.iter() {
let tmp_res = create_dict_from_interface(starlark_heap, name.clone(), *ip)?;
final_res.push(tmp_res);
}
Ok(final_res)
Expand All @@ -99,6 +38,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/8"));
assert!(format!("{:?}", res).contains("127.0.0.1"));
}
}
9 changes: 0 additions & 9 deletions tavern/tomes/arp_scan/main.eldritch

This file was deleted.

5 changes: 0 additions & 5 deletions tavern/tomes/arp_scan/metadata.yml

This file was deleted.

6 changes: 3 additions & 3 deletions tavern/tomes/get_net_info/main.eldritch
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ def print_table(rows: list[list]):

def ifconfig():
print("HOSTNAME " + sys.hostname())
rows = [["IFACE", "IP", "MAC"]]
rows = [["IFACE", "IP"]]
ip_res = sys.get_ip()
for interface in ip_res:
for ip in interface['ips']:
rows.append([interface['name'], ip, interface['mac']])
rows.append([interface['name'], interface['ip']])

print_table(rows)


Expand Down
Loading