Files
HIP7CTF_Writeups/false_flags.md
m0rph3us1987 a79656b647 Added writeups
2026-03-08 12:22:39 +01:00

116 lines
3.9 KiB
Markdown

# False Flags
`falseFlags` is a beginner-friendly reverse engineering challenge. We are given a binary that contains multiple "fake" flags, and our goal is to identify the correct one.
## 1. Initial Analysis
We start by examining the file type and basic properties.
```bash
$ file false_flags
false_flags: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=..., for GNU/Linux 3.2.0, stripped
```
It's a standard 64-bit ELF executable. Let's try running it. The challenge is also available remotely at `<SERVER_IP>:1301`.
```bash
$ nc <SERVER_IP> 1301
=== The Vault of Falsehoods ===
There are many keys, but only one opens the door.
Enter the password: test
[-] Wrong! That was merely a decoy.
```
Since the description mentions "hiding passwords in the binary", the `strings` command is a good first step to see what's inside.
```bash
$ strings false_flags | grep flag
{flag:This_Is_Definitely_Not_It}
{flag:Try_Harder_To_Find_The_Key}
{flag:Strings_Are_Misleading_You}
...
{flag:Reverse_Engineering_Is_Cool}
...
```
We see a long list of potential flags. We could try them one by one, but that's tedious (and "brute-force" isn't the elegant way!). We need to find out *which* specific string the program compares our input against.
## 2. Static Analysis
We can analyze the binary using `objdump` to look at the assembly code. Since the binary is stripped, we won't see function names like `main`. However, we can find the entry point.
```bash
$ readelf -h false_flags | grep "Entry point"
Entry point address: 0x4019f0
```
The entry point is at `0x4019f0`. If we disassemble at this address, we'll see the startup code (`_start`), which calls `__libc_start_main`. The first argument to `__libc_start_main` is the address of `main`.
```bash
$ objdump -d -M intel --start-address=0x4019f0 --stop-address=0x401a20 false_flags
00000000004019f0 <.text+0x830>:
...
401a08: 48 c7 c7 52 1b 40 00 mov rdi,0x401b52 <-- Address of main
401a0f: 67 e8 5b 15 00 00 addr32 call 0x402f70 <-- Call to __libc_start_main
...
```
So `main` is located at `0x401b52`. Let's disassemble it.
```bash
$ objdump -d -M intel --start-address=0x401b52 --stop-address=0x401c50 false_flags
```
In the output, we see a call early in the function:
```assembly
401ba0: e8 70 ff ff ff call 0x401b15
401ba5: 89 85 6c ff ff ff mov DWORD PTR [rbp-0x94],eax
```
The return value (in `eax`) is stored in `[rbp-0x94]`. This variable is later used to access an array. Let's look at what `0x401b15` does.
```bash
$ objdump -d -M intel --start-address=0x401b15 --stop-address=0x401b52 false_flags
0000000000401b15 <.text+0x955>:
...
401b4b: b8 0c 00 00 00 mov eax,0xc
401b50: 5d pop rbp
401b51: c3 ret
```
Despite some loop logic before it, the function ultimately returns `0xc` (decimal 12). This index is used to select the correct flag from the array of strings we saw earlier.
## 3. The Solution
Now we simply need to find the string at index 12 (counting from 0) in the list we found earlier.
0. {flag:This_Is_Definitely_Not_It}
1. {flag:Try_Harder_To_Find_The_Key}
2. {flag:Strings_Are_Misleading_You}
...
10. {flag:Do_Not_Trust_Simple_Strings}
11. {flag:Index_Twelve_Is_Not_Real_11}
12. {flag:Reverse_Engineering_Is_Cool}
The string at index 12 is:
`{flag:Reverse_Engineering_Is_Cool}`
Let's verify by connecting to the remote server:
```bash
$ nc <SERVER_IP> 1301
=== The Vault of Falsehoods ===
There are many keys, but only one opens the door.
Enter the password: {flag:Reverse_Engineering_Is_Cool}
[+] Correct! Access Granted.
[*] The flag is indeed: {flag:Reverse_Engineering_Is_Cool}
```
## Conclusion
This challenge demonstrates that while `strings` can reveal interesting data, understanding the *logic* (Control Flow) of the program is often necessary to distinguish useful data from decoys.