diff --git a/docs/_docs/admin-guide/tavern.md b/docs/_docs/admin-guide/tavern.md index 0706127ea..09139f60f 100644 --- a/docs/_docs/admin-guide/tavern.md +++ b/docs/_docs/admin-guide/tavern.md @@ -183,7 +183,7 @@ By default, Tavern will listen on `0.0.0.0:8000`. If you ever wish to change thi ### Metrics -By default, Tavern does not export metrics. You may use the below environment configuration variables to enable [Prometheus](https://prometheus.io/docs/introduction/overview/) metric collection. These metrics become available at the "/metrics" endpoint configured. These metrics are hosted on a separate HTTP server such that it can be restricted to localhost (default). This is because the endpoint is unauthenticated, and would leak sensitive information if it was accessible. +By default, Tavern does not export metrics. You may use the below environment configuration variables to enable [Prometheus](https://prometheus.io/docs/introduction/overview/) metric collection. These metrics become available at the "/metrics" endpoint configured. These metrics are hosted on a separate HTTP server so that it can be restricted to localhost (default). This is because the endpoint is unauthenticated, and would leak sensitive information if it was accessible. | Env Var | Description | Default | Required | | ------- | ----------- | ------- | -------- | @@ -193,7 +193,7 @@ By default, Tavern does not export metrics. You may use the below environment co ### Secrets By default, Tavern wants to use a GCP KMS for secrets management. The secrets engine is used to generate keypairs when communicating with agents. -If you're running locally make sure to set the secrets manager to a local file path using: +If you're running locally, make sure to set the secrets manager to a local file path using: ```bash SECRETS_FILE_PATH="/tmp/secrets" go run ./tavern/ @@ -479,7 +479,7 @@ query listtomes{ ### Upload - POST /cdn/upload - AUTHENTICATED -The upload API for the Tavern CDN use forms and the POST method. The parameters are `fileName` and `fileContent`. and the API will return an Ent ID for the file created. A curl example is shown below: +The upload API for the Tavern CDN uses forms and the POST method. The parameters are `fileName` and `fileContent`. and the API will return an Ent ID for the file created. A curl example is shown below: ```bash [$ /tmp] curl --cookie "auth-session=REDACTED" -F "fileName=test_file" -F "fileContent=@/path/to/file" https://example.com/cdn/upload @@ -488,7 +488,7 @@ The upload API for the Tavern CDN use forms and the POST method. The parameters ### Create a link - AUTHENTICATED -Once a file's been uploaded you won't be able to download it until you create a link for it through the graphql playground `/playground` +Once a file's been uploaded you won't be able to download it until you create a link for it through the GraphQL playground `/playground` ```graphql mutation tempLink { @@ -498,9 +498,9 @@ mutation tempLink { } ``` -This will create a link that allows the link to be active until Feburary 2nd 2026 at 21:33:18 UTC with 10 downloads. These two conditions are or'd so if either is allowed the download will work. +This will create a link that allows the link to be active until February 2nd 2026 at 21:33:18 UTC with 10 downloads. These two conditions are or'd so if either is allowed the download will work. -If no path is specified a random 6 character path will be generated. In the graphql query above we request the path back to ensure we know where to grab the file. +If no path is specified a random 6 character path will be generated. In the GraphQL query above we request the path back to ensure we know where to grab the file. ### Playground - GET /cdn/{path} - UNAUTHENTICATED diff --git a/docs/_docs/dev-guide/eldritch.md b/docs/_docs/dev-guide/eldritch.md index 2584034e2..5dd896ad5 100644 --- a/docs/_docs/dev-guide/eldritch.md +++ b/docs/_docs/dev-guide/eldritch.md @@ -39,7 +39,7 @@ Currently Eldritch has the following libraries your function can be bound to: * `crypto` Is used to encrypt/decrypt or hash data. * `file`: Is used for any on disk file processing. * `http`: Is used for any web requests needed to be made. -* `pivot`: Is used to migrate to identify, and migrate between systems. The pivot library is also responsible for facilitating connectivity within an environment. +* `pivot`: Is used to identify targets 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. * `random` - Used to generate cryptographically secure random values. * `regex`: Is used to perform regex operations on strings. @@ -50,7 +50,7 @@ Currently Eldritch has the following libraries your function can be bound to: If your function does not fall under a specific standard library reach out to the core developers about adding a new library or finding the right fit. Specify the input and output according to the [supported types.](/user-guide/eldritch#data-types) -If there are OS or edge case specific behaviors make sure to document them here. If there are limitations (e.g. if a function doesn't use file streaming) specify that it can't be used for large files. +If there are OS- or edge-case-specific behaviors make sure to document them here. If there are limitations (e.g. if a function doesn't use file streaming) specify that it can't be used for large files. Please add your function in alphabetical order this makes it easy to search by key words. @@ -97,7 +97,7 @@ impl FileLibrary for StdFileLibrary { function_impl::function(arg1, arg2, arg3) } - // If your function does not return a value, return a () and error as string. + // If your function does not return a value, return () and error as string. fn other_function(&self) -> Result<(), String> { other_function_impl::other_function() } @@ -163,7 +163,7 @@ mod tests { ### Testing Testing can be really daunting especially with complex system functions required by security professionals. -If you have any questions or hit any road blocks please reach out we'd love to help, also feel free to open a draft PR with what you have and mark it with the `help wanted` tag. +If you have any questions or hit any road blocks please reach out we'd love to help, also, feel free to open a draft PR with what you have and mark it with the `help wanted` tag. Testing isn't meant to be a barrier to contributing but instead a safety net so you know your code doesn't affect other systems. If it becomes a blocker please reach out so we can help 🙂 #### How to Test @@ -200,7 +200,7 @@ For all non supported OSes return an error with a message explaining which OSes return Err(anyhow::anyhow!("This OS isn't supported by the dll_inject function.\nOnly windows systems are supported")); ``` -### Using `Dict` +### Using `Dict`s --- The `Dict` type requires dynamic memory allocation in eldritch. In order to achieve this we can leverage the `BTreeMap` and push entries onto it. It's pretty simple to implement and starlark does some magic to streamline the process. To make the heap available to your function simply add it as an argument to your function. @@ -246,10 +246,10 @@ pub fn get_os() -> Result { } ``` -### Using `Async` +### Using Asynchronous Code --- -When writing performant code bound by many I/O operations, it can be greatly beneficial to use `async` methods and a scheduler, to enable CPU bound operations to be performed while awaiting I/O. This can dramatically reduce latency for many applications. Using `async` for your eldritch function implementations can be difficult however. It can be done, but it will add complexity to your code and must be implemented carefully. **YOU SHOULD NOT** implement `async` functions without having a complete understanding of how eldritch manages threads and it's own async runtime. Doing so will likely result in bugs, where you attempt to create a new `tokio::Runtime` within an existing runtime. By default, the `eldritch::Runtime` creates a new blocking thread (`tokio::task::spawn_blocking`), which helps prevent it from blocking other tome evaluation. Any results reported via the `report` library will already be concurrent with the thread that started the eldritch evaluation. **ALL ELDRITCH CODE IS SYNCHRONOUS** which means that creating an `async` function will not enable tome developers to run code in parallel, it just may allow the `tokio` scheduler to allocate CPU away from your code while it awaits an I/O operation. The primary performance benefits of using `async` is for the environment from which eldritch is being run, it is unlikely to impact the performance of any individual Tome (due to their synchronous nature). +When writing performant code bound by many I/O operations, it can be greatly beneficial to use `async` methods and a scheduler, to enable CPU bound operations to be performed while awaiting I/O. This can dramatically reduce latency for many applications. Using `async` for your eldritch function implementations can be difficult however. It can be done, but it will add complexity to your code and must be implemented carefully. **YOU SHOULD NOT** implement `async` functions without having a complete understanding of how eldritch manages threads and its own async runtime. Doing so will likely result in bugs, where you attempt to create a new `tokio::Runtime` within an existing runtime. By default, the `eldritch::Runtime` creates a new blocking thread (`tokio::task::spawn_blocking`), which helps prevent it from blocking other tome evaluation. Any results reported via the `report` library will already be concurrent with the thread that started the eldritch evaluation. **ALL ELDRITCH CODE IS SYNCHRONOUS** which means that creating an `async` function will not enable tome developers to run code in parallel, it just may allow the `tokio` scheduler to allocate CPU away from your code while it awaits an I/O operation. The primary performance benefits of using `async` is for the environment from which eldritch is being run, it is unlikely to impact the performance of any individual Tome (due to their synchronous nature). #### Async Testing diff --git a/docs/_docs/dev-guide/imix.md b/docs/_docs/dev-guide/imix.md index 2d1fe8b51..92e673251 100644 --- a/docs/_docs/dev-guide/imix.md +++ b/docs/_docs/dev-guide/imix.md @@ -12,7 +12,7 @@ Imix is the main bot for Realm. ## Agent protobuf -In order to communicate agent state and configuration during the claimTask request the agent sends a protobuf containing various configuration options. If any are updated agent side they're now synchronized with the server ensuring operators can track the state of their agents. +In order to communicate agent state and configuration during the claimTask request the agent sends a protobuf containing various configuration options. If any are updated agent-side they're now synchronized with the server ensuring operators can track the state of their agents. In order to keep these configuration options in sync realm uses protobuf and code generation to ensure agent and server agree. @@ -51,7 +51,7 @@ And add a new enum definition to `tavern/internal/c2/c2pb/enum___impl.rs` file. Here are a few things to keep in mind: +Any methods added to the Eldritch Standard Library should have tests colocated in the method's `_impl.rs` file. Here are a few things to keep in mind: * Tests should be cross platform * Rely on [NamedTempFile](https://docs.rs/tempfile/1.1.1/tempfile/struct.NamedTempFile.html) for temporary files @@ -39,7 +39,7 @@ All code changes to Tavern must be tested. Below are some standards for test wri * For GraphQL API Tests, please refer to our [YAML specification](/dev-guide/tavern#yaml-test-reference-graphql) * For gRPC API Tests, please refer to our [YAML specification](/dev-guide/tavern#yaml-test-reference-grpc) * Conventionally, please colocate your test code with the code it is testing and include it in the `_test` package -* We rely on the standard [testify](https://github.com/stretchr/testify) assert & require libraries for ensuring expected values (or errors) are returned +* We rely on the standard [testify](https://github.com/stretchr/testify) assert and require libraries for ensuring expected values (or errors) are returned * To enable a variety of inputs for a test case, we rely on closure-driven testing for Golang, you can read more about it [here](https://medium.com/@cep21/closure-driven-tests-an-alternative-style-to-table-driven-tests-in-go-628a41497e5e) * Reusable test code should go in a sub-package suffixed with test * For example, reusable test code for the `ent` package would be located in the `ent/enttest` package diff --git a/docs/_docs/dev-guide/tavern.md b/docs/_docs/dev-guide/tavern.md index 19603a3e4..9fb4250ed 100644 --- a/docs/_docs/dev-guide/tavern.md +++ b/docs/_docs/dev-guide/tavern.md @@ -193,7 +193,7 @@ If you can't use the default google oauth2 backend Realm has a flexible implemen For example to add Hashicorp Vault as an OIDC backend you'll need to: 1. Setup an OIDC provider in vault - -2. Get the relevant variables from the '.well-known/openid-configuration` endpoint: `authorization_endpoint`,`token_endpoint`,`userinfo_endpoint`,`scopes_supported` +2. Get the relevant variables from the `.well-known/openid-configuration` endpoint: `authorization_endpoint`,`token_endpoint`,`userinfo_endpoint`,`scopes_supported` 3. Open the `tavern/config.go` file and find where the `oauth2.Config` is initialized. 4. You'll need to change `Endpoint: google.Endpoint` to `oauth2.Endpoint{}` and fill in the `AuthURL` and `TokenURL` with `authorization_endpoint` and `token_endpoint` respectively. 5. Update the `cfg.userProfiles` link with the `userinfo_endpoint` @@ -233,4 +233,4 @@ func ConfigureOAuthFromEnv(redirectPath string) func(*Config) { ``` -_Keep in mind `/default/` in vault corresponds to the name of the OIDC provider and may be different in your environment. You may need to include / create additional scopes to get things like profile pictures and users names from vault into Tavern_ +_Keep in mind `/default/` in vault corresponds to the name of the OIDC provider and may be different in your environment. You may need to include / create additional scopes to get things like profile pictures and usernames from vault into Tavern_ diff --git a/docs/_docs/user-guide/eldritch.md b/docs/_docs/user-guide/eldritch.md index a43568fd2..847a16523 100644 --- a/docs/_docs/user-guide/eldritch.md +++ b/docs/_docs/user-guide/eldritch.md @@ -179,7 +179,7 @@ not persist across agent reboots. `agent.set_callback_uri(new_uri: str) -> None` -The agent.set_callback_uri method takes an string and changes the +The agent.set_callback_uri method takes a 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 @@ -491,7 +491,7 @@ The file.remove method deletes a file or directory (and it's contents) sp `file.replace(path: str, pattern: str, value: str) -> None` -The file.replace method finds the first string matching a regex pattern in the specified file and replaces them with the value. Please consult the [Rust Regex Docs](https://rust-lang-nursery.github.io/rust-cookbook/text/regex.html) for more information on pattern matching. +The file.replace method finds the first string matching a regex pattern in the specified file and replaces it with the value. Please consult the [Rust Regex Docs](https://rust-lang-nursery.github.io/rust-cookbook/text/regex.html) for more information on pattern matching. ### file.replace_all @@ -525,14 +525,14 @@ Unimplemented. `file.write(path: str, content: str) -> None` The file.write method writes to a given file path with the given content. -If a file already exists at this path, the method will overwite it. If a directory +If a file already exists at this path, the method will overwrite it. If a directory already exists at the path the method will error. ### file.find `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. +The file.find method finds all files matching the used parameters. Returns file paths for all matching items. - name: Checks if file name contains provided input - file_type: Checks for 'file' or 'dir' for files or directories, respectively. @@ -556,13 +556,13 @@ The http.download method downloads a file at the URI specified in `uri` t `http.get(uri: str, query_params: Option>, headers: Option>, allow_insecure: Option) -> str` -The http.get method sends an HTTP GET request to the URI specified in `uri` with the optional query parameters specified in `query_params` and headers specified in `headers`, then return the response body as a string. Note: in order to conform with HTTP2+ all header names are transmuted to lowercase. +The http.get method sends an HTTP GET request to the URI specified in `uri` with the optional query parameters specified in `query_params` and headers specified in `headers`, then returns the response body as a string. Note: in order to conform with HTTP2+ all header names are transmuted to lowercase. ### http.post `http.post(uri: str, body: Option, form: Option>, headers: Option>, allow_insecure: Option) -> str` -The http.post method sends an HTTP POST request to the URI specified in `uri` with the optional request body specified by `body`, form parameters specified in `form`, and headers specified in `headers`, then return the response body as a string. Note: in order to conform with HTTP2+ all header names are transmuted to lowercase. Other Note: if a `body` and a `form` are supplied the value of `body` will be used. +The http.post method sends an HTTP POST request to the URI specified in `uri` with the optional request body specified by `body`, form parameters specified in `form`, and headers specified in `headers`, then returns the response body as a string. Note: in order to conform with HTTP2+ all header names are transmuted to lowercase. Other Note: if a `body` and a `form` are supplied the value of `body` will be used. --- @@ -608,13 +608,13 @@ The pivot.bind_proxy method is being proposed to provide users another op `pivot.ncat(address: str, port: int, data: str, protocol: str ) -> str` -The pivot.ncat method allows a user to send arbitrary data over TCP/UDP to a host. If the server responds that response will be returned. +The pivot.ncat method allows a user to send arbitrary data over TCP/UDP to a host. If the server responds, that response will be returned. `protocol` must be `tcp`, or `udp` anything else will return an error `Protocol not supported please use: udp or tcp.`. ### pivot.port_forward -`pivot.port_forward(listen_address: str, listen_port: int, forward_address: str, forward_port: int, str: protocol ) -> None` +`pivot.port_forward(listen_address: str, listen_port: int, forward_address: str, forward_port: int, protocol: str) -> None` The pivot.port_forward method is being proposed to provide socat like functionality by forwarding traffic from a port on a local machine to a port on a different machine allowing traffic to be relayed. @@ -817,7 +817,7 @@ The random.int method returns randomly generated integer value between a ### random.string `random.string(length: uint, charset: Optional) -> str` -The random.string method returns a randomly generated string of the specified length. If `charset` is not provided defaults to [Alphanumeric](https://docs.rs/rand_distr/latest/rand_distr/struct.Alphanumeric.html). Warning, the string is stored entirely in memory so exceptionally large files (multiple megabytes) can lead to performance issues. +The random.string method returns a randomly generated string of the specified length. If `charset` is not provided defaults to [Alphanumeric](https://docs.rs/rand_distr/latest/rand_distr/struct.Alphanumeric.html). Warning: the string is stored entirely in memory so exceptionally large files (multiple megabytes) can lead to performance issues. --- @@ -897,7 +897,7 @@ The sys.dll_inject method will attempt to inject a dll on disk into a rem The sys.dll_reflect method will attempt to inject a dll from memory into a remote process by using the loader defined in `realm/bin/reflective_loader`. -The ints in dll_bytes will be cast down from int u32 ---> u8 in rust. +The ints in dll_bytes will be cast from u32 -> u8 in rust. If your dll_bytes array contains a value greater than u8::MAX it will cause the function to fail. If you're doing any decryption in starlark make sure to be careful of the u8::MAX bound for each byte. ### sys.exec @@ -905,8 +905,8 @@ If your dll_bytes array contains a value greater than u8::MAX it will cause the `sys.exec(path: str, args: List, disown: Optional, env_vars: Option>) -> Dict` The sys.exec method executes a program specified with `path` and passes the `args` list. -On *nix systems disown will run the process in the background disowned from the agent. This is done through double forking. -On Windows systems disown will run the process with detached stdin and stdout such that it won't block the tomes execution. +On *nix systems, disown will run the process in the background disowned from the agent. This is done through double forking. +On Windows systems, disown will run the process with detached stdin and stdout such that it won't block the tomes execution. The `env_vars` will be a map of environment variables to be added to the process of the execution. ```python @@ -1229,7 +1229,7 @@ For reference on all available format specifiers, see int` -The time.now method returns the time since UNIX EPOCH (Jan 01 1970). This uses the local system time. +The time.now method returns the time since Unix Epoch (Jan 01 1970). This uses the local system time. ### time.sleep diff --git a/docs/_docs/user-guide/getting-started.md b/docs/_docs/user-guide/getting-started.md index 89cb01e8a..f416fea82 100644 --- a/docs/_docs/user-guide/getting-started.md +++ b/docs/_docs/user-guide/getting-started.md @@ -87,7 +87,7 @@ These configurations can be controlled via Environment Variables at `imix` compi ### Quests -Now it's time to provide our [Beacon](/user-guide/terminology#beacon) its first [Task](/user-guide/terminology#task). We do this, by creating a [Quest](/user-guide/terminology#quest) in the UI, which represents a collection of [Tasks](/user-guide/terminology#task) across one or more [Hosts](/user-guide/terminology#host). Let's open our UI, which should be available at [http://127.0.0.1:8000/](http://127.0.0.1:8000/). +Now it's time to provide our [Beacon](/user-guide/terminology#beacon) its first [Task](/user-guide/terminology#task). We do this by creating a [Quest](/user-guide/terminology#quest) in the UI, which represents a collection of [Tasks](/user-guide/terminology#task) across one or more [Hosts](/user-guide/terminology#host). Let's open our UI, which should be available at [http://127.0.0.1:8000/](http://127.0.0.1:8000/). #### Beacon Selection @@ -101,11 +101,11 @@ This view will show all of our active [Beacons](/user-guide/terminology#beacon) #### Tome Selection -A [Tome](/user-guide/terminology#tome) is an [Eldritch](/user-guide/terminology#eldritch) package ready for execution by `imix`. By default, Tavern includes several core [Tomes](/user-guide/terminology#tome) to get you started. But don't worry, for more customization and advanced capabilities, it's easy to write your own [Tomes](/user-guide/terminology#tome)! These [Tomes](/user-guide/terminology#tome) are designed to be cross-platform, so it shouldn't matter which platform you're running on. You can view the underlying [Eldritch](/user-guide/terminology#eldritch) code a [Tome](/user-guide/terminology#tome) will run by clicking on the "details" dropdown. Feel free to take a minute to read through some of the core [Tomes](/user-guide/terminology#tome) available to you. +A [Tome](/user-guide/terminology#tome) is an [Eldritch](/user-guide/terminology#eldritch) package ready for execution by `imix`. By default, Tavern includes several core [Tomes](/user-guide/terminology#tome) to get you started. But don't worry, for more customization and advanced capabilities, it's easy to write your own [Tomes](/user-guide/terminology#tome)! These [Tomes](/user-guide/terminology#tome) are designed to be cross-platform, so it shouldn't matter which platform you're running on. You can view the underlying [Eldritch](/user-guide/terminology#eldritch) code that a [Tome](/user-guide/terminology#tome) will run by clicking on the "details" dropdown. Feel free to take a minute to read through some of the core [Tomes](/user-guide/terminology#tome) available to you. ![select-tome](/assets/img/user-guide/getting-started/select-tome.png) -Let's select "System Info", which will print the OS, hostname, and IP of the [Host](/user-guide/terminology#host) `imix` is running on as well as the user the [Beacon](/user-guide/terminology#beacon) is running as. You may filter [Tomes](/user-guide/terminology#tome) using the search bar above. Certain [Tomes](/user-guide/terminology#tome) will allow / require you to specify parameters to inform their execution, which will be displayed in this step (for relevant [Tomes](/user-guide/terminology#tome)). When you're ready, select "Continue". +Let's select "System Info", which will print the OS, hostname, and IP of the [Host](/user-guide/terminology#host) `imix` is running on as well as the user the [Beacon](/user-guide/terminology#beacon) is running as. You may filter [Tomes](/user-guide/terminology#tome) using the search bar above. Certain [Tomes](/user-guide/terminology#tome) will allow/require you to specify parameters to inform their execution, which will be displayed in this step (for relevant [Tomes](/user-guide/terminology#tome)). When you're ready, select "Continue". #### Confirm and Submit @@ -119,7 +119,7 @@ Now, in your `imix` logs you'll see that when it calls back, it will obtain the ![imix-tome-eval](/assets/img/user-guide/getting-started/imix-tome-eval.png) -Refresh the UI, you should see the output is now available! +Refresh the UI; you should see the output is now available! ![quest-result](/assets/img/user-guide/getting-started/quest-result.png) diff --git a/docs/_docs/user-guide/golem.md b/docs/_docs/user-guide/golem.md index 16d312458..58df68c8e 100644 --- a/docs/_docs/user-guide/golem.md +++ b/docs/_docs/user-guide/golem.md @@ -8,7 +8,7 @@ permalink: user-guide/golem ## What is Golem Golem is the standalone interpreter for Eldritch. -This program exists to help users get experience with the Eldritch language as well as a jumping-off point if you're interested in implementing your own program using the Eldritch language. Additionally, consult our [Tomes](/user-guide/tomes) documentation for information about packaging [Eldritch](/user-guide/terminology#eldritch) code for use with [Imix](/user-guide/imix) and Tavern. +This program exists to help users get experience with the Eldritch language as well as serve as a jumping-off point if you're interested in implementing your own program using the Eldritch language. Additionally, consult our [Tomes](/user-guide/tomes) documentation for information about packaging [Eldritch](/user-guide/terminology#eldritch) code for use with [Imix](/user-guide/imix) and Tavern. Golem can also be used operationally as an alternative to a system native shell. You can leverage the power of Eldritch with minimal exposure in the system process tree. @@ -82,9 +82,9 @@ paramdefs: # A list of inputs the tome requires. ### Building your Eldritch script -Eldritch while it looks like python is distinct and many features in python do not exist in Eldritch. +Eldritch, while it looks like python, is distinct and many features in python do not exist in Eldritch. -For an almost complete list of syntax checkout the Starlark (DSL which Eldritch is based on) docs +For an almost complete list of syntax check out the Starlark (DSL which Eldritch is based on) docs *Note: The docs may be incorrect in some places as we're using the starlark-rust implementation which doesn't always adhere to the starlark spec.* ```python @@ -105,7 +105,7 @@ def file_list(path): if f['type'] == "File": type_str = "File" # Formatting - By default Eldritch will print data as a JSON Dictionary which is easy for scripts to read but - # not great for humans to make your tome more usable make sure you print data in a readable way. + # not great for humans. To make your tome more usable, make sure you print data in a readable way. print(f['permissions']+"\t"+f['owner']+"\t"+f['group']+"\t"+str(f['size'])+"\t"+f['modified']+"\t"+type_str+"\t"+f['file_name']+"\n") else: print("Error: Invalid Path ("+path+")\n") @@ -140,7 +140,7 @@ Now that your tome is created let's test it locally. # ... ``` -_If you have input_params that you need to define for your tome manually set them for your test by adding a line like this:_ +_If you have `input_params` that you need to define for your tome, manually set them for your test by adding a line like this:_ ```python input_params['path'] = "/tmp/" @@ -149,11 +149,11 @@ file_list(input_params['path']) ## Golem embedded files -The Eldritch interpreter can embed files at compile time. To interact with these assets use the `assets` module in Eldritch. In addition to programmatic access the embedded files can be automatically executed at run time. If no other option is specified `-i` or a file path, golem will iterate over every instance of `main.eldritch` in the embedded assets launching each one as a separate thread. This behavior is desirable when trying to perform recon or deploy persistence quickly. +The Eldritch interpreter can embed files at compile time. To interact with these assets use the `assets` module in Eldritch. In addition to programmatic access the embedded files can be automatically executed at run time. If no other option is specified (`-i` or a file path), golem will iterate over every instance of `main.eldritch` in the embedded assets launching each one as a separate thread. This behavior is desirable when trying to perform recon or deploy persistence quickly. ## Golem as a stage 0 -Golem can also be used as a stage 0 to load imix or other c2 agents. When building as a stage 0 releases builds are recommended to optimize build size. +Golem can also be used as a stage 0 to load imix or other c2 agents. When building as a stage 0 release builds are recommended to optimize build size. ```bash # Build imix.exe diff --git a/docs/_docs/user-guide/imix.md b/docs/_docs/user-guide/imix.md index 03331cb28..4457bb82a 100644 --- a/docs/_docs/user-guide/imix.md +++ b/docs/_docs/user-guide/imix.md @@ -11,7 +11,7 @@ Imix is an offensive security implant designed for stealthy communication and ad ## Configuration -Imix has compile-time configuration, that may be specified using environment variables during `cargo build`. +Imix has compile-time configuration that may be specified using environment variables during `cargo build`. **We strongly recommend building agents inside the provided devcontainer `.devcontainer`** Building in the dev container limits variables that might cause issues and is the most tested way to compile. @@ -26,7 +26,7 @@ Building in the dev container limits variables that might cause issues and is th | 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. +Imix has run-time configuration that may be specified using environment variables during execution. | Env Var | Description | Default | Required | | ------- | ----------- | ------- | -------- | @@ -42,7 +42,7 @@ Building in the dev container limits variables that might cause issues and is th **Imix requires a server public key so it can encrypt messages to and from the server check the server status page `http://example.com/status` or logs for `level=INFO msg="public key: "`. This base64 encoded string should be passed to the agent using the environment variable `IMIX_SERVER_PUBKEY`** -**🚨 Note:** You must cd into the imix directory `implants/imix/` not `implants/` in order to build the agent. +**🚨 Note:** To generate the associated agent protos, use cargo build in the `implants` directory. You must cd into the imix directory `implants/imix/` not `implants/` in order to build the agent. ## Setting encryption key @@ -238,13 +238,13 @@ Imix communicates which host it's on to Tavern enabling operators to reliably pe Imix uses the `host_unique` library under `implants/lib/host_unique` to determine which host it's on. The `id` function will fail over all available options returning the first successful ID. If a method is unable to determine the uniqueness of a host it should return `None`. -We recommend that you use the `File` for the most reliability: +We recommend that you use the `File` selector for the most reliability: - Exists across reboots - Guaranteed to be unique per host (because the bot creates it) - Can be used by multiple instances of the beacon on the same host. -If you cannot use the `File` selector we highly recommend manually setting the `Env` selector with the environment variable `IMIX_HOST_ID`. This will override the `File` one avoiding writes to disk but must be managed by the operators. +If you cannot use the `File` selector, we highly recommend manually setting the `Env` selector with the environment variable `IMIX_HOST_ID`. This will override the `File` one avoiding writes to disk but must be managed by the operators. For Windows hosts, a `Registry` selector is available, but must be enabled before compilation. See the [imix dev guide](/dev-guide/imix#host-selector) on how to enable it. diff --git a/docs/_docs/user-guide/terminology.md b/docs/_docs/user-guide/terminology.md index 96271f877..674c7553a 100644 --- a/docs/_docs/user-guide/terminology.md +++ b/docs/_docs/user-guide/terminology.md @@ -8,7 +8,7 @@ permalink: user-guide/terminology ## Terminology -Throughout the documentation terms that are used to reference various components of Realm. Below we attempt to define some of those terms, to add some clarity to that other documentation. +Throughout the documentation, terms are used to reference various components of Realm. Below we attempt to define some of those terms, to add some clarity to that other documentation. ### Implant @@ -24,7 +24,7 @@ A Beacon is an instance of an Agent running as a process. Beacons are the underl ### Host -Hosts are in-scope systems for the current engagement. A host can have multiple beacons which can execute instructions provided by tomes. +Hosts are in-scope systems for the current engagement. A host can have multiple beacons, which can execute instructions provided by tomes. ### Quest diff --git a/docs/_docs/user-guide/tomes.md b/docs/_docs/user-guide/tomes.md index d74754ba0..5b26cb696 100644 --- a/docs/_docs/user-guide/tomes.md +++ b/docs/_docs/user-guide/tomes.md @@ -7,7 +7,7 @@ permalink: user-guide/tomes --- ## Tomes -A [Tome](/user-guide/terminology#tome) is an [Eldritch](/user-guide/terminology#eldritch) package that can be run on one or more [Beacons](/user-guide/terminology#beacon). By default, Tavern includes several core [Tomes](/user-guide/terminology#tome) to get you started. Please take a few minutes to read through the [options available to you](https://github.com/spellshift/realm/tree/main/tavern/tomes) now, and be sure to refer to them as reference when creating your own [Tomes](/user-guide/terminology#tome). If you're looking for information on how to run [Tomes](/user-guide/terminology#tome) and aren't quite ready to write your own, check out our [Getting Started guide](/user-guide/getting-started). Otherwise, adventure onwards, but with a word of warning. [Eldritch](/user-guide/terminology#eldritch) provides a useful abstraction for many offensive operations, however it is under heavy active development at this time and is subject to change. After the release of [Realm](https://github.com/spellshift/realm) version `1.0.0`, [Eldritch](/user-guide/terminology#eldritch) will follow [Semantic Versioning](https://semver.org/), to prevent [Tomes](/user-guide/terminology#tome) from failing when breaking changes are introduced. Until then however, the [Eldritch](/user-guide/terminology#eldritch) API may change. This rapid iteration will enable the language to more quickly reach maturity and ensure we provide the best possible design for operators, so thank you for your patience. +A [Tome](/user-guide/terminology#tome) is an [Eldritch](/user-guide/terminology#eldritch) package that can be run on one or more [Beacons](/user-guide/terminology#beacon). By default, Tavern includes several core [Tomes](/user-guide/terminology#tome) to get you started. Please take a few minutes to read through the [options available to you](https://github.com/spellshift/realm/tree/main/tavern/tomes) now, and be sure to refer to them as a reference when creating your own [Tomes](/user-guide/terminology#tome). If you're looking for information on how to run [Tomes](/user-guide/terminology#tome) and aren't quite ready to write your own, check out our [Getting Started guide](/user-guide/getting-started). Otherwise, adventure onwards, but with a word of warning. [Eldritch](/user-guide/terminology#eldritch) provides a useful abstraction for many offensive operations, however it is under heavy active development at this time and is subject to change. After the release of [Realm](https://github.com/spellshift/realm) version `1.0.0`, [Eldritch](/user-guide/terminology#eldritch) will follow [Semantic Versioning](https://semver.org/), to prevent [Tomes](/user-guide/terminology#tome) from failing when breaking changes are introduced. Until then, however, the [Eldritch](/user-guide/terminology#eldritch) API may change. This rapid iteration will enable the language to more quickly reach maturity and ensure we provide the best possible design for operators, so thank you for your patience. ## Anatomy of a Tome @@ -55,7 +55,7 @@ paramdefs: #### Referencing Tome Parameters -If you've defined a parameter for your [Tome](/user-guide/terminology#tome), there's a good chance you'll want to use it. Luckily, [Eldritch](/user-guide/terminology#eldritch) makes this easy for you by providing a global `input_params` dictionary, which is populated with the parameter values provided to your [Tome](/user-guide/terminology#tome). To access a parameter, simply use the `paramdef` name (defined in `metadata.yml`). For example: +If you've defined a parameter for your [Tome](/user-guide/terminology#tome), there's a good chance you'll want to use it. Luckily, [Eldritch](/user-guide/terminology#eldritch) makes this easy for you by providing a global `input_params` variable, which is populated with the parameter values provided to your [Tome](/user-guide/terminology#tome). To access a parameter, simply use the `paramdef` name (defined in `metadata.yml`). For example: ```python def print_path_param(): @@ -311,7 +311,7 @@ res = sys.shell(f"{shell_client} 127.0.0.1 id") ### Idempotence In many situations especially when deploying persistence you'll want to ensure that running a tome twice won't cause issues. -The best way to handle this is to when possible check the current state of the resource you're about to modify. +The best way to handle this is to, when possible, check the current state of the resource you're about to modify. This often takes the shape of running validation before and after taking an action. In the same way during manual operation you might check if a file is on disk and the right size you can automate that with eldritch. diff --git a/tavern/internal/cryptocodec/cryptocodec.go b/tavern/internal/cryptocodec/cryptocodec.go index a24e1dcff..d92af4782 100644 --- a/tavern/internal/cryptocodec/cryptocodec.go +++ b/tavern/internal/cryptocodec/cryptocodec.go @@ -83,7 +83,7 @@ func (s StreamDecryptCodec) Marshal(v any) (mem.BufferSlice, error) { proto := encoding.GetCodecV2("proto") res, err := proto.Marshal(v) if err != nil { - slog.Error("Unable to marshall data") + slog.Error("Unable to marshal data") return res, err } enc_res := s.Csvc.Encrypt(res.Materialize()) @@ -152,7 +152,6 @@ func (csvc *CryptoSvc) Decrypt(in_arr []byte) ([]byte, []byte) { client_pub_key_bytes := make([]byte, x25519.Size) copy(client_pub_key_bytes, in_arr[:x25519.Size]) - ids, err := goAllIds() if err != nil { slog.Error("failed to get goid") @@ -174,7 +173,7 @@ func (csvc *CryptoSvc) Decrypt(in_arr []byte) ([]byte, []byte) { // Read nonce & cipher text if len(in_arr) < aead.NonceSize() { - slog.Error(fmt.Sprintf("input bytes to short %d expected at least %d", len(in_arr), aead.NonceSize())) + slog.Error(fmt.Sprintf("input bytes too short %d expected at least %d", len(in_arr), aead.NonceSize())) return FAILURE_BYTES, FAILURE_BYTES } nonce, ciphertext := in_arr[:aead.NonceSize()], in_arr[aead.NonceSize():]