# 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 `:1301`. ```bash $ nc 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 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.