caas

Published: April 2, 2026

Description

Now presenting cowsay as a service. Find the flag at caas.mars.picoctf.net.

Remote

The challenge runs at https://caas.mars.picoctf.net -- no download needed.

Try visiting /cowsay/hello in your browser to see the cowsay output.

Solution

  1. Step 1Identify the command injection
    The server runs /usr/games/cowsay followed by the URL path parameter directly in a shell. Because the input is unsanitized, a semicolon appends a second shell command after the cowsay call.
    Learn more

    OS command injection occurs when a web application passes user-controlled data to a shell interpreter without sanitization. The server-side code is likely something like exec('cowsay ' + req.params.message) in Node.js, which hands the entire string to /bin/sh -c. The shell interprets special characters in the user's input as control syntax rather than data.

    The semicolon (;) is a shell command separator -- it tells sh to execute the next command regardless of whether the previous one succeeded. Other injection characters include && (run if previous succeeded), || (run if previous failed), | (pipe output), and backticks or $() for command substitution.

    This is classified as a CWE-78 (Improper Neutralization of Special Elements used in an OS Command) and appears in the OWASP Top 10 under "Injection." The correct fix is to never pass user input to a shell at all -- use language-native APIs (in Node.js: child_process.execFile() with an argument array, which bypasses the shell entirely).

  2. Step 2List files on the server
    Append ;ls to the URL path to run ls after cowsay. This reveals a file called falg.txt -- note the deliberate typo.
    curl "https://caas.mars.picoctf.net/cowsay/hello;ls"
    Learn more

    Enumeration is the process of discovering what resources exist on a target system before trying to access them. Running ls via command injection shows the current working directory's contents -- file names, which point toward where interesting data lives. This is the first step in post-injection reconnaissance.

    The deliberate typo falg.txt (instead of flag.txt) is a common CTF trick: it prevents people from guessing the filename without actually exploiting the vulnerability. It also tests whether solvers actually read the directory listing or just blindly try common filenames.

    In real penetration testing, command injection of this severity is a critical finding. From an ls, a real attacker would escalate to reading /etc/passwd, exfiltrating credentials, establishing persistence, or pivoting to other internal systems. The cowsay wrapper is irrelevant -- it's just the vector through which the shell receives the injection.

  3. Step 3Read the flag file
    Use ;cat with %20 for the space character (URL encoding) to read the flag file.
    curl "https://caas.mars.picoctf.net/cowsay/hello;cat%20falg.txt"
    Learn more

    URL encoding (percent-encoding) represents characters that have special meaning in URLs by replacing them with a % followed by two hexadecimal digits. A space is %20. This is necessary because raw spaces in a URL path are invalid -- browsers and HTTP clients either reject them or encode them automatically. When the server decodes the URL before passing it to the shell, %20 becomes a literal space.

    cat (concatenate) reads and prints file contents to standard output. In a web context, standard output from the injected command is captured and included in the HTTP response -- the server's cowsay output and the flag file contents both appear in the same response body.

    This challenge is named "CaaS" -- Cowsay as a Service -- a playful reference to "Software as a Service (SaaS)." It illustrates how wrapping any command-line tool as a web service without input sanitization is dangerous regardless of how harmless the tool itself is. The same vulnerability would exist if the server ran fortune, figlet, or banner with user input.

Flag

picoCTF{...}

Node.js exec() with unsanitized user input in a shell context allows arbitrary command injection -- semicolons separate commands in bash, so ;cat falg.txt runs as a second shell command.

More Web Exploitation