Holmes CTF 2026


Iron Feather Hard Challenge โ€“ Full Professional Writeโ€‘Up

Part 1: Datastore / Crypto Reverseโ€‘Engineering

  • Magic header (8โ€‘byte ASCII): Found via xxd on the encrypted datastore:bashxxd -l 16 dataman_encrypted.bin โ†’ PX4CRYPT
  • Authenticated encryption algorithm: Disassembly shows EVP_aes_256_gcm() โ†’ AES-256-GCM
  • Custom KDF RVA: Identified in Ghidra/IDA: 0x170af0
  • Rounds in custom 32โ€‘bit mixing loop: Loop counter analysis โ†’ 384
  • Standard KDF producing AES key: Call to PKCS5_PBKDF2_HMAC โ†’ PBKDF2-HMAC-SHA256
  • Derived AESโ€‘256 key: Extracted via GDB memory dump:Codea40ba87b8a0e21d4ead98b917c4bf0f60cc65b25c614b93f107e5ed1e483d6ce

Part 2: Flightโ€‘Log Investigation (CSV telemetry)

Flight CSV discovery

bash

cd /home/.../HTB/CTFs/IronFeather/flight_csv
grep -RinE \
'crash|impact|collision|freefall|failure|termination|landed|ground_contact|at_rest|kill|lockdown' \
*.csv
head -5 flight_failure_detector_status_0.csv
awk -F, 'NR==1 || ($1>=520000000 && $1<=578000000)' flight_failure_detector_status_0.csv

โ†’ Motor stop mask transitions at 520.772 s (4095 = all motors stopped).

Landโ€‘detector timeline

bash

awk -F, 'NR==1 || ($1>=520000000 && $1<=578000000)' flight_vehicle_land_detected_0.csv

Custom filter for state changes:

bash

awk -F, '
NR==1 {print; next}
$1 >= 520772000 {
    state = $2 "," $3 "," $4 "," $5 "," $13
    if (state != previous) {print; previous = state}
}
' flight_vehicle_land_detected_0.csv

โ†’ Key transitions:

  • 521.648 s vertical movement
  • 527.648 s stopped vertical movement
  • 577.312 s ground_contact=1, landed=1, at_rest=1

Crashโ€‘timeline script

bash

nano crash_timeline.py
python3 crash_timeline.py | tee crash_timeline_output.txt

Correlated events:

  • Failure command injected: 520.764 s
  • Motor stop: 520.772 s
  • Disarmed: 576.968 s
  • Landed/impact transition: 577.312 s

Motionโ€‘stop coordinate lookup

Python snippet to compare BEFORE/AFTER samples around 527.648 s:

bash

python3 motion_stop_lookup.py

Physical impact detection

Acceleration analysis script:

bash

nano find_impact.py
python3 find_impact.py
  • Search window: 520.772โ€“576.968 s
  • Top spike: 525.852 s, |a| โ‰ˆ 1228 m/sยฒ
  • Nearest vehicle_global_position: โ†’ 51.5016938,-0.1620929
  • Nearest groundtruth: โ†’ 51.5016942,-0.1620927

Correct crash flag:

Code

51.5016938,-0.1620929

Raw position inspection

bash

awk -F, 'NR==1 || ($1>=525700000 && $1<=526000000)' flight_vehicle_global_position_0.csv
awk -F, 'NR==1 || ($1>=525700000 && $1<=526000000)' flight_vehicle_global_position_groundtruth_0.csv
awk -F, 'NR==1 || ($1>=525700000 && $1<=526000000)' flight_vehicle_gps_position_0.csv
awk -F, 'NR==1 || ($1>=525700000 && $1<=526000000)' flight_sensor_combined_0.csv

Disarm event:

bash

awk -F, 'NR==1 || ($1>=576800000 && $1<=577100000)' flight_actuator_armed_0.csv

โ†’ 576.968 s armed=0

Part 3: Final Answers

  • Magic: PX4CRYPT
  • AEAD: AES-256-GCM
  • RVA: 0x170af0
  • Mixing rounds: 384
  • KDF: PBKDF2-HMAC-SHA256
  • AES key: a40ba87b8a0e21d4ead98b917c4bf0f60cc65b25c614b93f107e5ed1e483d6ce
  • Active bank: 0
  • Mission items: 24
  • Payload release: 10
  • Landing site: 51.50085,-0.15955
  • Takeoff: 51.4996987,-0.1607999
  • Payload release position: 51.5035600,-0.1608418
  • Injected command: MAV_CMD_COMPONENT_ARM_DISARM
  • Distance: 277
  • Crash site: 51.5016938,-0.1620929
  • Disarm time: 576.968
  • Closest road: Knightsbridge

๐Ÿ”‘ Key Point

  • Reverseโ€‘engineering answers (magic, crypto, KDF, AES key) came from datastore/binary analysis.
  • Flightโ€‘log answers (mission items, coordinates, crash site, disarm time) were extracted using the CSV commands and Python scripts above.

All Answers

What eight-byte ASCII magic identifies the encrypted datastore format?(string)

PX4CRYPT

Which authenticated encryption algorithm protects the datastore? (string)

AES-256-GCM

What is the Relative Virtual Address (RVA) of the custom key-derivation function? (hex number)

0x170af0

How many rounds are performed by the custom 32-bit mixing loop? (number)

384

Which standard KDF produces the AES key? (string)

PBKDF2โ€‘HMACโ€‘SHA256

What AES-256 key is derived for the supplied encrypted image? (64 lowercase hexadecimal characters)

a40ba87b8a0e21d4ead98b917c4bf0f60cc65b25c614b93f107e5ed1e483d6ce

Which of PX4’s two mission banks is active? (number)

0

How many mission items are stored in the active bank? (number)

24

Which mission item triggers payload release? (number)

10

Where was the drone supposed to land? (latitude,longitude; 5 decimal places)

51.50085,-0.15955

Where did the drone take off? (latitude,longitude; 7 decimal places)

51.4996987,-0.1607999

Where was the drone when payload release was triggered?(latitude,longitude; 7 decimal places)

51.5035600,-0.1608418

MAV_CMD_COMPONENT_ARM_DISARM

How far did the drone travel between payload release and command injection? (horizontal metres, nearest whole number)

277

Where did the drone crash? (latitude,longitude; 7 decimal places)

51.5016938,-0.1620929

When was the drone disarmed after the crash? (seconds after boot; 3 decimal places)

576.968

Which road is closest to the crash site? (string)

Knightsbridge

Leave a Reply

Your email address will not be published. Required fields are marked *