In this write-up, I go over the step-by-step solution of “Hell’s Hex Station”, a challenge I created for the 2024 edition of Infogroep’s Capture the Flag.
Description
Mein Fraulein,I haven't heard from you in a while. Won't you write me?
Solution
The title of the challenge is a reference to Rudolf Hell (inventor of the “Hellschreiber”), the hexadecimal system, and numbers stations. The description is a reference to a 2006 talk at DEF CON and also references the recurring German theme of this challenge.1
The provided .wav
file starts with the tune of the “Lincolnshire Poacher” numbers station followed by a voice repeating "CP437"
and ends with beeping. Using exiftool
to look at the metadata of the audio file, we get the following output:
$ exiftool recording.wav ⋯Comment : FELDHELL freq=14071.500Software : fldigi-4.1.06 (libsndfile-1.0.28)⋯
The Comment
and Software
values bring us to the solution of the challenge: the beeping that makes up the bulk of the .wav
file is “Hellschreiber” in Feld Hell mode, a technique developed in 1927 by Rudolf Hell and currently in use by Ham radio hobbyists. Hellschreiber modes are based on character scanning2: we transmit characters as patterns of beeps, resembling a dot-matrix printer.
As fldigi
contains Feld Hell as one of their supported digital modes, we can use it to decode the beeping in our file. After installing and opening fldigi
, we select the correct operational mode via "Op Mode → Hell → Feld Hell"
and load our .wav
file via "File → Audio → Playback"
.
In the waterfall view on the bottom of the fldigi
window, we select the area that lights up when the beeping begins. Below, you can see a screenshot of the fldigi
program, around a minute after loading the .wav
file. A list of numbers in hexadecimal representation appear on screen:
49 47 43 54 46 7b 48 33 4c 4c e1 43 48 52 33 31 42 33 52 21 7d
In general, we could use a range of different tools to transform this list of hexadecimal numbers to a string of characters. The simplest way of doing this would be through CyberChef. After giving our list of numbers as input, we can pick the "From Hex"
recipe (or choose “Magic” and provide IGCTF
as the crib) to obtain the following output:
IGCTF{H3LLáCHR31B3R!}
This is not the correct flag, however! The provided .wav
file specifically mentioned "CP437"
, which is a specific character encoding. Using Python (or any other tool that allows us to use CP437
), we obtain IGCTF{H3LLßCHR31B3R!}
, which is the correct flag:
>>> bytes.fromhex(hex_string).decode("cp437")'IGCTF{H3LLßCHR31B3R!}'
The “Mein Fraulein” description, Rudolf Hell being a German engineer, and the correct flag of this challenge containing a
ß
. ↩︎