From 62202dfdfe9894c356c960ebd520879411741e1c Mon Sep 17 00:00:00 2001 From: Nicholas O'Brien Date: Thu, 22 May 2025 01:08:28 +0000 Subject: [PATCH 1/2] done --- docs/_docs/user-guide/imix.md | 7 +++++++ implants/imix/src/agent.rs | 4 ++++ implants/imix/src/run.rs | 6 ++++++ implants/lib/pb/src/config.rs | 23 ++++++++++++++++++++++- 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/docs/_docs/user-guide/imix.md b/docs/_docs/user-guide/imix.md index fe9b31f8a..0c0738f62 100644 --- a/docs/_docs/user-guide/imix.md +++ b/docs/_docs/user-guide/imix.md @@ -20,6 +20,13 @@ Imix has compile-time configuration, that may be specified using environment var | IMIX_RETRY_INTERVAL | Duration to wait before restarting the agent loop if an error occurs, in seconds. | `5` | No | | IMIX_PROXY_URI | Overide system settings for proxy URI over HTTP(S) (must specify a scheme, e.g. `https://`) | No proxy | No | | IMIX_HOST_ID | Manually specify the host ID for this beacon. Supersedes the file on disk. | - | No | +| IMIX_RUN_ONCE | Imix will only do one callback and execution of queued tasks | false | No | + +Imix has run-time configuration, that may be specified using environment variables during execution. + +| Env Var | Description | Default | Required | +| ------- | ----------- | ------- | -------- | +| IMIX_BEACON_ID | The identifier to be used during callback (must be globally unique) | Random UUID | No | ## Logging diff --git a/implants/imix/src/agent.rs b/implants/imix/src/agent.rs index 76a9386d9..3e58647f5 100644 --- a/implants/imix/src/agent.rs +++ b/implants/imix/src/agent.rs @@ -116,6 +116,10 @@ impl Agent { } }; + if self.cfg.run_once { + return Ok(()); + } + let interval = match self.cfg.info.clone() { Some(b) => Ok(b.interval), None => Err(anyhow::anyhow!("beacon info is missing from agent")), diff --git a/implants/imix/src/run.rs b/implants/imix/src/run.rs index 6394dff7c..d14ea1d7c 100644 --- a/implants/imix/src/run.rs +++ b/implants/imix/src/run.rs @@ -24,6 +24,8 @@ pub async fn handle_main() { #[cfg(debug_assertions)] log::info!("agent config initialized {:#?}", cfg.clone()); + let run_once = cfg.run_once; + match run(cfg).await { Ok(_) => {} Err(_err) => { @@ -33,6 +35,10 @@ pub async fn handle_main() { tokio::time::sleep(Duration::from_secs(retry_interval)).await; } } + + if run_once { + break; + } } } diff --git a/implants/lib/pb/src/config.rs b/implants/lib/pb/src/config.rs index 98aafd535..9ea730a2d 100644 --- a/implants/lib/pb/src/config.rs +++ b/implants/lib/pb/src/config.rs @@ -11,6 +11,8 @@ pub struct Config { pub proxy_uri: ::core::option::Option<::prost::alloc::string::String>, #[prost(uint64, tag = "4")] pub retry_interval: u64, + #[prost(bool, tag = "5")] + pub run_once: bool, } macro_rules! callback_uri { @@ -64,6 +66,20 @@ macro_rules! retry_interval { */ pub const RETRY_INTERVAL: &str = retry_interval!(); +macro_rules! run_once { + () => { + match option_env!("IMIX_RUN_ONCE") { + Some(_) => true, + None => false, + } + }; +} + +/* Compile-time constant for the agent run once flag, derived from the IMIX_RUN_ONCE environment variable during compilation. + * Defaults to false if unset. + */ +pub const RUN_ONCE: bool = run_once!(); + /* * Config methods. */ @@ -82,8 +98,12 @@ impl Config { primary_ip: get_primary_ip(), }; + // Try to grab the beacon identitifier from env var, o/w use a random UUID + let beacon_id = + std::env::var("IMIX_BEACON_ID").unwrap_or_else(|_| String::from(Uuid::new_v4())); + let info = crate::c2::Beacon { - identifier: String::from(Uuid::new_v4()), + identifier: beacon_id, principal: whoami::username(), interval: match CALLBACK_INTERVAL.parse::() { Ok(i) => i, @@ -113,6 +133,7 @@ impl Config { 5 } }, + run_once: RUN_ONCE, } } pub fn refresh_primary_ip(&mut self) { From 5fa330a61432582a2ee591a4b53f3a7a525fa422 Mon Sep 17 00:00:00 2001 From: Nicholas O'Brien Date: Thu, 22 May 2025 16:46:38 +0000 Subject: [PATCH 2/2] nit resolved --- docs/_docs/user-guide/imix.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/_docs/user-guide/imix.md b/docs/_docs/user-guide/imix.md index 0c0738f62..81a64f363 100644 --- a/docs/_docs/user-guide/imix.md +++ b/docs/_docs/user-guide/imix.md @@ -20,13 +20,13 @@ Imix has compile-time configuration, that may be specified using environment var | IMIX_RETRY_INTERVAL | Duration to wait before restarting the agent loop if an error occurs, in seconds. | `5` | No | | IMIX_PROXY_URI | Overide system settings for proxy URI over HTTP(S) (must specify a scheme, e.g. `https://`) | No proxy | No | | IMIX_HOST_ID | Manually specify the host ID for this beacon. Supersedes the file on disk. | - | No | -| IMIX_RUN_ONCE | Imix will only do one callback and execution of queued tasks | false | No | +| IMIX_RUN_ONCE | Imix will only do one callback and execution of queued tasks (may want to pair with runtime environment variable `IMIX_BEACON_ID`) | false | No | Imix has run-time configuration, that may be specified using environment variables during execution. | Env Var | Description | Default | Required | | ------- | ----------- | ------- | -------- | -| IMIX_BEACON_ID | The identifier to be used during callback (must be globally unique) | Random UUID | No | +| IMIX_BEACON_ID | The identifier to be used during callback (must be globally unique) | Random UUIDv4 | No | ## Logging