Skip to content

Comments

1019: Dns transport support#1139

Merged
KaliPatriot merged 28 commits intomainfrom
feat/dns-transport
Dec 27, 2025
Merged

1019: Dns transport support#1139
KaliPatriot merged 28 commits intomainfrom
feat/dns-transport

Conversation

@KaliPatriot
Copy link
Collaborator

What type of PR is this?

/kind feature

What this PR does / why we need it:

This PR adds a DNS redirector to tavern and a DNS transport to imix to enable DNS beacon communication. I have also updated some of the documentation around developing and using new transport methods.

Which issue(s) this PR fixes:

Fixes #1019

@KaliPatriot KaliPatriot linked an issue Dec 5, 2025 that may be closed by this pull request
@hulto
Copy link
Collaborator

hulto commented Dec 6, 2025

Were you able to run this end to end over public DNS?

@KaliPatriot
Copy link
Collaborator Author

Were you able to run this end to end over public DNS?

Good question, let me test this

Copy link
Collaborator

@hulto hulto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got some of the way through the rust.
Can you explain the conversations concept?

#[cfg(debug_assertions)]
log::debug!("Init packet subdomain: {}.{}", subdomain, self.base_domain);

for attempt in 0..MAX_RETRIES {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually retries are handled in the agent code not the transport.
Centralizing the logic in the agent makes things like run time reconfiguration easier.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with this for retrying to entire transport conversation, however I do think given that dns has to have chunked conversations, its good to keep this retry logic. Other wise a single missed chunk will cause a whole conversation to fail. This increased the overall stability a lot more for the protocol.

Copy link
Collaborator

@hulto hulto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took another pass - still have a lot to review.

@hulto
Copy link
Collaborator

hulto commented Dec 9, 2025

Also have you seen sliver's implementation?
https://github.com/BishopFox/sliver/blob/master/implant/sliver/transports/dnsclient/dnsclient.go
Similarly they use grpc for comms tho they have a meta proto called envelope that embeds the message as opposed to our use of codecs.

Copy link
Collaborator

@hulto hulto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lemme know when you're ready for another review.

Overall I think two big changes:

  • When possible remove failover and retry logic allow the agent to handle those
  • Look into grpc built-in functionality to replace some of the manual chunking and retry logic.

@KaliPatriot KaliPatriot marked this pull request as draft December 22, 2025 02:56
@github-actions
Copy link
Contributor

github-actions bot commented Dec 25, 2025

Summary

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Other ❓ Flaky 🍂 Duration ⏱️
7518    ±0 7518    ±0 0    ±0 0    ±0 0    ±0 0    ±0 1ms    ±0

Previous Results

Build 🏗️ Result 🧪 Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Other ❓ Flaky 🍂 Duration ⏱️
#16 7518 7518 0 0 0 0 26.8s

Insights

Average Tests per Run Total Flaky Tests Total Failed Slowest Test (p95)
7518 0 0 44.1s

Slowest Tests

Test 📝 Results 📊 Duration (avg) ⏱️ Duration (p95) ⏱️
eldritch: random::string_impl::tests::test_string_uniform 9 40.2s 44.1s
eldritch: random::string_impl::tests::test_string_uniform 9 40.2s 44.1s
eldritch: random::string_impl::tests::test_string_uniform 9 40.2s 44.1s
eldritch: random::string_impl::tests::test_string_uniform 9 40.2s 44.1s
eldritch: random::string_impl::tests::test_string_uniform 9 40.2s 44.1s
eldritch: random::string_impl::tests::test_string_uniform 9 40.2s 44.1s
eldritch: random::string_impl::tests::test_string_uniform 9 40.2s 44.1s
eldritch: random::string_impl::tests::test_string_uniform 9 40.2s 44.1s
eldritch: random::string_impl::tests::test_string_uniform 9 40.2s 44.1s
eldritch: random::string_impl::tests::test_string_length 9 6.2s 11.0s

🎉 No failed tests in this run. | 🍂 No flaky tests in this run.

Github Test Reporter by CTRF 💚

🔄 This comment has been updated

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds DNS-based covert channel communication to Realm, enabling agents (Imix) to communicate with the C2 server (Tavern) through DNS queries and responses. The implementation includes:

  • A DNS redirector in Tavern that receives DNS queries, parses encoded C2 traffic, forwards to upstream gRPC, and returns responses
  • A DNS transport in Imix that encodes requests as DNS subdomains and decodes responses from DNS records
  • Support for TXT, A, and AAAA record types with automatic resolver fallback
  • Async windowed protocol with ACK/NACK for reliable UDP transmission
  • Comprehensive test coverage for both client and server

Reviewed changes

Copilot reviewed 20 out of 22 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tavern/internal/redirectors/dns/dns.go DNS redirector implementation with packet handling, conversation management, and DNS protocol support
tavern/internal/redirectors/dns/dns_test.go Comprehensive unit tests for DNS redirector functionality
implants/lib/transport/src/dns.rs DNS transport client with chunking, windowing, retry logic, and record type support
tavern/internal/c2/proto/dns.proto Protobuf definitions for DNS packet protocol
tavern/internal/ent/beacon/beacon.go Added TRANSPORT_DNS enum value
docs/_docs/user-guide/imix.md User documentation for DNS transport configuration
docs/_docs/dev-guide/imix.md Developer guide for implementing new transports
Various Cargo.toml and build files Build configuration for DNS feature

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…mt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt
@KaliPatriot KaliPatriot marked this pull request as ready for review December 25, 2025 06:02
tavern redirector --transport dns --listen "0.0.0.0:53?domain=c2.example.com" localhost:8000

# Support multiple domains
tavern redirector --transport dns --listen "0.0.0.0:53?domain=c2.example.com&domain=backup.example.com" localhost:8000
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't do multi-domain here.
We're going to do multi transport in the agent logic which can include multiple domains on the same transport.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for the redirector, not the agent.

@KaliPatriot KaliPatriot requested a review from hulto December 26, 2025 22:58
hulto
hulto previously approved these changes Dec 27, 2025
@KaliPatriot KaliPatriot merged commit 3c61bbc into main Dec 27, 2025
11 of 12 checks passed
@KaliPatriot KaliPatriot deleted the feat/dns-transport branch December 27, 2025 01:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feature] DNS transport

3 participants