Skip to content
Security
Skill

/detecting-command-and-control-over-dns

Detects command-and-control (C2) communications tunneled through DNS protocol including DNS tunneling tools

From plugin
sectinel
12200 skills

Claude Code

$ npx -y skills add Mikaru0Mystic/sectinel --skill detecting-command-and-control-over-dns --agent claude-code

SKILL.md

detecting-command-and-control-over-dns.SKILL.md
name: detecting-command-and-control-over-dns
description: 'Detects command-and-control (C2) communications tunneled through DNS protocol including DNS tunneling tools
  (Iodine, dnscat2, dns2tcp, Cobalt Strike DNS beacon), domain generation algorithms (DGA), encoded payload delivery via TXT/CNAME
  records, and DNS beaconing patterns. Covers Shannon entropy analysis of query subdomains, statistical anomaly detection,
  ML-based DGA classification, passive DNS correlation, and Zeek/Suricata signature development. Activates for requests involving
  DNS-based C2 detection, DNS tunnel identification, suspicious DNS traffic investigation, or DGA domain classification.

  '
domain: cybersecurity
subdomain: network-security
tags:
- dns
- c2
- tunneling
- dga
- network-forensics
- threat-detection
version: 1.0.0
author: mukul975
license: Apache-2.0
nist_csf:
- PR.IR-01
- DE.CM-01
- ID.AM-03
- PR.DS-02

Detecting Command and Control Over DNS

When to Use

  • Investigating suspected DNS tunneling used for C2 communication or data exfiltration
  • Analyzing DNS query logs for signs of encoded payloads in subdomain strings
  • Classifying domains as DGA-generated vs. legitimate using statistical or ML methods
  • Detecting DNS beaconing patterns (regular intervals, consistent query sizes)
  • Hunting for Iodine, dnscat2, dns2tcp, Cobalt Strike DNS, or Sliver DNS traffic
  • Monitoring TXT record abuse for command delivery or staged payload download
  • Building DNS anomaly detection rules for SOC/SIEM deployment

**Do not use** for general DNS performance monitoring or DNS configuration auditing; use DNS health monitoring tools for those. For HTTP/HTTPS-based C2 detection, use network traffic analysis skills focused on web protocols.

**DISCLAIMER**: DNS tunneling tools referenced in this skill (Iodine, dnscat2, dns2tcp) are dual-use. They have legitimate uses (bypassing captive portals, security research) and malicious uses (C2 channels, exfiltration). Only deploy detection in networks you are authorized to monitor. Testing tunneling tools requires explicit authorization.

Prerequisites

  • DNS query logs from recursive resolver, Zeek/Bro, Suricata, or passive DNS tap
  • Python 3.9+ with `numpy`, `scikit-learn`, `pandas`, `tldextract`, and `dnspython`
  • Zeek (formerly Bro) with dns.log output or Suricata with DNS EVE JSON logging
  • SIEM access (Splunk, Elastic, Microsoft Sentinel) for log correlation
  • Passive DNS database access (CIRCL pDNS, Farsight DNSDB, or internal) for enrichment
  • Wireshark/tshark for packet-level DNS inspection
  • Known-good domain whitelist (Alexa/Tranco top 1M or Majestic Million)

Workflow

Step 1: Collect and Parse DNS Query Logs

Ingest DNS traffic from network sensors and parse into analyzable format:

# Zeek - extract dns.log fields
# Default Zeek dns.log columns:
# ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto trans_id rtt query
# qclass qclass_name qtype qtype_name rcode rcode_name AA TC RD RA Z
# answers TTLs rejected

# Filter for potentially suspicious record types
cat dns.log | zeek-cut ts id.orig_h query qtype_name answers rcode_name | \
    grep -E "TXT|NULL|CNAME|MX" > suspicious_qtypes.log

# Extract unique queried domains
cat dns.log | zeek-cut query | sort -u > unique_domains.txt

