You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/_docs/admin-guide/tavern.md
+68-1Lines changed: 68 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -104,7 +104,74 @@ Below are some deployment gotchas and notes that we try to address with Terrafor
104
104
105
105
## Redirectors
106
106
107
-
By default Tavern only supports GRPC connections directly to the server. To Enable additional protocols or additional IPs / Domain names in your callbacks utilize tavern redirectors which recieve traffic using a specific protocol like HTTP/1.1 and then forward it to an upstream tavern server over GRPC. See: `tavern redirector -help`
107
+
By default Tavern only supports gRPC connections directly to the server. To enable additional protocols or additional IPs/domain names in your callbacks, utilize Tavern redirectors which receive traffic using a specific protocol (like HTTP/1.1 or DNS) and then forward it to an upstream Tavern server over gRPC.
108
+
109
+
### Available Redirectors
110
+
111
+
Realm includes three built-in redirector implementations:
The DNS redirector tunnels C2 traffic through DNS queries and responses, providing a covert communication channel. It supports TXT, A, and AAAA record types.
143
+
144
+
```bash
145
+
# Start DNS redirector on UDP port 53 for domain c2.example.com
146
+
tavern redirector --transport dns --listen "0.0.0.0:53?domain=c2.example.com" localhost:8000
147
+
148
+
# Support multiple domains
149
+
tavern redirector --transport dns --listen "0.0.0.0:53?domain=c2.example.com&domain=backup.example.com" localhost:8000
150
+
```
151
+
152
+
**DNS Configuration Requirements:**
153
+
154
+
1. Configure your DNS server to delegate queries for your C2 domain to the redirector IP
155
+
2. Or run the redirector as your authoritative DNS server for the domain
156
+
3. Ensure UDP port 53 is accessible
157
+
158
+
**Server Behavior:**
159
+
160
+
-**Benign responses**: Non-C2 queries to A records return `0.0.0.0` instead of NXDOMAIN to avoid breaking recursive DNS lookups (e.g., when using Cloudflare as an intermediary)
161
+
-**Conversation tracking**: The server tracks up to 10,000 concurrent conversations
162
+
-**Timeout management**: Conversations timeout after 15 minutes of inactivity (reduced to 5 minutes when at capacity)
163
+
-**Maximum data size**: 50MB per request
164
+
165
+
See the [DNS Transport Configuration](/user-guide/imix#dns-transport-configuration) section in the Imix user guide for more details on agent-side configuration.
166
+
167
+
### gRPC Redirector
168
+
169
+
The gRPC redirector provides a passthrough for gRPC traffic, useful for deploying multiple Tavern endpoints or load balancing.
Copy file name to clipboardExpand all lines: docs/_docs/dev-guide/imix.md
+94-21Lines changed: 94 additions & 21 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -91,29 +91,45 @@ pub use mac_address::MacAddress;
91
91
92
92
## Develop a New Transport
93
93
94
-
We've tried to make Imix super extensible for transport development. In fact, all of the transport specific logic is complete abstracted from how Imix operates for callbacks/tome excution. For Imix all Transports live in the `realm/implants/lib/transport/src` directory.
94
+
We've tried to make Imix super extensible for transport development. In fact, all of the transport specific logic is completely abstracted from how Imix operates for callbacks/tome execution. For Imix all Transports live in the `realm/implants/lib/transport/src` directory.
95
95
96
-
If creating a new Transport create a new file in the directory and name it after the protocol you plan to use. For example, if writing a DNS Transport then call your file `dns.rs`. Then define your public struct where any connection state/clients will be. For example,
96
+
### Current Available Transports
97
+
98
+
Realm currently includes three transport implementations:
99
+
100
+
-**`grpc`** - Default gRPC transport (with optional DoH support via `grpc-doh` feature)
101
+
-**`http1`** - HTTP/1.1 transport
102
+
-**`dns`** - DNS-based covert channel transport
103
+
104
+
**Note:** Only one transport may be selected at compile time. The build will fail if multiple transport features are enabled simultaneously.
105
+
106
+
### Creating a New Transport
107
+
108
+
If creating a new Transport, create a new file in the `realm/implants/lib/transport/src` directory and name it after the protocol you plan to use. For example, if writing a new protocol called "Custom" then call your file `custom.rs`. Then define your public struct where any connection state/clients will be stored. For example,
97
109
98
110
```rust
99
111
#[derive(Debug, Clone)]
100
-
pubstructDNS {
101
-
dns_client:Option<hickory_dns::Client>
112
+
pubstructCustom {
113
+
// Your connection state here
114
+
// e.g., client: Option<CustomClient>
102
115
}
103
116
```
104
117
105
-
NOTE: Depending on the struct you build, you may need to derive certain features, see above we derive `Debug`and `Clone`.
118
+
**NOTE:** Your struct **must** derive `Clone` and `Send` as these are required by the Transport trait. Deriving `Debug`is also recommended for troubleshooting.
106
119
107
120
Next, we need to implement the Transport trait for our new struct. This will look like:
NOTE: Be Aware that currently `reverse_shell` uses tokio's sender/reciever while the rest of the methods rely on mpsc's. This is an artifact of some implementation details under the hood of Imix. Some day we may wish to move completely over to tokio's but currenlty it would just result in performance loss/less maintainable code.
171
187
172
-
After you implement all the functions/write in a decent error message for operators to understand why the function call failed then you need to import the Transport to the broader lib scope. To do this open up `realm/implants/lib/transport/src/lib.rs` and add in your new Transport like so:
188
+
After you implement all the functions and write descriptive error messages for operators to understand why function calls failed, you need to:
173
189
174
-
```rust
175
-
// more stuff above
190
+
#### 1. Add Compile-Time Exclusivity Checks
176
191
177
-
#[cfg(feature ="dns")]
178
-
moddns;
179
-
#[cfg(feature ="dns")]
180
-
pubusedns::DNSasActiveTransport;
192
+
In `realm/implants/lib/transport/src/lib.rs`, add compile-time checks to ensure your new transport cannot be compiled alongside others:
181
193
182
-
// more stuff below
194
+
```rust
195
+
// Add your transport to the mutual exclusivity checks
196
+
#[cfg(all(feature ="grpc", feature ="custom"))]
197
+
compile_error!("only one transport may be selected");
198
+
#[cfg(all(feature ="http1", feature ="custom"))]
199
+
compile_error!("only one transport may be selected");
200
+
#[cfg(all(feature ="dns", feature ="custom"))]
201
+
compile_error!("only one transport may be selected");
202
+
203
+
// ... existing checks above ...
204
+
205
+
// Add your transport module and export
206
+
#[cfg(feature ="custom")]
207
+
modcustom;
208
+
#[cfg(feature ="custom")]
209
+
pubusecustom::CustomasActiveTransport;
183
210
```
184
211
185
-
Also add your new feature to the Transport Cargo.toml at `realm/implants/lib/transport/Cargo.toml`.
212
+
**Important:** The transport is exported as `ActiveTransport`, not by its type name. This allows the imix agent code to remain transport-agnostic.
213
+
214
+
#### 2. Update Transport Library Dependencies
215
+
216
+
Add your new feature and any required dependencies to `realm/implants/lib/transport/Cargo.toml`:
186
217
187
218
```toml
188
219
# more stuff above
189
220
190
221
[features]
191
222
default = []
192
223
grpc = []
193
-
dns = [] # <-- see here
224
+
grpc-doh = ["grpc", "dep:hickory-resolver"]
225
+
http1 = []
226
+
dns = ["dep:data-encoding", "dep:rand"]
227
+
custom = ["dep:your-custom-dependency"] # <-- Add your feature here
194
228
mock = ["dep:mockall"]
195
229
230
+
[dependencies]
231
+
# ... existing dependencies ...
232
+
233
+
# Add any dependencies needed by your transport
234
+
your-custom-dependency = { version = "1.0", optional = true }
235
+
196
236
# more stuff below
197
237
```
198
238
199
-
Then make sure the feature flag is populated down from the imix crate `realm/implants/imix/Cargo.toml`
239
+
#### 3. Enable Your Transport in Imix
240
+
241
+
To use your new transport, update the imix Cargo.toml at `realm/implants/imix/Cargo.toml`:
242
+
200
243
```toml
201
244
# more stuff above
202
245
203
246
[features]
204
-
default = ["transport/grpc"]
247
+
# Check if compiled by imix
248
+
win_service = []
249
+
default = ["transport/grpc"] # Default transport
205
250
http1 = ["transport/http1"]
206
251
dns = ["transport/dns"]
252
+
custom = ["transport/custom"] # <-- Add your feature here
207
253
transport-grpc-doh = ["transport/grpc-doh"]
208
254
209
255
# more stuff below
210
256
```
211
257
212
-
And that's all that is needed for Imix to use a new Transport! Now all there is to do is setup the Tarver redirector see the [tavern dev docs here](/dev-guide/tavern#transport-development)
**Important:** Only specify one transport feature at a time. The build will fail if multiple transport features are enabled. Ensure you include `--no-default-features` when building with a non-default transport.
274
+
275
+
#### 5. Set Up the Corresponding Redirector
276
+
277
+
For your agent to communicate, you'll need to implement a corresponding redirector in Tavern. See the redirector implementations in `tavern/internal/redirectors/` for examples:
-`tavern/internal/redirectors/dns/` - DNS redirector
282
+
283
+
Your redirector must implement the `Redirector` interface and register itself in the redirector registry. See `tavern/internal/redirectors/redirector.go` for the interface definition.
284
+
285
+
And that's all that is needed for Imix to use a new Transport! The agent code automatically uses whichever transport is enabled at compile time via the `ActiveTransport` type alias.
Copy file name to clipboardExpand all lines: docs/_docs/user-guide/imix.md
+61-1Lines changed: 61 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,7 +18,7 @@ Building in the dev container limits variables that might cause issues and is th
18
18
19
19
| Env Var | Description | Default | Required |
20
20
| ------- | ----------- | ------- | -------- |
21
-
| IMIX_CALLBACK_URI | URI for initial callbacks (must specify a scheme, e.g. `http://`) |`http://127.0.0.1:8000`| No |
21
+
| IMIX_CALLBACK_URI | URI for initial callbacks (must specify a scheme, e.g. `http://` or `dns://`) |`http://127.0.0.1:8000`| No |
22
22
| IMIX_SERVER_PUBKEY | The public key for the tavern server (obtain from server using `curl $IMIX_CALLBACK_URI/status`). | automatic | Yes |
23
23
| IMIX_CALLBACK_INTERVAL | Duration between callbacks, in seconds. |`5`| No |
24
24
| IMIX_RETRY_INTERVAL | Duration to wait before restarting the agent loop if an error occurs, in seconds. |`5`| No |
@@ -33,6 +33,65 @@ Imix has run-time configuration, that may be specified using environment variabl
33
33
| IMIX_BEACON_ID | The identifier to be used during callback (must be globally unique) | Random UUIDv4 | No |
34
34
| IMIX_LOG | Log message level for debug builds. See below for more information. | INFO | No |
35
35
36
+
## DNS Transport Configuration
37
+
38
+
The DNS transport enables covert C2 communication by tunneling traffic through DNS queries and responses. This transport supports multiple DNS record types (TXT, A, AAAA) and can use either specific DNS servers or the system's default resolver with automatic fallback.
39
+
40
+
### DNS URI Format
41
+
42
+
When using the DNS transport, configure `IMIX_CALLBACK_URI` with the following format:
43
+
44
+
```
45
+
dns://<server>?domain=<DOMAIN>[&type=<TYPE>]
46
+
```
47
+
48
+
**Parameters:**
49
+
-`<server>` - DNS server address(es), `*` to use system resolver, or comma-separated list (e.g., `8.8.8.8:53,1.1.1.1:53`)
50
+
-`domain` - Base domain for DNS queries (e.g., `c2.example.com`)
51
+
-`type` (optional) - DNS record type: `txt` (default), `a`, or `aaaa`
52
+
53
+
**Examples:**
54
+
55
+
```bash
56
+
# Use specific DNS server with TXT records (default)
When using `*` as the server, the agent uses system DNS servers followed by public resolvers (1.1.1.1, 8.8.8.8) as fallbacks. If system configuration cannot be read, only the public resolvers are used. When multiple servers are configured, the agent tries each server in order on every failed request until one succeeds, then uses the working server for subsequent requests.
72
+
73
+
### Record Types
74
+
75
+
| Type | Description | Use Case |
76
+
|------|-------------|----------|
77
+
| TXT | Text records (default) | Best throughput, data encoded in TXT RDATA |
78
+
| A | IPv4 address records | Lower profile, data encoded across multiple A records |
79
+
| AAAA | IPv6 address records | Medium profile, more data per record than A |
80
+
81
+
### Protocol Details
82
+
83
+
The DNS transport uses an async windowed protocol to handle UDP unreliability:
84
+
85
+
-**Chunked transmission**: Large requests are split into chunks that fit within DNS query limits (253 bytes total domain length)
86
+
-**Windowed sending**: Up to 10 packets are sent concurrently
87
+
-**ACK/NACK protocol**: The server responds with acknowledgments for received chunks and requests retransmission of missing chunks
88
+
-**Automatic retries**: Failed chunks are retried up to 3 times before the request fails
89
+
-**CRC32 verification**: Data integrity is verified using CRC32 checksums
90
+
91
+
**Limits:**
92
+
- Maximum data size: 50MB per request
93
+
- Maximum concurrent conversations on server: 10,000
94
+
36
95
## Logging
37
96
38
97
At runtime, you may use the `IMIX_LOG` environment variable to control log levels and verbosity. See [these docs](https://docs.rs/pretty_env_logger/latest/pretty_env_logger/) for more information. **When building a release version of imix, logging is disabled** and is not included in the released binary.
@@ -100,6 +159,7 @@ These flags are passed to cargo build Eg.:
100
159
101
160
-`--features grpc-doh` - Enable DNS over HTTP using cloudflare DNS for the grpc transport
102
161
-`--features http1 --no-default-features` - Changes the default grpc transport to use HTTP/1.1. Requires running the http redirector.
162
+
-`--features dns --no-default-features` - Changes the default grpc transport to use DNS. Requires running the dns redirector. See the [DNS Transport Configuration](#dns-transport-configuration) section for more information on how to configure the DNS transport URI.
0 commit comments