From 8219f05e89991d733738fd31f3f44226252f73f6 Mon Sep 17 00:00:00 2001 From: Nicholas O'Brien Date: Fri, 16 Feb 2024 20:22:00 +0000 Subject: [PATCH 1/6] wrote out the skeleton for the regex lib. --- implants/lib/eldritch/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/implants/lib/eldritch/src/lib.rs b/implants/lib/eldritch/src/lib.rs index a1181246e..122e9380f 100644 --- a/implants/lib/eldritch/src/lib.rs +++ b/implants/lib/eldritch/src/lib.rs @@ -3,6 +3,7 @@ pub mod crypto; pub mod file; pub mod pivot; pub mod process; +pub mod regex; mod report; pub mod runtime; pub mod sys; From c70086c50bbb516fcbd00efbbfb83b36d9b73246 Mon Sep 17 00:00:00 2001 From: Nicholas O'Brien Date: Fri, 16 Feb 2024 20:22:04 +0000 Subject: [PATCH 2/6] wrote out the skeleton for the regex lib. --- .../lib/eldritch/src/regex/match_all_impl.rs | 5 ++ implants/lib/eldritch/src/regex/match_impl.rs | 5 ++ implants/lib/eldritch/src/regex/mod.rs | 46 +++++++++++++++++++ .../eldritch/src/regex/replace_all_impl.rs | 5 ++ .../lib/eldritch/src/regex/replace_impl.rs | 5 ++ 5 files changed, 66 insertions(+) create mode 100644 implants/lib/eldritch/src/regex/match_all_impl.rs create mode 100644 implants/lib/eldritch/src/regex/match_impl.rs create mode 100644 implants/lib/eldritch/src/regex/mod.rs create mode 100644 implants/lib/eldritch/src/regex/replace_all_impl.rs create mode 100644 implants/lib/eldritch/src/regex/replace_impl.rs diff --git a/implants/lib/eldritch/src/regex/match_all_impl.rs b/implants/lib/eldritch/src/regex/match_all_impl.rs new file mode 100644 index 000000000..d544ecd01 --- /dev/null +++ b/implants/lib/eldritch/src/regex/match_all_impl.rs @@ -0,0 +1,5 @@ +use anyhow::Result; + +pub fn match_all(_haystack: String, _pattern: String, _value: String) -> Result> { + unimplemented!("Method unimplemented") +} diff --git a/implants/lib/eldritch/src/regex/match_impl.rs b/implants/lib/eldritch/src/regex/match_impl.rs new file mode 100644 index 000000000..04953b9bb --- /dev/null +++ b/implants/lib/eldritch/src/regex/match_impl.rs @@ -0,0 +1,5 @@ +use anyhow::Result; + +pub fn r#match(_haystack: String, _pattern: String, _value: String) -> Result { + unimplemented!("Method unimplemented") +} diff --git a/implants/lib/eldritch/src/regex/mod.rs b/implants/lib/eldritch/src/regex/mod.rs new file mode 100644 index 000000000..1903e3c38 --- /dev/null +++ b/implants/lib/eldritch/src/regex/mod.rs @@ -0,0 +1,46 @@ +mod match_all_impl; +mod match_impl; +mod replace_all_impl; +mod replace_impl; + +use starlark::{ + environment::MethodsBuilder, + starlark_module, + values::{none::NoneType, starlark_value}, +}; + +/* + * Define our library for this module. + */ +crate::eldritch_lib!(RegexLibrary, "regex_library"); + +/* + * Below, we define starlark wrappers for all of our library methods. + * The functions must be defined here to be present on our library. + */ +#[starlark_module] +#[rustfmt::skip] +#[allow(clippy::needless_lifetimes, clippy::type_complexity, clippy::too_many_arguments)] +fn methods(builder: &mut MethodsBuilder) { + #[allow(unused_variables)] + fn replace_all<'v>(this: &RegexLibrary, haystack: String, pattern: String, text: String) -> anyhow::Result { + replace_all_impl::replace_all(haystack, pattern, text)?; + Ok(NoneType{}) + } + + #[allow(unused_variables)] + fn replace<'v>(this: &RegexLibrary, haystack: String, pattern: String, text: String) -> anyhow::Result { + replace_impl::replace(haystack, pattern, text)?; + Ok(NoneType{}) + } + + #[allow(unused_variables)] + fn match_all<'v>(this: &RegexLibrary, haystack: String, pattern: String, text: String) -> anyhow::Result> { + match_all_impl::match_all(haystack, pattern, text) + } + + #[allow(unused_variables)] + fn r#match<'v>(this: &RegexLibrary, haystack: String, pattern: String, text: String) -> anyhow::Result { + match_impl::r#match(haystack, pattern, text) + } +} diff --git a/implants/lib/eldritch/src/regex/replace_all_impl.rs b/implants/lib/eldritch/src/regex/replace_all_impl.rs new file mode 100644 index 000000000..924f98ddf --- /dev/null +++ b/implants/lib/eldritch/src/regex/replace_all_impl.rs @@ -0,0 +1,5 @@ +use anyhow::Result; + +pub fn replace_all(_haystack: String, _pattern: String, _value: String) -> Result<()> { + unimplemented!("Method unimplemented") +} diff --git a/implants/lib/eldritch/src/regex/replace_impl.rs b/implants/lib/eldritch/src/regex/replace_impl.rs new file mode 100644 index 000000000..3ed3bf922 --- /dev/null +++ b/implants/lib/eldritch/src/regex/replace_impl.rs @@ -0,0 +1,5 @@ +use anyhow::Result; + +pub fn replace(_haystack: String, _pattern: String, _value: String) -> Result<()> { + unimplemented!("Method unimplemented") +} From 67bc14171553af4aeee2d7309e5344b3bc75b516 Mon Sep 17 00:00:00 2001 From: Nicholas O'Brien Date: Fri, 16 Feb 2024 20:47:51 +0000 Subject: [PATCH 3/6] stubbed out docs and added the 'dir' test for the library --- docs/_docs/user-guide/eldritch.md | 39 +++++++++++++++++-- .../lib/eldritch/src/regex/match_all_impl.rs | 7 +++- implants/lib/eldritch/src/regex/match_impl.rs | 7 +++- implants/lib/eldritch/src/regex/mod.rs | 8 ++-- .../eldritch/src/regex/replace_all_impl.rs | 5 +++ .../lib/eldritch/src/regex/replace_impl.rs | 5 +++ implants/lib/eldritch/src/runtime/eval.rs | 2 + implants/lib/eldritch/src/runtime/mod.rs | 10 +++++ 8 files changed, 73 insertions(+), 10 deletions(-) diff --git a/docs/_docs/user-guide/eldritch.md b/docs/_docs/user-guide/eldritch.md index 48d0b7c29..4be89d782 100644 --- a/docs/_docs/user-guide/eldritch.md +++ b/docs/_docs/user-guide/eldritch.md @@ -357,7 +357,8 @@ The file.remove method deletes a file or directory (and it's contents) sp ### file.replace `file.replace(path: str, pattern: str, value: str) -> None` -The file.replace method is very cool, and will be even cooler when Nick documents it. + +Unimplemented. ### file.replace_all @@ -378,7 +379,7 @@ The `args` dictionary currently supports values of: `int`, `str`, and `List`. `file.timestomp(src: str, dst: str) -> None` -The file.timestomp method is very cool, and will be even cooler when Nick documents it. +Unimplemented. ### file.write @@ -389,7 +390,7 @@ If a file or directory already exists at this path, the method will fail. ### file.find -`file.find(path: str, name: Option, file_type: Option, permissions: Option, modified_time: Option, create_time: Option) -> Vec` +`file.find(path: str, name: Option, file_type: Option, permissions: Option, modified_time: Option, create_time: Option) -> List` The file.find method finds all files matching the used parameters. Returns file path for all matching items. @@ -613,7 +614,7 @@ The process.name method returns the name of the process from it's given p ### process.netstat -`process.netstat() -> Vec` +`process.netstat() -> List` The process.netstat method returns all information on TCP, UDP, and Unix sockets on the system. Will also return PID and Process Name of attached process, if one exists. @@ -636,6 +637,36 @@ The process.netstat method returns all information on TCP, UDP, and Unix --- +## Regex + +The regex library is designed to enable basic regex upon strings. + +### regex.match_all + +`regex.match_all(haystack: str, pattern: str) -> List` + +Unimplemented. + +### regex.match + +`regex.match(haystack: str, pattern: str) -> str` + +Unimplemented. + +### regex.replace_all + +`regex.replace_all(haystack: str, pattern: str, value: string) -> None` + +Unimplemented. + +### regex.replace + +`regex.replace(haystack: str, pattern: str, value: string) -> None` + +Unimplemented. + +--- + ## Report The report library is designed to enable reporting structured data to Tavern. It's API is still in the active development phase, so **future versions of Eldritch may break tomes that rely on this API**. diff --git a/implants/lib/eldritch/src/regex/match_all_impl.rs b/implants/lib/eldritch/src/regex/match_all_impl.rs index d544ecd01..a544c17ae 100644 --- a/implants/lib/eldritch/src/regex/match_all_impl.rs +++ b/implants/lib/eldritch/src/regex/match_all_impl.rs @@ -1,5 +1,10 @@ use anyhow::Result; -pub fn match_all(_haystack: String, _pattern: String, _value: String) -> Result> { +pub fn match_all(_haystack: String, _pattern: String) -> Result> { unimplemented!("Method unimplemented") } + +#[cfg(test)] +mod tests { + // TODO: Write Tests After Implementing the Function! +} diff --git a/implants/lib/eldritch/src/regex/match_impl.rs b/implants/lib/eldritch/src/regex/match_impl.rs index 04953b9bb..547107b8b 100644 --- a/implants/lib/eldritch/src/regex/match_impl.rs +++ b/implants/lib/eldritch/src/regex/match_impl.rs @@ -1,5 +1,10 @@ use anyhow::Result; -pub fn r#match(_haystack: String, _pattern: String, _value: String) -> Result { +pub fn r#match(_haystack: String, _pattern: String) -> Result { unimplemented!("Method unimplemented") } + +#[cfg(test)] +mod tests { + // TODO: Write Tests After Implementing the Function! +} diff --git a/implants/lib/eldritch/src/regex/mod.rs b/implants/lib/eldritch/src/regex/mod.rs index 1903e3c38..f9e622f06 100644 --- a/implants/lib/eldritch/src/regex/mod.rs +++ b/implants/lib/eldritch/src/regex/mod.rs @@ -35,12 +35,12 @@ fn methods(builder: &mut MethodsBuilder) { } #[allow(unused_variables)] - fn match_all<'v>(this: &RegexLibrary, haystack: String, pattern: String, text: String) -> anyhow::Result> { - match_all_impl::match_all(haystack, pattern, text) + fn match_all<'v>(this: &RegexLibrary, haystack: String, pattern: String) -> anyhow::Result> { + match_all_impl::match_all(haystack, pattern) } #[allow(unused_variables)] - fn r#match<'v>(this: &RegexLibrary, haystack: String, pattern: String, text: String) -> anyhow::Result { - match_impl::r#match(haystack, pattern, text) + fn r#match<'v>(this: &RegexLibrary, haystack: String, pattern: String) -> anyhow::Result { + match_impl::r#match(haystack, pattern) } } diff --git a/implants/lib/eldritch/src/regex/replace_all_impl.rs b/implants/lib/eldritch/src/regex/replace_all_impl.rs index 924f98ddf..4e724ee4e 100644 --- a/implants/lib/eldritch/src/regex/replace_all_impl.rs +++ b/implants/lib/eldritch/src/regex/replace_all_impl.rs @@ -3,3 +3,8 @@ use anyhow::Result; pub fn replace_all(_haystack: String, _pattern: String, _value: String) -> Result<()> { unimplemented!("Method unimplemented") } + +#[cfg(test)] +mod tests { + // TODO: Write Tests After Implementing the Function! +} diff --git a/implants/lib/eldritch/src/regex/replace_impl.rs b/implants/lib/eldritch/src/regex/replace_impl.rs index 3ed3bf922..e01ef66cf 100644 --- a/implants/lib/eldritch/src/regex/replace_impl.rs +++ b/implants/lib/eldritch/src/regex/replace_impl.rs @@ -3,3 +3,8 @@ use anyhow::Result; pub fn replace(_haystack: String, _pattern: String, _value: String) -> Result<()> { unimplemented!("Method unimplemented") } + +#[cfg(test)] +mod tests { + // TODO: Write Tests After Implementing the Function! +} diff --git a/implants/lib/eldritch/src/runtime/eval.rs b/implants/lib/eldritch/src/runtime/eval.rs index d53087522..f9cb4a750 100644 --- a/implants/lib/eldritch/src/runtime/eval.rs +++ b/implants/lib/eldritch/src/runtime/eval.rs @@ -5,6 +5,7 @@ use crate::{ file::FileLibrary, pivot::PivotLibrary, process::ProcessLibrary, + regex::RegexLibrary, report::ReportLibrary, runtime::{ messages::{reduce, Message, ReportErrorMessage, ReportFinishMessage, ReportStartMessage}, @@ -157,6 +158,7 @@ impl Runtime { const crypto: CryptoLibrary = CryptoLibrary; const time: TimeLibrary = TimeLibrary; const report: ReportLibrary = ReportLibrary; + const regex: RegexLibrary = RegexLibrary; } GlobalsBuilder::extended_by(&[ diff --git a/implants/lib/eldritch/src/runtime/mod.rs b/implants/lib/eldritch/src/runtime/mod.rs index d470c8949..221866dbd 100644 --- a/implants/lib/eldritch/src/runtime/mod.rs +++ b/implants/lib/eldritch/src/runtime/mod.rs @@ -161,6 +161,16 @@ mod tests { want_text: String::from(r#"["file", "process_list", "ssh_key", "user_password"]"#), want_error: None, }, + regex_bindings: TestCase { + id: 123, + tome: Tome { + eldritch: String::from("print(dir(regex))"), + parameters: HashMap::new(), + file_names: Vec::new(), + }, + want_text: String::from(r#"["match", "match_all", "replace", "replace_all"]"#), + want_error: None, + }, } #[tokio::test(flavor = "multi_thread", worker_threads = 128)] From 540421c77cb559932b0ed3d27ba99f5e6c9dc353 Mon Sep 17 00:00:00 2001 From: Nicholas O'Brien Date: Fri, 16 Feb 2024 20:52:37 +0000 Subject: [PATCH 4/6] forgot word in doc stub --- docs/_docs/user-guide/eldritch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_docs/user-guide/eldritch.md b/docs/_docs/user-guide/eldritch.md index 4be89d782..893cadf74 100644 --- a/docs/_docs/user-guide/eldritch.md +++ b/docs/_docs/user-guide/eldritch.md @@ -639,7 +639,7 @@ The process.netstat method returns all information on TCP, UDP, and Unix ## Regex -The regex library is designed to enable basic regex upon strings. +The regex library is designed to enable basic regex operations upon strings. ### regex.match_all From 11c13250c5e894d04b0180ccc2984d0b0ec78f18 Mon Sep 17 00:00:00 2001 From: Nicholas O'Brien Date: Fri, 16 Feb 2024 20:53:04 +0000 Subject: [PATCH 5/6] i suck at words --- docs/_docs/user-guide/eldritch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_docs/user-guide/eldritch.md b/docs/_docs/user-guide/eldritch.md index 893cadf74..11f685df7 100644 --- a/docs/_docs/user-guide/eldritch.md +++ b/docs/_docs/user-guide/eldritch.md @@ -639,7 +639,7 @@ The process.netstat method returns all information on TCP, UDP, and Unix ## Regex -The regex library is designed to enable basic regex operations upon strings. +The regex library is designed to enable basic regex operations on strings. ### regex.match_all From 3619ad219de41080af1e353b75994ca5ca6cd534 Mon Sep 17 00:00:00 2001 From: Nicholas O'Brien Date: Fri, 16 Feb 2024 21:07:14 +0000 Subject: [PATCH 6/6] one other doc update --- docs/_docs/dev-guide/eldritch.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/_docs/dev-guide/eldritch.md b/docs/_docs/dev-guide/eldritch.md index c29e4b4ad..c8921dce4 100644 --- a/docs/_docs/dev-guide/eldritch.md +++ b/docs/_docs/dev-guide/eldritch.md @@ -40,6 +40,7 @@ Currently Eldritch has eight libraries your function can be bound to: * `file`: Is used for any on disk file processing. * `pivot`: Is used to migrate to identify, and migrate between systems. The pivot library is also responsible for facilitating connectivity within an environment. * `process`: Is used to manage running processes on a system. +* `regex`: Is used to preform regex operations on strings. * `report`: Is used to report structured data to the caller of the eldritch environment (e.g. to the c2). * `sys`: Is used to check system specific configurations and start new processes. * `time`: Is used for obtaining and formatting time or adding delays into code.