$ cat writeup.md…
$ cat writeup.md…
hackthebox
Task: Analyze AVR firmware for Arduino Mega bomb defusal device with keypad, LCD, and LED matrix. Solution: Extract XOR-encrypted LED bitmap frames from .data section and decrypt with password 7355608 (CS:GO bomb code) to reveal flag characters displayed on 8x8 LED matrix.
"BOMB HAS BEEN PLANTED". The usual defusal kit isn't working, and something about the device's output seems... unusual. The only way to stop the explosion is buried deep within the firmware. Analyze the schematics, uncover the hidden logic, and defuse the bomb before it's too late.
Provided files:
Defusal — ELF 32-bit AVR executable for ATmega2560 (Arduino Mega), not stripped, with debug info (60KB)circuit.png — Schematic: Arduino Mega + 4×4 keypad + 16×2 LCD + 8×8 LED matrix (MAX7219)C4-BOMB.mp4 — Video intro (not needed for the solution)The firmware is not stripped — all symbols are available: correctPassword, print_flag, inputPassword, keys, rowPins, colPins. Libraries: Keypad, LiquidCrystal, LedControl.
Arduino Mega is connected to:
.data section (0x800200):
colPins/rowPins — keypad configurationkeys — keyboard layout "123A456B789C*0#D""7355608" at address 0x8003B1correctPassword — Arduino String, initialized by global constructor from string "7355608" (length 7). This is the bomb defusal code from CS:GO.
"7355608" (0x37,0x33,0x35,0x35,0x36,0x30,0x38)LedControl::setRow() (each byte = row 8×8, MSB = left LED)#!/usr/bin/env python3 """ Defusal — XOR decryption of LED matrix Extract 296 bytes from .data (0x80021E), XOR with password "7355608" """ password = b"7355608" # 37 frames × 8 bytes from firmware .data section # encrypted_frames = [...] — extract via avr-objdump or Ghidra def decrypt_frame(frame_bytes): """XOR first 7 bytes of frame with password""" result = bytearray(8) for j in range(8): if j < 7: result[j] = frame_bytes[j] ^ password[j] else: result[j] = frame_bytes[j] return result def render_bitmap(frame): """Render 8×8 LED bitmap""" lines = [] for row_byte in frame: row = "" for bit in range(8): row += "██" if row_byte & (0x80 >> bit) else " " lines.append(row) return "\n".join(lines) # Result: each frame = one flag character # H T B { B 1 N G O _ B 4 N G O _ B 0 N G O _ B 1 S H _ B 4 S H _ B 0 S H }
Decoding result of 37 frames:
H T B { B 1 N G O _ B 4 N G O _ B 0 N G O _ B 1 S H _ B 4 S H _ B 0 S H }
Use this technique when:
print_flag, correctPassword are directly visible, simplifying reverse engineering$ cat /etc/motd
Liked this one?
Pro unlocks every writeup, every flag, and API access. $9/mo.
$ cat pricing.md$ grep --similar