# Suricata EVE JSON - extract DNS events
cat eve.json | jq -r 'select(.event_type=="dns") |
    [.timestamp, .src_ip, .dns.rrname, .dns.rrtype, .dns.rcode] |
    @tsv' > dns_events.tsv

# tshark - extract DNS queries from pcap
tshark -r capture.pcap -T fields \
    -e frame.time -e ip.src -e ip.dst \
    -e dns.qry.name -e dns.qry.type \
    -e dns.resp.type -e dns.txt \
    -Y "dns" > dns_queries.tsv

# Count queries per domain (find high-volume destinations)
cat dns.log | zeek-cut query | \
    awk -F. '{print $(NF-1)"."$NF}' | \
    sort | uniq -c | sort -rn | head -50

Step 2: Shannon Entropy Analysis of DNS Queries

Calculate entropy of subdomain strings to identify encoded/encrypted data:

#!/usr/bin/env python3
"""Shannon entropy analysis for DNS query subdomains."""

import math
import csv
import sys
from collections import Counter

try:
    import tldextract
    HAS_TLDEXTRACT = True
except ImportError:
    HAS_TLDEXTRACT = False


def shannon_entropy(data):
    """Calculate Shannon entropy of a string (bits per character)."""
    if not data:
        return 0.0
    counter = Counter(data)
    length = len(data)
    entropy = -sum(
        (count / length) * math.log2(count / length)
        for count in counter.values()
    )
    return entropy


def extract_subdomain(fqdn):
    """Extract the subdomain portion from a fully qualified domain name."""
    if HAS_TLDEXTRACT:
        ext = tldextract.extract(fqdn)
        if ext.subdomain:
            return ext.subdomain, f"{ext.domain}.{ext.suffix}"
        return "", f"{ext.domain}.{ext.suffix}"
    else:
        # Fallback: assume last two labels are domain + TLD
        parts = fqdn.rstrip(".").split(".")
        if len(parts) > 2:
            return ".".join(parts[:-2]), ".".join(parts[-2:])
        return "", fqdn


def analyze_dns_entropy(queries, entropy_threshold=3.5, length_threshold=30):
    """
    Analyze DNS queries for tunneling indicators using entropy.

    Thresholds (tunable per environment):
      - entropy_threshold: Shannon entropy above this flags as suspicious (3.5-4.0 typical)
      - length_threshold: Subdomain length above this flags as suspicious (30-50 chars)

    Returns list of flagged queries with scores.
    """
    results = []

    for query_record in queries:
        fqdn = query_record.get("query", "").lower().rstrip(".")
        if not fqdn:
            continue

        subdomain, base_domain = extract_subdomain(fqdn)
        if not subdomain:
            continue

        # Remove dots from subdomain for entropy calculation
        subdomain_flat = subdomain.replace(".", "")
        if not subdomain_flat:
            continue

        entropy
Read more
@mikaru0mystic
Ships withsectinel

Open-source security arsenal for AI coding agents: 784 cybersecurity skills, scanner integrations, and a security MCP for Claude Code, Cursor, opencode, Gemini CLI, Cline, and any agentskills.io agent. Mapped to OWASP, MITRE ATT&CK, NIST CSF, D3FEND, ATLAS.

Stars on GitHub

Momentum

stars in total
12
Star history of Mikaru0Mystic/sectinel on GitHub, a chart by star-history.com

Other skills on sectinel.

More skills from other plugins.

api-security

api-security

Use for authorized security assessment of REST, GraphQL, WebSocket, or SOAP APIs, including discovery, authentication,…

@zhaoxuya520@zhaoxuya520Install Skill
nemoclaw-user-guide

nemoclaw-user-guide

Find official NemoClaw documentation for installation, configuration, operation, or troubleshooting. Also handles requested docs…

@nvidia@nvidiaInstall Skill

Questions about detecting-command-and-control-over-dns.

Which coding agents can use detecting-command-and-control-over-dns?
detecting-command-and-control-over-dns installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.