//nullCTF 2025 – wordleOS (Reverse)
>TL;DR
- The bootable image hides a 64-bit Rust ELF at offset 0xCE00. Extract it, disassemble, and inspect the keyboard interrupt handler. The handler checks a specific VGA text buffer pattern to decide win/lose. Decoding the expected pattern reveals the flag:
nullctf{b00t_1nt0_w0rdl3}.
>Environment
-
Host: Linux
-
Tools:
binwalk,dd,file,objdump,strings,qemu-system-x86_64 -
Run command (if you want to see the OS):
```sh
qemu-system-x86_64 -drive format=raw,file=wordle_os.bin -display curses -serial mon:stdio
```
>Step-by-step
1) Unpack and identify
unzip -o wordle_os.zip
file wordle_os.bin # DOS/MBR boot sector
stat -c '%s' wordle_os.bin # size 94720
binwalk wordle_os.bin # shows ELF at 0xCE00
2) Extract the embedded ELF
dd if=wordle_os.bin of=payload_elf bs=1 skip=$((0xce00))
file payload_elf # 64-bit, static, not stripped
3) Quick strings poke
strings payload_elf shows splash text ("Welcome to WordleOS", "Correct!") but no obvious flag, so we move to disassembly.
4) Disassemble
objdump -d -M intel payload_elf > disasm.txt
Key symbol: keyboard_interrupt_handler (Rust mangled). It handles input, then compares the screen buffer against a fixed pattern before printing success/placeholder.
5) Find the win condition
Inside keyboard_interrupt_handler, near 0x2035a0+, there is a long sequence of mov/cmp pairs comparing 16-bit words loaded from [writer + offsets] with immediates like 0xf200f75.... These immediates are VGA text buffer entries: upper byte = attribute, lower byte = ASCII character.
I decoded the sequence of low bytes (characters) from the comparisons. They spell out the flag characters in order.
Extracted pattern (low bytes only):
6e 0f 20 0f 75 -> 'n'
6c 0f 20 0f 6c -> 'l'
30 0f 20 0f 30 -> '0'
66 0f 20 0f 7b -> '{'
62 0f 20 0f 30 -> 'b'
5f 0f 20 0f 31 -> '_'
... (continues)
Collecting all chars yields nullctf{b00t_1nt0_w0rdl3}.
![[Pasted image 20251206002345.png]]
6) Confirm flag
No brute force needed; the flag is encoded in the success VGA buffer pattern. The handler prints the win message only when the buffer matches this exact layout.
>Flag
nullctf{b00t_1nt0_w0rdl3}
>Solver snippets
While no standalone script was required, the key commands were:
# Extract ELF
binwalk wordle_os.bin
dd if=wordle_os.bin of=payload_elf bs=1 skip=$((0xce00))
# Disassemble
objdump -d -M intel payload_elf > disasm.txt
# (Optional) grep for handler
grep -n "keyboard_interrupt_handler" disasm.txt
To decode the pattern manually, note each movabs/cmp immediate; take the low byte of each 16-bit pair as the character. A quick manual walk over that block reveals the full flag.
>Notes
-
Running under QEMU is only for fun; the flag is recoverable statically.
-
Everything is plain VGA text mode; colors are all white (attribute 0x0f), matching the challenge story.