Picker I

Published: March 5, 2024

Description

This supposedly random-number service exposes helper functions inside its Python source. If you can trigger win(), it prints the flag instead of a number.

Remote Python serviceDownload picker-I.py

Grab the Python source so you can see helper functions like getRandomNumber() and win().

Test it locally with python3 to understand which identifiers the service accepts.

wget https://artifacts.picoctf.net/c/515/picker-I.py
python3 picker-I.py

Solution

  1. Step 1Identify callable functions
    The script reads a string and passes it into eval-style logic. Typing getRandomNumber returns 4 exactly as the code shows, so calling win should trigger the flag routine.
    Learn more

    Code review is always the first step when source code is available. Reading picker-I.py reveals the program's logic: it accepts a function name as input, looks up that name in its namespace, and calls it. This is a form of dynamic dispatch - the program decides at runtime which function to execute based on user input.

    The win() function is a backdoor left intentionally in the code for CTF purposes, but it mirrors a real vulnerability class. In production systems, developers sometimes leave debug functions, admin backdoors, or test endpoints in deployed code without realizing they are accessible. Auditing code for unintended callable functions is part of standard security review.

    The hint that getRandomNumber() returns 4 is a reference to the famous xkcdcomic about "random" numbers chosen by fair dice roll - chosen by a human rather than being truly random. The joke underscores a real principle: functions named "getRandomNumber" may not be cryptographically secure, and relying on predictable "random" values for security decisions (session tokens, CSRF tokens, one-time passwords) is a significant vulnerability.

  2. Step 2Call win on the remote service
    Connect to the deployed instance with netcat and send win. The program prints the flag as a sequence of hex bytes instead of ASCII.
    printf "win\n" | nc saturn.picoctf.net 51291
    Learn more

    Netcat (nc) is a networking utility that reads from standard input and sends it over a TCP or UDP connection, printing whatever the server responds. It is called the "Swiss Army knife of networking" because it can act as a client, server, port scanner, or data relay. In CTF exploitation, piping a Python payload into netcat (python3 -c '...' | nc host port) is the standard way to send crafted input to a remote service.

    The printf "win\n" command sends the string win followed by a newline character (\n). The newline is important - most line-oriented network services (including this Python script) wait for a newline to know the user has finished their input. Without the newline, the server might wait indefinitely for more input instead of processing the command.

    The fact that the flag is printed as hex bytes rather than ASCII is an intentional design choice in the Picker series: it adds a small extra step (hex decoding) to prevent the flag from appearing directly in plain text. This mirrors real scenarios where sensitive output is encoded to prevent casual interception, though proper protection requires encryption rather than simple encoding.

  3. Step 3Convert from hex
    Copy the 0x-prefixed values into CyberChef (From Hex) or pipe them through xxd -r -p locally to reveal the picoCTF flag.
    Learn more

    CyberChefis a web-based tool developed by GCHQ that chains data transformation operations ("recipes"). The "From Hex" operation accepts space-separated or 0x-prefixed hex values and produces the decoded bytes. CyberChef is particularly useful when you need to apply multiple transformations in sequence (e.g., From Hex, then Base64 Decode, then XOR) without writing code.

    For command-line decoding, xxd -r -p (reverse, plain) reads hex digits and outputs the corresponding bytes. The slight complication here is the 0x prefix on each byte - you would need to strip those before piping into xxd, or use Python: bytes.fromhex("70 69 63 6f".replace(" ", "")).

    The Picker series (I through IV) is designed as a progressive introduction to code injection and binary exploitation. Each version adds restrictions that require a more sophisticated bypass. Understanding each level's mechanism - and why its defenses fail - builds the mental model needed for real vulnerability research where defenses are layered and imperfect.

Flag

picoCTF{4_d14m0nd_1n_7h3_r0u...5d5b}

The remote program never validates user input beyond evaluating tokens, so calling win outputs the flag immediately.

Want more picoGym Exclusive writeups?

Useful tools for Reverse Engineering

Related reading

What to try next