Use the tree to jump between collections without leaving the reader.

archive Select writeup Open tree
TaipanBytesChartCTF/WriteupReverseMe.en.md READ_ONLY

Secret (Reversing)

Challenge Data

Field Value
CTF Taipanbyte CTF
Challenge Secret (Reversing)
Category Reversing
File secret.tb
Flag TB{reverse_engineering_is_cool}

Challenge Description

The challenge provided a binary that validated the flag. The program only applied a sequence of transformations around a string that was already embedded inside the executable.


Reconnaissance

The first step was to check what kind of binary it was.

file secret.tb

The result showed a 64 bit ELF, dynamically linked and also not stripped. That already made the job easier because the symbols were still there.

After that, strings and nm already gave several direct hints.

  • Enter flag:
  • Correct! Flag is
  • Wrong flag.
  • TB{reverse_engineering_is_cool}
  • symbols such as main and hex_decode

At that point, checking main was enough to confirm whether there was any real transformation or only an indirect comparison.


Analysis

Looking at main, the flow was roughly this.

  1. It asked for user input.
  2. It loaded the string TB{reverse_engineering_is_cool} from .rodata.
  3. It applied XOR 0x42 character by character.
  4. It converted the result to hexadecimal.
  5. It decoded it back with hex_decode.
  6. It applied XOR 0x42 again.
  7. It compared the final value against the user input.

This whole round trip produced exactly the original string again. The program was not building a hidden flag at runtime. It was only comparing against a value that was already present in cleartext inside the binary.

The constant could be seen directly in .rodata.

xxd -s 0x5010 -l 48 secret.tb
00005010: 666c 6167 3a20 0000 5442 7b72 6576 6572  flag: ..TB{rever
00005020: 7365 5f65 6e67 696e 6565 7269 6e67 5f69  se_engineering_i
00005030: 735f 636f 6f6c 7d00 2530 3278 0043 6f72  s_cool}.%02x.Cor

That showed the string was visible inside the binary.


Solution

The fastest way to solve it was simply to read the string with strings. If we wanted to confirm it, running the program with that exact input was enough.

chmod +x secret.tb
echo 'TB{reverse_engineering_is_cool}' | ./secret.tb

The binary replied with Correct! Flag is TB{reverse_engineering_is_cool}, so that confirmed the correct value.


Flag

TB{reverse_engineering_is_cool}