2024 Cyber Apocalypse: Hardware Rids
Challenge Information
| Attribute | Details |
|---|---|
| Event | 2024 Cyber Apocalypse |
| Category | Hardware |
| Challenge | Hardware Rids |
| Difficulty | Easy |
Summary
Hardware Rids challenges participants to read data from a simulated W25Q128 flash memory chip via SPI interface. The challenge provides a Python client that communicates with a remote endpoint mimicking an FTDI device. By understanding the SPI command set and using the correct read instruction (0x03), the flag can be extracted from the flash memory.
Analysis
Key components:
- Device: W25Q128 flash memory chip (128 Mbit)
- Interface: SPI (Serial Peripheral Interface)
- Connection: JSON-based TCP protocol to FTDI device
- Tools: pyftdi library for device communication
- Commands: Standard W25Q128 SPI instruction set
The challenge hints at the device through:
- References to ‘ftdi’ and ‘2232h’ in the source code
- Usage of ‘0x9F’ instruction for JEDEC ID reading
- Need to identify the read instruction (0x03)
Solution
Step 1: Identify the Device
From the source code analyzing instruction 0x9F:
jedec_id = exchange([0x9F], 1)This is the “Read JEDEC ID” instruction, revealing the device as W25Q128.
Step 2: Consult Device Datasheet
W25Q128 datasheet specifies:
- Read Data (0x03): Followed by 24-bit address
- Page Program (0x02): Write up to 256 bytes
- Sector Erase (0x20): 4KB blocks
- Block Erase (0xD8): 64KB blocks
- Status Register (0x05): Device status
Step 3: Construct Read Command
To read from address 0x000000:
# Instruction: 0x03# Address: 0x000000 (24-bit, big-endian)# Length: Data to read
read_command = [0x03, 0x00, 0x00, 0x00]Step 4: Send Command and Receive Data
import socketimport json
def exchange(hex_list, readlen=0): host = '94.237.55.246' port = 31251 cs = 0 usb_device_url = 'ftdi://ftdi:2232h/0'
command_data = { "tool": "pyftdi", "cs_pin": cs, "url": usb_device_url, "data_out": [hex(x) for x in hex_list], "readlen": readlen }
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.connect((host, port)) s.sendall(json.dumps(command_data).encode('utf-8'))
data = b'' while True: data += s.recv(1024) if data.endswith(b']'): break
response = json.loads(data.decode('utf-8')) return responseStep 5: Read Flag Data
# Read 50 bytes from address 0x000000flag_data = exchange([0x03, 0x00, 0x00, 0x00], 50)print(flag_data)# Output: [72, 84, 66, 123, 109, 51, 109, 48, 50, 49, 51, 53, ...]Step 6: Convert to ASCII
flag_bytes = bytes(flag_data)flag = flag_bytes.decode('utf-8')print(flag)# HTB{m3m02135_57023_53c2375_f02_3v32y0n3_70_533!@}W25Q128 SPI Commands Reference
Basic Commands
| Command | Opcode | Description |
|---|---|---|
| Read Data | 0x03 | Read memory from address |
| Fast Read | 0x0B | Higher-speed read |
| Page Prog | 0x02 | Write up to 256 bytes |
| Sector Ers | 0x20 | Erase 4KB sector |
| Block Ers | 0x52 | Erase 32KB block |
| Block Ers | 0xD8 | Erase 64KB block |
| Chip Erase | 0xC7 | Erase entire chip |
Status Commands
| Command | Opcode | Description |
|---|---|---|
| Read Status Reg | 0x05 | Read device status |
| Write Status Reg | 0x01 | Modify status |
| Write Enable | 0x06 | Enable write ops |
| Write Disable | 0x04 | Disable write ops |
ID Commands
| Command | Opcode | Description |
|---|---|---|
| Read JEDEC ID | 0x9F | Manufacturer & capacity |
| Read Unique ID | 0x4B | Device unique identifier |
Advanced Commands
| Command | Opcode | Description |
|---|---|---|
| Deep Power-down | 0xB9 | Minimize power usage |
| Release Power-down | 0xAB | Wake from sleep |
| Read Security Reg | 0x48 | Security data |
| Program Security Reg | 0x42 | Write security data |
Protocol Details
Command Data Structure
{ "tool": "pyftdi", "cs_pin": 0, "url": "ftdi://ftdi:2232h/0", "data_out": ["0x3", "0x0", "0x0", "0x0"], "readlen": 50}Response Format
Array of decimal byte values:
[72, 84, 66, 123, ...]Key Takeaways
- SPI is a common interface for flash memory devices
- Device datasheets are essential for understanding command sets
- FTDI chips bridge USB to SPI/JTAG/UART interfaces
- Standard instruction codes (0x9F for JEDEC ID) identify devices
- Reading from address 0x000000 typically contains stored data
- JSON-based protocols simplify hardware simulation in CTF challenges