format string 0

Published: April 3, 2024

Description

Can you use your knowledge of format strings to make the customers happy?

Remote menu

Connect to mimas.picoctf.net <PORT_FROM_INSTANCE> via netcat.

Observe the menu items in each round and look for strings containing %.

nc mimas.picoctf.net <PORT_FROM_INSTANCE>

Solution

This is the introductory format string challenge. Once you understand how format specifiers leak data here, progress to format string 1 for stack leaking and format string 2 for memory overwrites. The Buffer Overflow and Binary Exploitation guide covers format string vulnerabilities in depth alongside stack overflows and heap exploitation.
  1. Step 1Round 1
    Choose Gr%114d_Cheese. The %11 leaks memory instead of printing a literal name, which is the intended foothold.
    Gr%114d_Cheese
    Learn more

    A format string vulnerability occurs when user-controlled input is passed directly as the format string argument to printf() or similar functions. Instead of printf("%s", user_input), the vulnerable code calls printf(user_input). This allows an attacker to inject format specifiers like %d, %s, %p, and %n that cause printf to read from (or write to) the stack.

    The %114d specifier tells printf to print an integer with a minimum field width of 114 characters. Since there's no corresponding integer argument on the stack for this extra specifier, printf reads whatever value happens to be on the stack next - which could be a return address, a pointer, or sensitive data. This is called stack data leakage.

    Format string bugs were extremely prevalent in the late 1990s and early 2000s, leading to high-profile exploits in syslog, wu-ftpd, and many other servers. While modern compilers produce warnings for printf(user_input), the vulnerability still appears in legacy code, embedded systems, and cases where the format string is dynamically constructed.

    The OWASP Testing Guide includes format string testing as part of input validation testing. Fuzzing tools like AFL and libFuzzer can automatically detect format string vulnerabilities by monitoring for crashes or unusual output when format specifiers are injected into inputs.

  2. Step 2Round 2
    Select Cla%sic_Che%s%steak so printf interprets each %s and prints arbitrary stack entries, eventually revealing picoCTF{...}.
    Cla%sic_Che%s%steak
    Learn more

    The %s specifier tells printf to treat the next stack argument as a pointer and print the null-terminated string at that address. When there's no corresponding argument, printf reads the next value off the stack and treats it as a string pointer. If that value happens to point to readable memory containing the flag, it gets printed. If it points to unmapped memory, the program crashes with a SEGFAULT - which explains the flag text SEGFAULT in the flag.

    Chaining multiple %s specifiers (%s%s%s...) walks further up the stack, reading more memory with each specifier. The attacker doesn't need to know the exact stack layout in advance - they can spray many specifiers and observe which one prints useful data. This brute-force approach makes format string bugs practical even without debugging access.

    The specific menu item names in this challenge are cleverly crafted to hide the format specifiers in plain sight. Cla%sic looks like "Classic" with a typo; Che%s%steak resembles "Cheesesteak." This social engineering aspect - making malicious input look benign - is a technique used in real attacks where format strings appear in log entries, usernames, or other inputs that humans might not scrutinize carefully.

Flag

picoCTF{7h3_cu570m3r_15_n3v3r_SEGFAULT_dc...}

Ordering the format-string specials leaks the flag directly in the connection output.

Want more picoCTF 2024 writeups?

Useful tools for Binary Exploitation

Related reading

What to try next