Gatekeeper picoCTF 2026 Solution

Published: March 20, 2026

Description

What's behind the numeric gate? Download gatekeeper, reverse the numeric checks, and enter the one value that passes.

Download the binary and make it executable.

Run it and observe what kind of input it expects.

bash
chmod +x gatekeeper
bash
./gatekeeper
  1. Step 1Run the binary
    Execute gatekeeper and read the prompt. It asks for a number, and internally checks it against a threshold using an unsigned comparison on a signed input.
    bash
    ./gatekeeper
    Learn more

    When approaching an unknown binary, always start by running it with normal input to understand its interface. The program's prompts, error messages, and exit codes give you immediate information about what it expects. In this case the binary asks for a number, which suggests it performs integer comparisons internally.

    If the binary doesn't reveal enough from runtime behaviour, the next steps are static analysis (disassembling with objdump or Ghidra, or reading the source with strings / cat) and dynamic analysis (running under strace to see system calls, or ltrace to see library calls). For this challenge the vulnerability class (integer type confusion) is inferable from the prompt alone and confirmed quickly.

  2. Step 2Send -1 as the input
    The binary uses an unsigned comparison on a signed integer, so -1 wraps to 0xFFFFFFFF when re-read as uint32_t and passes the gate. Replace <PORT_FROM_INSTANCE> with the port shown on the picoCTF instance launch page (next to the host).
    bash
    echo '-1' | ./gatekeeper
    bash
    # Or on the remote instance:
    bash
    echo '-1' | nc <HOST> <PORT_FROM_INSTANCE>
    Learn more

    This is a signed/unsigned integer confusion vulnerability, also called type confusion or an integer signedness bug. In C, -1 stored in a signed 32-bit integer (int) has the bit pattern 0xFFFFFFFF. Reinterpreted as unsigned int, that bit pattern is 4,294,967,295 (all-ones in 32 bits = 232 - 1), the largest unsigned 32-bit value, far greater than any positive number a sane threshold would pick.

    The vulnerable pattern in this binary is essentially: if (input > THRESHOLD) where input was read as a signed int but the comparison promotes both sides to unsigned. Any positive input you try (like 5, 100, or 1000) takes the failing branch because it really is less than THRESHOLD. Only a negative number wraps to something larger than THRESHOLD after the unsigned promotion, and -1 wraps to the maximum.

    Integer signedness bugs appear throughout real-world security vulnerabilities. MITRE CWE-195 (Signed to Unsigned Conversion Error) and CWE-196 (Unsigned to Signed Conversion Error) catalogue this class. Famous examples include the MS04-011 LSASS buffer overflow and vulnerabilities in OpenSSH and PHP's integer handling. Compilers warn about signed/unsigned comparisons with -Wsign-compare; always enable it. For the broader context on integer-class bugs in pwn challenges, see the buffer overflow guide.

  3. Step 3Read the flag
    The gate opens and the binary prints the flag directly.
    Learn more

    Integer type bugs are among the oldest and most pervasive vulnerability classes in C and C++ code. They are particularly dangerous because they often lead to memory corruption (out-of-bounds reads and writes) in addition to logic bypass. A negative array index like buf[-1] accesses memory before the buffer, which often lands in other stack variables or heap metadata.

    Modern defences include compiler sanitisers (-fsanitize=signed-integer-overflow, -fsanitize=unsigned-integer-overflow in Clang), static analysis tools (Coverity, CodeQL), and rigorous code review. Memory-safe languages like Rust eliminate this entire class by making integer overflow a compile-time check (in debug mode) or well-defined wrapping (in release mode with explicit wrapping_add). In Rust you cannot accidentally treat a signed integer as unsigned in a comparison.

Flag

picoCTF{g4t3k33p3r_byp4ss_...}

The gatekeeper checks the input with a signed/unsigned integer mismatch - passing -1 satisfies the unsigned comparison and bypasses the gate.

Want more picoCTF 2026 writeups?

Useful tools for Reverse Engineering

Related reading

What to try next