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

4.3 KiB

False Flags

falseFlags ist eine einsteigerfreundliche Reverse-Engineering-Challenge. Wir erhalten eine Binärdatei, die mehrere "falsche" Flaggen enthält, und unser Ziel ist es, die richtige zu identifizieren.

1. Erste Analyse

Wir beginnen mit der Untersuchung des Dateityps und der grundlegenden Eigenschaften.

$ 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

Es ist eine Standard-64-Bit-ELF-ausführbare Datei. Versuchen wir, sie auszuführen. Die Challenge ist auch remote verfügbar unter <SERVER_IP>:1301.

$ 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.

Da die Beschreibung "versteckte Passwörter in der Binärdatei" erwähnt, ist der strings-Befehl ein guter erster Schritt, um zu sehen, was drin ist.

$ 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}
...

Wir sehen eine lange Liste potenzieller Flaggen. Wir könnten sie eine nach der anderen ausprobieren, aber das ist mühsam (und "Brute-Force" ist nicht der elegante Weg!). Wir müssen herausfinden, mit welchem spezifischen String das Programm unsere Eingabe vergleicht.

2. Statische Analyse

Wir können die Binärdatei mit objdump analysieren, um uns den Assembler-Code anzusehen. Da die Binärdatei "stripped" ist, sehen wir keine Funktionsnamen wie main. Wir können jedoch den Einsprungpunkt finden.

$ readelf -h false_flags | grep "Entry point"
  Entry point address:               0x4019f0

Der Einsprungpunkt ist bei 0x4019f0. Wenn wir an dieser Adresse disassemblieren, sehen wir den Startcode (_start), der __libc_start_main aufruft. Das erste Argument für __libc_start_main ist die Adresse von main.

$ 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  <-- Adresse von main
  401a0f:       67 e8 5b 15 00 00       addr32 call 0x402f70 <-- Aufruf von __libc_start_main
  ...

Also befindet sich main bei 0x401b52. Disassemblieren wir sie.

$ objdump -d -M intel --start-address=0x401b52 --stop-address=0x401c50 false_flags

In der Ausgabe sehen wir früh in der Funktion einen Aufruf:

  401ba0:       e8 70 ff ff ff          call   0x401b15
  401ba5:       89 85 6c ff ff ff       mov    DWORD PTR [rbp-0x94],eax

Der Rückgabewert (in eax) wird in [rbp-0x94] gespeichert. Diese Variable wird später verwendet, um auf ein Array zuzugreifen. Schauen wir uns an, was 0x401b15 tut.

$ 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

Trotz einiger Schleifenlogik davor gibt die Funktion letztendlich 0xc (dezimal 12) zurück. Dieser Index wird verwendet, um die richtige Flagge aus dem Array von Strings auszuwählen, die wir früher gesehen haben.

3. Die Lösung

Jetzt müssen wir einfach den String am Index 12 (beginnend bei 0) in der Liste finden, die wir früher gefunden haben.

  1. {flag:This_Is_Definitely_Not_It}
  2. {flag:Try_Harder_To_Find_The_Key}
  3. {flag:Strings_Are_Misleading_You} ...
  4. {flag:Do_Not_Trust_Simple_Strings}
  5. {flag:Index_Twelve_Is_Not_Real_11}
  6. {flag:Reverse_Engineering_Is_Cool}

Der String bei Index 12 ist: {flag:Reverse_Engineering_Is_Cool}

Überprüfen wir dies, indem wir uns mit dem Remote-Server verbinden:

$ 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}

Fazit

Diese Challenge zeigt, dass strings zwar interessante Daten offenbaren kann, das Verständnis der Logik (Kontrollfluss) des Programms jedoch oft notwendig ist, um nützliche Daten von Täuschungen zu unterscheiden.