Writeup: Solving the Reverse Engineering Challenge
This writeup details the process of solving a reverse engineering challenge involving an ELF64 x86-64 binary named chall. The goal is to determine the correct input string that, when provided to the program via ./chall, results in the output:
Congratss!! you can now submit the flag
Through disassembly, analysis of the .rodata section, and reverse engineering, we derive the 40-character flag: nexus{vm_revers1ng_1s_f45c1n4t1ng_4nd_3xtremely_p41nful}.
This writeup details the process of solving a Capture The Flag (CTF) challenge that involves reverse-engineering a virtual machine (VM) implemented in C. The VM reads instructions from a binary file (code.bin), processes an input flag, and outputs “Correct!” if the flag is valid. The goal is to determine the correct flag by analyzing the VM’s behavior and extracting the necessary computations from code.bin.
This challenge involves reverse-engineering a C++ program to uncover a hidden flag in the format nexus{...}, commonly used in Capture The Flag (CTF) competitions. The program performs a series of bitwise transformations and XOR operations on provided byte arrays (fakeflag, key, affus, and key2) and attempts to read a file whose name and contents are derived from these arrays. A provided Python script replicates the necessary transformations to compute the flag directly.
The provided Python script, patch_pong.py, modifies the MS-DOS COM executable pong.com to reveal a hidden flag in a Capture The Flag (CTF) challenge. The script applies two byte patches to ensure the program jumps directly to the flag-displaying routine and exits cleanly, displaying the flag when run in DOSBox. This writeup explains the problem, the script’s functionality, and its effect.
Problem Context
The pong.com binary is a DOS-based game (likely Pong) containing a hidden flag. The flag is displayed when the game state byte at memory address 0x086B (referred to as byte_1086B, file offset 0x086B - 0x0100 = 0x076B) is set to 0x03. This triggers a routine at 0x0796 that prints:
This writeup details the steps to reverse engineer and analyze the binary rustySteps. The challenge has 7 solves and is tagged as “easy”. The flag is nexus{RusT_R3v_15_Fun_Right}.
Step 1: Identifying UPX Packing
After running the strings command on the binary, we observe indications of UPX packing:
To unpack the binary, we use the following command:
upx -d rustySteps
Step 2: Analyzing with strings Again
After unpacking, running strings again reveals more interesting strings. This gives us clues for further analysis.
Upon analyzing the provided files, we observed the following directory structure:
➜ solver ls
decrypted.png enc main reconstructed_data.txt sol.py
The main objective is to decrypt the file enc to retrieve an image. By inspecting main, we determined that it applies a Fourier transformation, meaning the encryption likely involves transforming the image into the frequency domain.
After decompiling dados.apk, I checked AndroidManifest.xml
to find the app’s entry point. The <activity> tag with <intent-filter> containing android.intent.action.MAIN and android.intent.category.LAUNCHER revealed that the main activity is:
Flag : .;,;.{we_ought_to_start_storing_our_data_as_dna_instead}
Description
deoxy ribo nucleic acid deoxy meaning without oxygen ribo meaning the 5-carbon sugar backbone nucleic meaning of the nucleus acid meaning proton donor
Solution
Initial Recon
We start by looking at the challenge directory:
➜ dna ls
main.cpython-310.pyc vm.dna
➜ dna
We can see that this is a virtual machine challenge, and the Python code has been compiled with Python 3.10 into a .pyc file ,Before diving into the challenge, let’s take a moment to understand what a virtual machine (VM) is.