Skip to main content

dont-you-love-banners picoCTF 2024 Solution

A general skills challenge involving remote service interaction, authentication, and creative use of system features.

Published: April 3, 2024Updated: August 25, 2026

Description

Can you abuse the banner? The server has been leaking crucial information on tethys.picoctf.net <PORT1_FROM_INSTANCE>. Use the leak to reach the real service on tethys.picoctf.net <PORT2_FROM_INSTANCE>, then abuse the machine and grab the flag from /root.

Two netcat sessions

Connect to tethys.picoctf.net <PORT1_FROM_INSTANCE> to capture the leaked SSH banner.

Use tethys.picoctf.net <PORT2_FROM_INSTANCE> (the real service) for authentication and exploitation.

bash
nc tethys.picoctf.net <PORT1_FROM_INSTANCE>
bash
nc tethys.picoctf.net <PORT2_FROM_INSTANCE>

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
  1. Step 1Harvest the password
    Observation
    The description calls PORT1 a leak endpoint, so the server is probably handing out a credential in its banner before any handshake.
    The leak on port <PORT1_FROM_INSTANCE> prints its SSH banner, exposing the password (e.g., My_Passw@rd_@1234). Save it for the next step.
    bash
    nc tethys.picoctf.net <PORT1_FROM_INSTANCE>
    What didn't work first

    Tried: Running nmap -sV against PORT1 to grab the banner instead of plain netcat

    nmap -sV probes and negotiates versions, which can truncate or suppress the raw banner the server volunteers on connect. Plain netcat prints exactly what arrives, so the password is visible right away.

    Tried: Using curl or a browser to connect to PORT1 expecting an HTTP response

    The leak port speaks raw TCP, not HTTP. curl sends a request and waits for a response that never comes, then times out without showing the banner. netcat just connects and prints whatever arrives.

    Learn more

    A service banner is the initial text a server sends when a client connects - before any authentication occurs. SSH, FTP, SMTP, and many other protocols transmit banners that typically include the software name and version. This information helps clients negotiate compatible protocols, but it also helps attackers fingerprint services and identify exploitable versions.

    Banner grabbing is one of the first steps in network reconnaissance. Tools like netcat, nmap (with -sV), and Shodan collect banners to build a picture of exposed services. The key insight in this challenge is that someone configured the banner to include a credential - a serious misconfiguration that mirrors real-world cases where developers accidentally hardcode secrets in configuration files that end up in banners or error messages.

    In penetration testing, information leakage through banners is a common finding. Beyond passwords, banners can reveal internal hostnames, software versions with known CVEs, and even environment variables. Security hardening guides recommend minimizing banner verbosity - for example, configuring SSH to show only "SSH-2.0" rather than the full OpenSSH version string.

    The OWASP Top 10 lists Security Misconfiguration as a critical vulnerability class. Credentials in banners are an extreme but not unheard-of example - similar to finding database credentials in HTML comments, error messages that expose stack traces, or directory listings that reveal sensitive files.

  2. Step 2Authenticate on the main service
    Observation
    The banner hands over a plaintext password, and the description points at a second port for the real service. Use the credential there.
    Connect to <PORT2_FROM_INSTANCE>, enter the leaked password, and answer the security trivia (DEFCON / John Draper). You'll drop into /home/player with limited rights.
    bash
    nc tethys.picoctf.net <PORT2_FROM_INSTANCE>
    What didn't work first

    Tried: Trying to SSH into PORT2 with the leaked password instead of using netcat

    PORT2 only imitates a login prompt; it is not an SSH daemon. An ssh client fails with a protocol mismatch because nothing there speaks the SSH binary protocol. Connect with netcat and answer the prompts by hand.

    Tried: Reusing PORT1 to authenticate with the leaked password

    PORT1 is a read-only banner leak endpoint that does not accept credentials - it just prints its message and closes. The actual interactive login session lives on PORT2. Sending the password to PORT1 will produce no response or an immediate disconnect.

    Learn more

    Security trivia questions (like the DEFCON and John Draper questions here) are a challenge mechanic simulating knowledge-based authentication - a second factor beyond the password. In the real world, knowledge-based authentication (KBA) like "What was the name of your first pet?" is widely considered weak because answers can often be researched from public information.

    DEFCON is the world's largest underground hacking conference, held annually in Las Vegas. John Draper (a.k.a. Cap'n Crunch) is a legendary phone phreaker who discovered that a toy whistle from Cap'n Crunch cereal produced a 2600 Hz tone that could manipulate AT&T's phone network - a famous early example of exploiting unintended system behaviors. These trivia questions are nods to hacker culture and history.

    Once authenticated, landing in /home/player with limited rights demonstrates the principle of least privilege: even authenticated users should not have root access by default. The challenge requires a privilege escalation step to reach /root/flag.txt, reflecting real-world attack chains where an initial foothold must be leveraged for further access.

  3. Step 3Abuse the banner reader
    Observation
    /home/player/banner sits in a directory you can write to, and a root-owned script reads it on every login. Replace it with a symlink to /root/flag.txt and root reads the flag for you.
    The root-owned script reads /home/player/banner. Replace it with a symlink to /root/flag.txt so the next login displays the flag as the banner.
    bash
    cd /home/player && rm banner && ln -s /root/flag.txt banner
    Reconnect to <PORT2_FROM_INSTANCE>; root prints the flag when it loads the banner.
    What didn't work first

    Tried: Overwriting the banner file with flag content using echo or cat instead of creating a symlink

    The player account cannot read /root/flag.txt, so there is no content to write into the banner in the first place. The symlink is the point: the root-owned script follows it and does the read with root's privileges. Writing the file yourself would mean already knowing the flag.

    Tried: Creating the symlink as ln -s banner /root/flag.txt (arguments reversed) instead of ln -s /root/flag.txt banner

    Swap the arguments and you ask for a symlink at /root/flag.txt pointing back at banner, the opposite of what you want. The form is target first, link name second, so banner is the name and /root/flag.txt is what it points to. Reversed, it either fails on /root permissions or leaves a dangling link.

    Learn more

    A symbolic link (symlink) is a special file that acts as a pointer to another path. When any process reads the symlink, the OS transparently redirects the read to the target. Here, replacing the player-owned banner file with a symlink to /root/flag.txt causes the root-owned banner-reading script to unknowingly read and display the flag.

    This is a symlink attack - a classic privilege escalation technique. It works when: (1) a privileged process reads a file in a location writable by a lower-privileged user, and (2) the process follows symlinks without checking that the target is in a safe location.

    Two complementary mitigations:

    • O_NOFOLLOW on open() refuses to traverse a symlink and returns ELOOP. Cheap, kernel-level, but only blocks the final component.
    • realpath() canonicalizes the target path, expanding every symlink and ... The privileged script then checks the resolved path is inside an allowed prefix (e.g. /var/banners/) before reading. This catches symlinks anywhere in the path, not just the leaf.

    For more on Linux file primitives that bite in CTFs, see the Linux CLI for CTF guide.

    The broader vulnerability class is called TOCTOU (Time Of Check to Time Of Use): the script checks that the banner file exists (the check), then later opens and reads it (the use). Between those two events an attacker can replace the file with a symlink. Narrowing the window does not close it; the reliable fix is to open the path once and inspect the resulting descriptor rather than re-resolving the name.

    Symlink attacks appear regularly in CVEs affecting Linux system services. Notable examples include vulnerabilities in sudo, systemd, and various package managers. Linux ships a direct mitigation for the world-writable-directory case, the fs.protected_symlinks sysctl, which refuses to follow a symlink inside a world-writable sticky directory such as /tmp unless the follower owns the link or the link owner also owns the directory. It does not help here, because /home/player is the player's own directory rather than a shared sticky one, so the privileged reader still has to validate the path itself.

Interactive tools
  • Strings ExtractorPull printable text from any binary, library, or image. ASCII and UTF-16 detection, configurable minimum length, flag-like highlight, no command line needed.
  • Reverse Shell GeneratorGenerate reverse shell payloads (bash, nc, python, perl, ruby, php, node, powershell) and matching listeners. Set host and port once, copy any variant.

Flag

Reveal flag

picoCTF{b4nn3r_gr4bb1n9_su((3sfu11y_8126...}

When the root script renders your symlinked banner, it prints the flag exactly as shown.

Key takeaway

A symlink attack lives in the gap between a privileged process trusting a path and the OS quietly redirecting that path anywhere. When a high-privilege service reads a file a low-privilege user can replace, a link into a protected location escalates access with no password involved. Real CVEs against sudo, systemd, and package managers all follow this shape. The defense is to open with O_NOFOLLOW, or resolve the canonical path and check it stays inside an allowed directory.

Related reading

Useful tools for General Skills

Where to go next