From 1261d466c55dc4d634df1c824c0223c19dad3594 Mon Sep 17 00:00:00 2001 From: Nicholas O'Brien Date: Mon, 5 May 2025 00:40:59 +0000 Subject: [PATCH 1/2] done --- docs/_docs/user-guide/eldritch.md | 10 ++++ implants/lib/eldritch/src/agent/mod.rs | 7 +++ .../src/agent/set_callback_uri_impl.rs | 60 +++++++++++++++++++ .../lib/eldritch/src/runtime/messages/mod.rs | 6 ++ .../src/runtime/messages/set_callback_uri.rs | 21 +++++++ implants/lib/eldritch/src/runtime/mod.rs | 2 +- 6 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 implants/lib/eldritch/src/agent/set_callback_uri_impl.rs create mode 100644 implants/lib/eldritch/src/runtime/messages/set_callback_uri.rs diff --git a/docs/_docs/user-guide/eldritch.md b/docs/_docs/user-guide/eldritch.md index a07122644..b47364fb6 100644 --- a/docs/_docs/user-guide/eldritch.md +++ b/docs/_docs/user-guide/eldritch.md @@ -138,6 +138,16 @@ The agent.set_callback_interval method takes an unsigned int and changes running agent's callback interval to the passed value. This configuration change will not persist across agent reboots. +### agent.set_callback_uri + +`agent.set_callback_interval(new_uri: str) -> None` + +The agent.set_callback_interval method takes an string and changes the +running agent's callback uri to the passed value. This configuration change will +not persist across agent reboots. NOTE: please ensure the passed URI path is correct +for the underlying `Transport` being used, as a URI can take many forms and we make no +assumptions on `Transport` requirements no gut checks are applied to the passed string. + --- ## Assets diff --git a/implants/lib/eldritch/src/agent/mod.rs b/implants/lib/eldritch/src/agent/mod.rs index be07c49f1..589fc6a78 100644 --- a/implants/lib/eldritch/src/agent/mod.rs +++ b/implants/lib/eldritch/src/agent/mod.rs @@ -1,5 +1,6 @@ mod eval_impl; mod set_callback_interval_impl; +mod set_callback_uri_impl; use starlark::{ environment::MethodsBuilder, @@ -33,4 +34,10 @@ fn methods(builder: &mut MethodsBuilder) { set_callback_interval_impl::set_callback_interval(env, new_interval)?; Ok(NoneType{}) } + #[allow(unused_variables)] + fn set_callback_uri(this: &AgentLibrary, starlark_eval: &mut Evaluator<'v, '_>, new_uri: String) -> anyhow::Result { + let env = crate::runtime::Environment::from_extra(starlark_eval.extra)?; + set_callback_uri_impl::set_callback_interval(env, new_uri)?; + Ok(NoneType{}) + } } diff --git a/implants/lib/eldritch/src/agent/set_callback_uri_impl.rs b/implants/lib/eldritch/src/agent/set_callback_uri_impl.rs new file mode 100644 index 000000000..696948e56 --- /dev/null +++ b/implants/lib/eldritch/src/agent/set_callback_uri_impl.rs @@ -0,0 +1,60 @@ +use crate::runtime::{messages::SetCallbackUriMessage, messages::SyncMessage, Environment}; +use anyhow::Result; + +pub fn set_callback_interval(env: &Environment, new_uri: String) -> Result<()> { + env.send(SyncMessage::from(SetCallbackUriMessage { + id: env.id(), + new_uri, + }))?; + Ok(()) +} + +#[cfg(test)] +mod test { + use crate::runtime::{messages::SyncMessage, Message}; + use pb::eldritch::Tome; + use std::collections::HashMap; + + macro_rules! test_cases { + ($($name:ident: $value:expr,)*) => { + $( + #[tokio::test] + async fn $name() { + let tc: TestCase = $value; + + // Run Eldritch (until finished) + let mut runtime = crate::start(tc.id, tc.tome).await; + runtime.finish().await; + + // Read Messages + let mut found = false; + for msg in runtime.messages() { + if let Message::Sync(SyncMessage::SetCallbackUri(m)) = msg { + assert_eq!(tc.new_uri, m.new_uri); + found = true; + } + } + assert!(found); + } + )* + } + } + + struct TestCase { + pub id: i64, + pub tome: Tome, + pub new_uri: String, + } + + test_cases! { + change_interval: TestCase{ + id: 123, + tome: Tome{ + eldritch: String::from(r#"agent.set_callback_uri("https://127.0.0.1")"#), + parameters: HashMap::new(), + file_names: Vec::new(), + }, + new_uri: String::from("https://127.0.0.1"), + }, + } +} diff --git a/implants/lib/eldritch/src/runtime/messages/mod.rs b/implants/lib/eldritch/src/runtime/messages/mod.rs index dd7655c2a..924054125 100644 --- a/implants/lib/eldritch/src/runtime/messages/mod.rs +++ b/implants/lib/eldritch/src/runtime/messages/mod.rs @@ -10,6 +10,7 @@ mod report_start; mod report_text; mod reverse_shell_pty; mod set_callback_interval; +mod set_callback_uri; pub use fetch_asset::FetchAssetMessage; pub use pb::config::Config; @@ -23,6 +24,7 @@ pub use report_start::ReportStartMessage; pub use report_text::ReportTextMessage; pub use reverse_shell_pty::ReverseShellPTYMessage; pub use set_callback_interval::SetCallbackIntervalMessage; +pub use set_callback_uri::SetCallbackUriMessage; pub use transport::Transport; use anyhow::Result; @@ -121,6 +123,9 @@ impl AsyncDispatcher for AsyncMessage { pub enum SyncMessage { #[display(fmt = "SetCallbackInterval")] SetCallbackInterval(SetCallbackIntervalMessage), + + #[display(fmt = "SetCallbackInterval")] + SetCallbackUri(SetCallbackUriMessage), } impl SyncDispatcher for SyncMessage { @@ -130,6 +135,7 @@ impl SyncDispatcher for SyncMessage { match self { Self::SetCallbackInterval(msg) => msg.dispatch(transport, cfg), + Self::SetCallbackUri(msg) => msg.dispatch(transport, cfg), } } } diff --git a/implants/lib/eldritch/src/runtime/messages/set_callback_uri.rs b/implants/lib/eldritch/src/runtime/messages/set_callback_uri.rs new file mode 100644 index 000000000..47d5165fc --- /dev/null +++ b/implants/lib/eldritch/src/runtime/messages/set_callback_uri.rs @@ -0,0 +1,21 @@ +use super::{SyncDispatcher, Transport}; +use anyhow::Result; +use pb::config::Config; + +/* + * SetCallbackUriMessage sets the callback URI in the dispatched config. + */ +#[cfg_attr(debug_assertions, derive(Debug, PartialEq))] +#[derive(Clone)] +pub struct SetCallbackUriMessage { + pub(crate) id: i64, + pub(crate) new_uri: String, +} + +impl SyncDispatcher for SetCallbackUriMessage { + fn dispatch(self, _transport: &mut impl Transport, cfg: Config) -> Result { + let mut c = cfg.clone(); + c.callback_uri = self.new_uri; + Ok(c) + } +} diff --git a/implants/lib/eldritch/src/runtime/mod.rs b/implants/lib/eldritch/src/runtime/mod.rs index 5636e1298..c6d5f99ed 100644 --- a/implants/lib/eldritch/src/runtime/mod.rs +++ b/implants/lib/eldritch/src/runtime/mod.rs @@ -204,7 +204,7 @@ mod tests { parameters: HashMap::new(), file_names: Vec::new(), }, - want_text: format!("{}\n", r#"["eval", "set_callback_interval"]"#), + want_text: format!("{}\n", r#"["eval", "set_callback_interval", "set_callback_uri"]"#), want_error: None, }, } From 3bdfd84a722ef8fdb114deea208477e67d25211a Mon Sep 17 00:00:00 2001 From: Nicholas O'Brien Date: Mon, 5 May 2025 01:18:51 +0000 Subject: [PATCH 2/2] fix names --- docs/_docs/user-guide/eldritch.md | 4 ++-- implants/lib/eldritch/src/agent/mod.rs | 2 +- implants/lib/eldritch/src/agent/set_callback_uri_impl.rs | 2 +- implants/lib/eldritch/src/runtime/messages/mod.rs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/_docs/user-guide/eldritch.md b/docs/_docs/user-guide/eldritch.md index b47364fb6..0afae7653 100644 --- a/docs/_docs/user-guide/eldritch.md +++ b/docs/_docs/user-guide/eldritch.md @@ -140,9 +140,9 @@ not persist across agent reboots. ### agent.set_callback_uri -`agent.set_callback_interval(new_uri: str) -> None` +`agent.set_callback_uri(new_uri: str) -> None` -The agent.set_callback_interval method takes an string and changes the +The agent.set_callback_uri method takes an string and changes the running agent's callback uri to the passed value. This configuration change will not persist across agent reboots. NOTE: please ensure the passed URI path is correct for the underlying `Transport` being used, as a URI can take many forms and we make no diff --git a/implants/lib/eldritch/src/agent/mod.rs b/implants/lib/eldritch/src/agent/mod.rs index 589fc6a78..6c6d9552d 100644 --- a/implants/lib/eldritch/src/agent/mod.rs +++ b/implants/lib/eldritch/src/agent/mod.rs @@ -37,7 +37,7 @@ fn methods(builder: &mut MethodsBuilder) { #[allow(unused_variables)] fn set_callback_uri(this: &AgentLibrary, starlark_eval: &mut Evaluator<'v, '_>, new_uri: String) -> anyhow::Result { let env = crate::runtime::Environment::from_extra(starlark_eval.extra)?; - set_callback_uri_impl::set_callback_interval(env, new_uri)?; + set_callback_uri_impl::set_callback_uri(env, new_uri)?; Ok(NoneType{}) } } diff --git a/implants/lib/eldritch/src/agent/set_callback_uri_impl.rs b/implants/lib/eldritch/src/agent/set_callback_uri_impl.rs index 696948e56..b33dcd382 100644 --- a/implants/lib/eldritch/src/agent/set_callback_uri_impl.rs +++ b/implants/lib/eldritch/src/agent/set_callback_uri_impl.rs @@ -1,7 +1,7 @@ use crate::runtime::{messages::SetCallbackUriMessage, messages::SyncMessage, Environment}; use anyhow::Result; -pub fn set_callback_interval(env: &Environment, new_uri: String) -> Result<()> { +pub fn set_callback_uri(env: &Environment, new_uri: String) -> Result<()> { env.send(SyncMessage::from(SetCallbackUriMessage { id: env.id(), new_uri, diff --git a/implants/lib/eldritch/src/runtime/messages/mod.rs b/implants/lib/eldritch/src/runtime/messages/mod.rs index 924054125..8317d29e1 100644 --- a/implants/lib/eldritch/src/runtime/messages/mod.rs +++ b/implants/lib/eldritch/src/runtime/messages/mod.rs @@ -124,7 +124,7 @@ pub enum SyncMessage { #[display(fmt = "SetCallbackInterval")] SetCallbackInterval(SetCallbackIntervalMessage), - #[display(fmt = "SetCallbackInterval")] + #[display(fmt = "SetCallbackUri")] SetCallbackUri(SetCallbackUriMessage), }