1575  Security Testing for IoT Devices

1575.1 Learning Objectives

By the end of this chapter, you will be able to:

  • Plan Penetration Testing: Design security test plans for IoT devices
  • Perform Vulnerability Scanning: Use automated tools to find common vulnerabilities
  • Test Wireless Security: Validate BLE, Wi-Fi, and LoRa security implementations
  • Understand Security Certifications: Navigate PSA Certified, FIPS, and regulatory requirements

1575.2 Prerequisites

Before diving into this chapter, you should be familiar with:

NoteKey Takeaway

In one sentence: Security testing validates that your device resists real-world attacks, not just theoretical threats.

Remember this rule: If you haven’t tested for it, hackers will. Security bugs are the most expensive to fix after deployment.


1575.3 Why IoT Security Testing is Critical

IoT security failures are catastrophic:

Incident Impact Root Cause
Mirai botnet 600,000 compromised devices, major DDoS attacks Default credentials, no auth
Ring camera hacks Strangers talking to children through cameras Credential stuffing, weak passwords
Jeep Cherokee hack Remote control of vehicle steering/brakes Unprotected CAN bus access
St. Jude pacemakers FDA recall for security vulnerabilities Hardcoded credentials, no encryption

The IoT security challenge: - Devices deployed for 10+ years without updates - Resource constraints limit security measures - Physical access enables hardware attacks - Large fleets multiply attack surface


1575.4 Penetration Testing

1575.4.1 IoT Attack Surface

IoT device attack surface diagram showing physical, wireless, network, and cloud attack vectors

IoT device attack surface diagram
Figure 1575.1: IoT devices present multiple attack surfaces: physical ports, wireless interfaces, network protocols, and cloud APIs

1575.4.2 Penetration Test Methodology

Follow a structured approach to security testing:

Phase Activities Deliverables
Reconnaissance Gather device info, ports, protocols Device profile, attack surface map
Enumeration Identify services, firmware version Service inventory, version database
Vulnerability Assessment Scan for known CVEs, misconfigurations Vulnerability report
Exploitation Attempt to exploit identified vulns Proof-of-concept attacks
Post-Exploitation Pivot, persistence, data exfiltration Impact assessment
Reporting Document findings, recommendations Security report, remediation plan

1575.4.3 Physical Attack Testing

Test for hardware-based attacks:

# UART/Serial Console Access
$ screen /dev/ttyUSB0 115200
# Look for:
# - Boot messages with debug info
# - Shell access (root prompt)
# - Firmware dump capability

# JTAG/SWD Debug Port
$ openocd -f interface/ftdi/um232h.cfg -f target/esp32.cfg
# Check for:
# - Memory read capability
# - Firmware extraction
# - Debug authentication bypass

# Flash Memory Extraction
$ flashrom -p ch341a_spi -r firmware_dump.bin
# Analyze for:
# - Hardcoded credentials
# - Private keys
# - Debug symbols

1575.4.4 Wireless Security Testing

BLE Security Assessment:

# BLE security test script
from bluepy.btle import Scanner, Peripheral

def test_ble_security(device_mac):
    """Test BLE device security posture."""

    # 1. Check if device is discoverable
    scanner = Scanner()
    devices = scanner.scan(10.0)
    discoverable = any(d.addr == device_mac for d in devices)
    print(f"Device discoverable: {discoverable}")

    # 2. Check for pairing requirements
    try:
        p = Peripheral(device_mac)
        # If we get here without pairing, device accepts unauthenticated connections
        print("WARNING: Device accepts unauthenticated connections!")

        # 3. Enumerate services without auth
        services = p.getServices()
        for svc in services:
            print(f"Service: {svc.uuid}")
            for char in svc.getCharacteristics():
                print(f"  Characteristic: {char.uuid}, Properties: {char.propertiesToString()}")
                # Check if sensitive chars are readable without auth
                if char.supportsRead():
                    try:
                        value = char.read()
                        print(f"    Value (unauth): {value.hex()}")
                    except:
                        print(f"    Read protected (good)")

    except Exception as e:
        if "authentication" in str(e).lower():
            print("Device requires authentication (good)")
        else:
            print(f"Connection error: {e}")

Wi-Fi Security Testing:

Test Tool Pass Criteria
Encryption strength aircrack-ng WPA2/WPA3 only, no WEP/WPA
Default SSID Manual No identifiable device info in SSID
Hidden SSID airodump-ng SSID hidden (if security requirement)
AP mode security Manual Provisioning AP uses WPA2 minimum
Credential storage Firmware analysis Wi-Fi creds encrypted in flash

1575.5 Vulnerability Scanning

1575.5.1 Automated Scanning Tools

Tool Purpose Target
Binwalk Extract firmware contents Firmware binaries
Firmwalker Scan for hardcoded secrets Extracted filesystems
OWASP ZAP Web API vulnerability scanning Cloud APIs
Nmap Network service discovery Open ports on device

1575.5.2 Firmware Analysis

# Extract firmware from binary
$ binwalk -e device_firmware.bin

# Scan extracted filesystem for secrets
$ firmwalker firmware/_device_firmware.bin.extracted/

[!] Hardcoded Wi-Fi password found: config/wifi.conf
[!] Hardcoded API key found: app/cloud_client.py
[!] Private RSA key found: etc/ssl/device.key

# Scan for known CVEs in included libraries
$ grep -r "OpenSSL" firmware/_device_firmware.bin.extracted/
OpenSSL 1.0.1e 11 Feb 2013

# Check CVE database
CVE-2014-0160 (Heartbleed) affects OpenSSL 1.0.1e
β†’ Device vulnerable to Heartbleed attack!

1575.5.3 Common IoT Vulnerabilities

