Challenge: Rusted Oracle
Goal: Recover the flag from the supplied ELF binary.
Format: Step-by-step, command-driven walkthrough (suitable for beginners-to-intermediate reverse engineers).

Summary

Recover a flag hidden in the binary's .data section by reversing the small decoding routine found in the disassembly and reproducing it in Python.

Setup

Commands assume a Linux environment with typical reverse-engineering tools installed:

sudo apt update
sudo apt install -y binutils build-essential python3 python3-pip ghidra radare2 gdb
# radare2 and ghidra optional — objdump/readelf/strings are sufficient

Place the provided challenge binary in a working directory:

mkdir -p ~/htb/rusted_oracle && cd ~/htb/rusted_oracle
# copy/upload the file into this directory (here assumed named `rusted_oracle`)
ls -l

1) Basic reconnaissance

Identify file type and architecture:

file rusted_oracle
# example output: rusted_oracle: ELF 64-bit LSB executable, x86-64, ...

Get a quick impression with strings:

strings rusted_oracle | head -n 50

List sections (useful to locate .data or other relevant areas):

readelf -S rusted_oracle

2) Dump the .data section (where encoded data often lives)

Use readelf or objdump to hexdump the .data section. Either works; here are both examples:

With readelf:

readelf -x .data rusted_oracle | sed -n '1,120p'   # print first part

With objdump:

objdump -s -j .data rusted_oracle | sed -n '1,120p'

You will see a block of hex data — in this challenge the encoded values are laid out as 64-bit words (qwords).

Save the hex dump to a file for easier parsing:

objdump -s -j .data rusted_oracle > data_section_dump.txt

3) Inspect the decoding routine in the binary

Disassemble the binary to find the function that decodes the data. Two simple ways:

Option A — objdump:

objdump -d rusted_oracle | less
# search for likely function names or strings printed by the program when run

Option B — r2 (radare2) for quick cross-references:

r2 -A rusted_oracle
# inside r2: afl        -> list functions
# then: pdf @ sym.<function_name>  -> print disassembly of function

What to look for:

  • A loop that reads qwords from .data.

  • Bitwise operations (XOR, shifts, rotates).

  • A final mov or putchar/write that uses the low-order byte of the manipulated qword.

In this challenge, the decoding routine (reconstructed from the disassembly) applies these operations in order to each 64-bit word:

  1. XOR with 0x524e

  2. ROR (rotate right) by 1

  3. XOR with 0x5648

  4. ROL (rotate left) by 7

  5. SHR (logical right shift) by 8 Then the least-significant byte is taken as the plaintext output byte.

Subscribe to keep reading

This content is free, but you must be subscribed to Andrés to continue reading.

Already a subscriber?Sign in.Not now

Keep Reading


No posts found