VNE picoCTF 2023 Solution

Published: April 26, 2023

Description

We have a binary that can list directories as root. SSH into the provided server, run the binary named bin, and find a way to read the root flag through it.

SSH into the provided server as ctf-player using the supplied password and port.

Locate the SUID binary named bin in your home directory and run it once to see how it behaves.

bash
ssh ctf-player@saturn.picoctf.net -p <PORT_FROM_INSTANCE>
  1. Step 1Observe default behavior
    Running ./bin with nothing set prints: Error: SECRET_DIR environment variable is not set. The binary uses the SECRET_DIR value as the directory it lists, and it does the listing as root because it is SUID.
    bash
    ./bin
    Learn more

    A SUID binary runs with the privileges of its owner (here, root) regardless of who launches it. This binary lists the contents of whatever directory the SECRET_DIR environment variable points to, but performs that listing with root privileges. The intended use is harmless directory browsing; the bug is in how it constructs the listing command.

    Before crafting anything, run the binary normally to learn which environment variable it reads. The error message names it directly: SECRET_DIR. You can also confirm the SUID bit with ls -l bin (look for an s in the owner permission field).

  2. Step 2List directories as root with SECRET_DIR
    Set SECRET_DIR on the command line. Pointing it at /root shows that the flag file exists there, but a normal cat on it is denied because the file itself is only readable by root.
    bash
    SECRET_DIR=. ./bin
    bash
    SECRET_DIR=/root ./bin
    bash
    cat /root/flag.txt
    The listing of /root reveals flag.txt, but a direct cat /root/flag.txt returns Permission denied because only the binary runs as root, not your shell.
    Learn more

    Supplying SECRET_DIR=/root confirms the flag location, but you still cannot read the file directly. The binary holds the root privilege, your interactive shell does not. The path forward is to make the privileged binary itself read the file rather than just listing the directory.

    This is the classic split that makes these challenges solvable: the privileged process accepts attacker-controlled input (the environment variable) and feeds it into a shell command without sanitizing it.

  3. Step 3Inject a command through SECRET_DIR
    Because the binary passes SECRET_DIR into a shell, you can append your own command with a shell separator. Using & (or ;) chains a cat of the flag that runs as root, printing the flag.
    bash
    SECRET_DIR="/root&cat /root/flag.txt" ./bin
    Learn more

    This is a command injection vulnerability. The binary takes the SECRET_DIR value and interpolates it into a shell command line (something like ls $SECRET_DIR) that runs with root privileges. Because the value is never escaped, a shell metacharacter such as &, ;, or | breaks out of the intended command and lets you run a second one.

    Setting SECRET_DIR="/root&cat /root/flag.txt" makes the binary first list /root, then run cat /root/flag.txt as root, which prints the flag inline with the listing output. The fix in real software is to never build shell commands from untrusted input: pass arguments to execve directly, or strictly validate and quote any value before it reaches a shell.

  4. Step 4Read the flag
    The injected cat prints the flag value alongside the directory listing. Copy it and submit.
    Learn more

    Command injection through an unsanitized environment variable is a real and recurring class of privilege-escalation bug. Whenever a privileged program builds a shell command from data an unprivileged user controls (environment variables, file contents, network input), an attacker can chain arbitrary commands at the elevated privilege level.

Flag

picoCTF{...}

The SECRET_DIR command-injection payload (SECRET_DIR="/root&cat /root/flag.txt" ./bin) prints the flag inline with the directory listing.

Want more picoCTF 2023 writeups?

Useful tools for Binary Exploitation

Related reading

What to try next