Binary Whisper: Beginner Binary Analysis Walkthrough
If you want to try the challenge first, grab it here: https://welsh.co.ke/challenges/
TL;DR
- Goal: Recover the hidden flag from a small stripped ELF binary.
- Approach:
file+strings+ a tight look atobjdump. - Key idea: A fixed XOR key is used to decode a hardcoded byte array.
1) Quick recon with file
welsh@0xwelsh binary_whisper $ file ./binary_whisper./binary_whisper: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=e68da56ebe43d698f2c54471b7c075e181f4156e, for GNU/Linux 4.4.0, strippedWhat this tells us: it’s a stripped 64‑bit ELF, so symbols are gone, but we can still rely on strings and common libc calls.
2) Find interesting strings
welsh@0xwelsh binary_whisper $ strings -n 6 ./binary_whisper | head -n 40n/lib64/ld-linux-x86-64.so.2__stack_chk_failstrcspn__libc_start_main__cxa_finalizeprintfstrcmplibc.so.6GLIBC_2.4GLIBC_2.2.5GLIBC_2.34_ITM_deregisterTMCloneTable__gmon_start___ITM_registerTMCloneTableI^LQHCDKXSuKDKFSYCYuWEnter flag:Input error.Access granted.Access denied.GCC: (GNU) 15.2.1 20260103...Key observations:
- The binary uses
printf,strcspn, andstrcmp→ classic input → trim → compare flow. - The weird string
I^LQHCDKXSuKDKFSYCYuis a strong candidate for an encoded flag.
3) Locate the comparison logic
welsh@0xwelsh binary_whisper $ objdump -d ./binary_whisper | rg -n "strcmp|strcspn|printf|puts"...The interesting part is where strcspn is called (to remove the newline), a loop runs, and then strcmp compares your input to a decoded buffer.
To focus the logic, I disassembled around the core block:
objdump -d --start-address=0x11f0 --stop-address=0x12b0 ./binary_whisperThis loop does the work:
- Reads bytes from
.rodata - XORs each byte with
0x2a - Builds a decoded buffer
- Compares that buffer with your input using
strcmp
So the operation is:
decoded[i] = rodata[0x2020 + i] ^ 0x2a4) Extract the encoded bytes from .rodata
objdump -s -j .rodata ./binary_whisper | head -n 80From .rodata, we can lift the 24 bytes at 0x2020:
49 5e 4c 51 48 43 44 4b 58 53 75 4b 44 4b 46 53 59 43 59 75 1b 1a 1b 575) Decode with a tiny Python script
Create a file named solve.py:
data = bytes.fromhex( "49 5e 4c 51 48 43 44 4b 58 53 75 4b 44 4b 46 53 59 43 59 75 1b 1a 1b 57")print(bytes(b ^ 0x2a for b in data).decode())Run it:
welsh@0xwelsh binary_whisper $ python3 solve.pyctf{binary_analysis_101}Flag
ctf{binary_analysis_101}
Takeaways
strings+ a small disassembly window can solve many beginner binaries.- XOR is reversible — if you spot the key, decoding is trivial.
- This is a great starter for learning how buffers are built and compared in real programs.
If you’re new to reverse engineering, try repeating the process without copying the steps — it locks the workflow into memory fast.
Next reads
View all →21 Dec
Advent of CTF 2025: Day 4 - The Elf's Wager
Reverse engineering challenge involving static analysis of a stripped ELF binary with anti-debugging measures and XOR-based authentication.
18 Dec
Static Analysis of ELF x86 Binary - RootMe Challenge
Systematic reverse engineering approach for unprotected ELF binaries using static analysis techniques and Ghidra decompilation
21 Dec
Advent of CTF 2025: Day 1 - The Mission Begins
A beginner-friendly cryptography challenge involving multi-step encoding conversion using CyberChef to decode binary data into the final flag.
Get posts by email
One email when I publish, not a drip, not weekly. Sign up and I'll only write when there's something new.
You won't get mail just for signing up. Unsubscribe any time.