TLS
The transport security layer under HTTPS, MQTTS and most everything else. On embedded devices it is usually present and usually misconfigured in one of four predictable ways.
TLS provides confidentiality, integrity and server authentication for a byte stream. It is what the S adds to HTTPS, MQTTS and CoAPS. The cryptography itself is sound and rarely the problem; on embedded devices, the failures are almost always in how it is configured and validated.
What the handshake establishes
Client Server
|-- ClientHello (versions, ciphers) ------->|
|<------- ServerHello + Certificate --------|
| [client validates the certificate] |
|-- key exchange ------------------------->|
|<================ encrypted =============>|
Three separate things happen, and they are worth keeping apart because devices routinely get one right and another wrong:
- Key agreement. Both sides derive a shared session key. Modern suites use ephemeral Diffie-Hellman so recording the traffic and later stealing the server key does not decrypt it.
- Server authentication. The server presents an X.509 certificate chaining to a CA the client trusts, and proves it holds the matching private key. This is the step that stops a machine-in-the-middle, and it is the step embedded clients skip.
- Record protection. Everything after is encrypted and integrity-protected.
Encryption without step 2 is worthless against an active attacker: they terminate your TLS, present their own certificate, and open a second TLS connection onwards. Both legs are properly encrypted, and they read everything.
Certificate validation, in full
A client that validates properly checks all of these. A client that checks some of them is not validating:
- the chain reaches a trusted root;
- every signature in the chain verifies;
- the leaf is not expired and not yet-valid;
- the hostname matches the certificate's SAN (not just the deprecated CN);
- the certificate is not revoked, where revocation checking is feasible;
- intermediate certificates carry the CA basic constraint.
The four failures you actually find
- Validation disabled.
verify=False,CURLOPT_SSL_VERIFYPEER 0,MQTT_SSL_VERIFY_NONE, anesp_http_client_config_twith nocert_pem. Common because it makes a development error disappear, and it ships. - Hostname not checked. The chain verifies, so it looks like validation works, but any valid certificate for any name is accepted. Any attacker with a legitimate certificate for a domain they own is now a valid man in the middle.
- A single private key across the fleet. The certificate and its key are in the firmware. Dump one device and you can impersonate the server, or any device, everywhere. This is endemic in consumer IoT.
- A trust store frozen in firmware. Roots expire. A device shipped in 2015 with a hardcoded CA bundle either stops connecting or has validation quietly turned off in a later update.
Pinning
Certificate pinning narrows trust from "any CA" to "this specific certificate or public key". It is the right default for a device that only ever talks to one vendor endpoint, because it removes the entire public CA system from the attack surface, including a compromised or coerced CA.
The tradeoff is operational: rotating the pinned key requires a firmware update, and a pin that expires before the fleet updates bricks the connection. Pinning the intermediate CA or the public key rather than the leaf certificate is the usual compromise. For an analyst, pinning is also exactly what stops mitmproxy from working, and unpinning by patching the firmware is a routine step.
Mutual TLS
In mTLS the client also presents a certificate, so the server authenticates the device. It is the strongest option for device-to-cloud and the reason per-device provisioning matters: mTLS with one shared client certificate across the fleet authenticates the model, not the unit.
Pitfalls
- TLS protects the transport, not the payload or the endpoints. An authenticated update over TLS is still unsafe if the image itself is unsigned.
- Devices with no reliable clock cannot check certificate validity dates, and firmware often works around it by ignoring them.
- TLS 1.0 and 1.1 are dead but still appear on long-lived devices. Check the negotiated version, not the marketing.
- Seeing TLS on the wire tells you nothing about whether the client validates. That has to be tested by presenting a bad certificate and watching whether it connects anyway.
What it pairs with
mitmproxy is how you inspect and break it, wireshark shows the handshake, ota-update depends on it, and hardcoded-secrets covers finding the fleet-wide key in the firmware.
Further reading
Used in these courses
**Intermediate** course (recommended pre-requisite: the offensive twin `mqtt-broker-takeover`). You take over a Mosquitto broker shipped with the locks off, harden it via ACLs and mTLS, wire detection signatures into a SIEM, and run the offensive playbook against your config in the final lab. 10 lessons + 1 lab.
REST API Recon on IoT Cloud Endpoints**Beginner** course (prereq: Hunting Hardcoded Secrets). Most IoT breaches today are the cloud REST API the device talks to. Cover endpoint identification, canonical IoT-cloud mistakes (no rate limit, IDOR, leaky firmware paths), curl + mitmproxy workflow. Validation Box deployment pending.