Vulnerability Detection Method Fix
Default credentials Firmware analysis Force password change on first boot
Hardcoded secrets String analysis Use secure key storage, provisioning
Unencrypted protocols Network capture Enforce TLS 1.2+ everywhere
Insecure update OTA interception Sign firmware, verify chain of trust
Debug interfaces Physical inspection Disable UART/JTAG in production
Weak crypto Crypto audit Use modern algorithms (AES-256, ECDSA)

1575.6 Automated Security Testing in CI/CD

1575.6.1 Security Test Pipeline

# .github/workflows/security-tests.yml
name: Security Test Suite
on:
  pull_request:
    branches: [main, release/*]

jobs:
  static-analysis:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Static security scan
        run: ./scripts/security-scan.sh
      - name: SAST with Semgrep
        uses: returntocorp/semgrep-action@v1
        with:
          config: >-
            p/security-audit
            p/secrets
            p/owasp-top-ten

  dynamic-ble-tests:
    runs-on: [self-hosted, device-farm]
    needs: static-analysis
    steps:
      - uses: actions/checkout@v3
      - name: Flash test firmware
        run: esptool.py write_flash 0x10000 build/firmware.bin
      - name: Run BLE security tests
        run: pytest tests/security/test_ble_security.py -v --timeout=300

  dynamic-tls-tests:
    runs-on: [self-hosted, device-farm]
    needs: static-analysis
    steps:
      - name: Run TLS security tests
        run: pytest tests/security/test_tls_security.py -v --timeout=300

  security-gate:
    runs-on: ubuntu-latest
    needs: [static-analysis, dynamic-ble-tests, dynamic-tls-tests]
    steps:
      - name: Security gate decision
        run: |
          echo "All security tests passed - PR approved for merge"

1575.6.2 Security Test Examples

# tests/security/test_tls_security.py
import pytest
import ssl
import socket

DEVICE_IP = "192.168.1.100"

def test_tls_version():
    """Device must reject TLS 1.1 and below."""
    context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_1)

    try:
        with socket.create_connection((DEVICE_IP, 443)) as sock:
            with context.wrap_socket(sock, server_hostname=DEVICE_IP) as ssock:
                pytest.fail("SECURITY FAILURE: Device accepted TLS 1.1")
    except ssl.SSLError:
        pass  # Expected - TLS 1.1 should be rejected

def test_firmware_update_requires_signature():
    """Verify device rejects unsigned firmware."""
    # Create unsigned firmware image
    unsigned_fw = create_test_firmware(signed=False)

    # Attempt OTA update
    result = attempt_ota_update(DEVICE_IP, unsigned_fw)

    assert result['status'] == 'rejected', \
        "SECURITY FAILURE: Device accepted unsigned firmware"
    assert 'signature' in result['reason'].lower(), \
        "Device rejected for wrong reason"

1575.7 Security Certifications

1575.7.1 Common IoT Security Certifications

Certification Level Scope Cost/Time
PSA Certified Level 1-3 ARM-based IoT devices $5K-$50K, 3-6 months
SESIP Level 1-3 Secure elements, TEE $10K-$100K, 6-12 months
FIPS 140-2 Level 1-4 Cryptographic modules $50K-$500K, 12-24 months
Common Criteria (EAL) EAL1-EAL7 High-security gov/mil $100K-$1M+, 12-36 months

1575.7.2 When to Certify

Device Type Recommended Certification
Consumer IoT PSA Certified Level 1 (baseline security)
Healthcare/Finance FIPS 140-2 Level 2 (regulated industries)
Government/Military Common Criteria EAL4+ (high assurance)

1575.7.3 PSA Certified Level 1 Requirements

  1. Secure boot: Device only runs signed firmware
  2. Secure storage: Encryption keys stored in secure element
  3. Secure communication: TLS 1.2+ with certificate validation
  4. Secure update: Firmware updates must be signed and authenticated
  5. Vulnerability disclosure: Process for handling reported vulnerabilities

1575.8 Multi-Region Regulatory Compliance

Scenario: A medical device startup has developed a continuous glucose monitor (CGM) with BLE connectivity. After FDA 510(k) clearance in the US, they want to expand to Europe (CE/MDR), Canada (Health Canada), and Japan (PMDA) within 18 months.

Requirements by Region:

Requirement USA (baseline) EU (CE/MDR) Canada Japan
Device classification Class II (510k) Class IIb (MDR) Class III Class II
Clinical data Predicate + bench Clinical study likely Accept FDA data Clinical in Japan
Quality system FDA 21 CFR 820 ISO 13485 + MDR ISO 13485 (MDSAP) ISO 13485 + JPAL
Typical timeline (complete) 12-18 months 6-10 months 12-18 months
Typical cost (complete) $150K-$250K $40K-$80K $100K-$180K

Optimal Strategy: EU first (hardest, most stringent), then Canada (accepts EU data), then Japan (requires local clinical but can use EU data as basis).

Key Insight: The EU MDR has the most stringent clinical evidence requirements. Satisfying MDR creates documentation that simplifies submissions to other regions.


1575.9 Knowledge Check


1575.10 Summary

Security testing validates real-world attack resistance:

  • Penetration Testing: Structured approach to finding security vulnerabilities
  • Physical Security: Test UART, JTAG, flash extraction attack vectors
  • Wireless Security: Validate BLE pairing, Wi-Fi encryption, protocol security
  • Vulnerability Scanning: Automated tools for firmware analysis and CVE detection
  • CI/CD Integration: Automated security gates in development pipeline
  • Certifications: PSA Certified, FIPS, Common Criteria for industry requirements

1575.11 What’s Next?

Continue your testing journey with these chapters: