Back to Articles

Inside GoBotnet: How DNS Tunneling Turns Corporate Networks Into Command Channels

[ View on GitHub ]

Inside GoBotnet: How DNS Tunneling Turns Corporate Networks Into Command Channels

Hook

DNS queries are supposed to resolve domain names, not smuggle remote execution commands. Yet this Go-based botnet turns your organization's most trusted network protocol into a bidirectional command channel that bypasses most traditional security monitoring.

Context

Traditional botnets rely on HTTP or IRC connections for command and control, but modern enterprise networks have gotten smarter. Firewalls inspect HTTP traffic, IDS systems flag suspicious outbound connections, and corporate proxies require NTLM authentication. For red teamers and security researchers studying adversarial techniques, this creates an interesting problem: how do you maintain persistent access in environments where almost everything is monitored?

GoBotnet emerged as an educational implementation addressing this challenge. Written entirely in Go, it demonstrates how modern malware evades network controls using DNS tunneling—a technique where command data is encoded into DNS queries and responses. Since DNS is essential for normal network operations, blocking it entirely breaks legitimate functionality. This makes DNS an attractive covert channel, and GoBotnet provides a working reference implementation that security professionals can study in controlled environments.

Technical Insight

Web Interface

C&C Server (Go/Echo)

Windows Bots (Go)

Registry Query

HTTP Beacon + NTLM Auth

Fallback: DNS Queries

Covert Channel

Store Commands

Poll for Tasks

Results: Recon/Files/Logs

Issue Commands

Bot Status

Bot Instance

Proxy Detection

DNS Tunnel

REST API

Command Queue

Angular Dashboard

System architecture — auto-generated

The architecture separates into three layers: Windows bots, a REST API C&C server built with Echo framework, and an Angular admin panel. What makes this interesting from an engineering perspective is how it solves the corporate environment problem—specifically, how bots beacon through authenticated proxies and fall back to DNS when HTTP fails.

The bot implementation detects system proxies automatically, a critical feature since most corporate Windows machines inherit proxy settings from Active Directory. Here's the relevant proxy detection logic:

func getSystemProxy() (*url.URL, error) {
    // Query Windows registry for proxy settings
    key, err := registry.OpenKey(registry.CURRENT_USER, 
        `Software\Microsoft\Windows\CurrentVersion\Internet Settings`, 
        registry.QUERY_VALUE)
    if err != nil {
        return nil, err
    }
    defer key.Close()
    
    proxyEnable, _, err := key.GetIntegerValue("ProxyEnable")
    if err != nil || proxyEnable == 0 {
        return nil, nil // No proxy configured
    }
    
    proxyServer, _, err := key.GetStringValue("ProxyServer")
    if err != nil {
        return nil, err
    }
    
    return url.Parse("http://" + proxyServer)
}

This registry-based approach is more reliable than environment variables in Windows enterprise environments. Once the proxy is detected, the bot wraps HTTP clients with NTLM authentication, allowing it to authenticate transparently using the current user's credentials—a technique that lets compromised workstations blend into normal corporate traffic patterns.

The DNS tunneling implementation is where the architecture gets genuinely interesting. When HTTP communication fails or is explicitly disabled, bots switch to DNS mode. Commands are base64-encoded and split across multiple TXT record queries. The C&C server runs a custom DNS resolver that intercepts these queries, decodes the payloads, executes commands, and returns responses encoded in DNS answers. This bidirectional channel operates entirely over port 53, the protocol's standard port that's rarely blocked.

The command execution flow uses a polling model rather than push notifications. Bots send periodic "heartbeat" requests containing system metadata (hostname, username, OS version, IP address). The C&C server queues commands in memory, associated with each bot's unique identifier. When a bot checks in, the server responds with any pending commands. This design avoids maintaining persistent connections—which are easily detected by behavioral analysis—in favor of periodic beacons that mimic legitimate DNS or HTTP traffic patterns.

From a code architecture perspective, GoBotnet demonstrates several patterns common in Go-based C&C frameworks. The bot uses a finite state machine to manage its lifecycle (initializing, beaconing, executing, sleeping). The C&C server leverages Echo's middleware for authentication, CORS handling, and request logging. The separation between transport layer (HTTP vs DNS) and command execution layer allows the same command set to work regardless of communication channel—an abstraction that makes the codebase maintainable despite supporting multiple protocols.

The keylogging and screenshot capabilities rely on Windows API calls via CGO, binding to user32.dll and gdi32.dll. This produces larger binaries than pure Go code, but provides the low-level system access necessary for these features. The file transfer implementation chunks data to avoid oversized DNS responses, a practical constraint when your C&C channel has strict packet size limits.

Gotcha

The Windows-only implementation is the most significant limitation. While Go compiles to multiple platforms, GoBotnet's reliance on Windows-specific APIs (registry access, user32.dll for keylogging, Windows proxy detection) means porting it to Linux or macOS would require substantial rewrites. For red team exercises targeting heterogeneous environments, this is a dealbreaker.

DNS tunneling, while covert, is also painfully slow. DNS responses are limited to approximately 512 bytes for UDP packets (though TCP can handle larger responses). This makes it suitable for command transmission but impractical for exfiltrating large files. Security tools specifically designed to detect DNS tunneling—like Cisco Umbrella or Darktrace—look for patterns like high query volumes to uncommon domains, abnormally long subdomain strings, or statistical anomalies in query entropy. GoBotnet implements basic encoding but lacks the sophisticated obfuscation techniques needed to evade modern DNS security analytics. The codebase also appears unmaintained, with the last commit from several years ago and no indication of active development or security hardening against analysis.

Verdict

Use if: You're a security researcher studying C&C protocols in a lab environment, a red teamer who needs a reference implementation of DNS tunneling to understand how attackers bypass network controls, or an educator building coursework around offensive security techniques. The code is clear enough to learn from and demonstrates practical corporate evasion tactics like proxy authentication. Skip if: You need a production-ready C2 framework (use Sliver or Mythic instead), you're targeting non-Windows systems, you lack explicit legal authorization (this is adversarial tooling), or you need active maintenance and community support. For anything beyond controlled research, established frameworks provide better operational security, cross-platform support, and legal backing.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/developer-tools/andrewaeva-gobotnet.svg)](https://starlog.is/api/badge-click/developer-tools/andrewaeva-gobotnet)