Credential Stuffing picoCTF 2026 Solution

Published: March 20, 2026

Description

Credential stuffing is the automated injection of stolen username and password pairs into website login forms, in order to fraudulently gain access to user accounts. Download the credentials dump creds-dump.txt .

Download creds-dump.txt - it contains username:password pairs from a data breach.

Launch the challenge instance and note the login endpoint.

bash
wc -l creds-dump.txt
bash
head creds-dump.txt
  1. Step 1Inspect the credentials dump
    The dump format is one credential per line, colon-delimited: username:password. Open the login page in DevTools first and check the Network tab to confirm the form field names (username vs user vs email) before scripting.
    bash
    head -20 creds-dump.txt
    Learn more

    Credential stuffing is a cyberattack where stolen username/password pairs from one data breach are tested against other services. It works because a large fraction of users reuse passwords across multiple sites. Major breaches - RockYou (2009), LinkedIn (2012), Collection #1 (2019) - have exposed billions of credentials, creating a vast corpus that attackers maintain and trade.

    The username:password format (colon-separated) is the most common dump format. Some dumps use tabs, semicolons, or JSON. The wc -l command counts lines to understand the scale. For a real credential stuffing attack, a typical dump contains millions of entries - but for this challenge the dump is small enough to iterate through quickly.

    HaveIBeenPwned's Pwned Passwords API is the canonical defensive tool here, and it uses a clever trick called k-anonymity: instead of sending the password to the API, the client computes SHA-1(password), sends only the first 5 hex characters of that hash to https://api.pwnedpasswords.com/range/{prefix}, and receives back every leaked hash that starts with that prefix (roughly 500-800 hashes per prefix). The client then compares the rest of the hash locally. The full password and full hash never leave the user's machine.

    From a defensive perspective, services layer rate limiting, CAPTCHA, IP reputation checks, multi-factor authentication, and breach-password rejection at signup. See the Web Challenges and Real-World Bug Patterns post for adjacent auth bugs and the Hash Cracking for CTF post for the offensive side of password hashing.

  2. Step 2Automate credential stuffing
    Write a multi-threaded script to try each credential pair against the login endpoint until one succeeds.
    python
    python3 << 'EOF'
    import requests
    from concurrent.futures import ThreadPoolExecutor
    
    URL = "http://HOST:PORT/login"
    creds = [line.strip().split(":", 1) for line in open("creds-dump.txt") if ":" in line]
    
    def try_cred(pair):
        username, password = pair
        r = requests.post(URL, data={"username": username, "password": password}, timeout=5)
        if "picoCTF" in r.text or "Welcome" in r.text:
            print(f"Valid: {username}:{password}")
            print(r.text)
            return True
        return False
    
    with ThreadPoolExecutor(max_workers=20) as ex:
        for result in ex.map(try_cred, creds):
            if result:
                break
    EOF
    Learn more

    ThreadPoolExecutor from Python's concurrent.futures module manages a pool of worker threads. With max_workers=20, up to 20 HTTP requests can be in-flight simultaneously, reducing total time from (n * request_time) to roughly (n/20 * request_time). For network I/O that spends most time waiting for server responses, threading provides near-linear speedup up to the server's concurrency limit.

    The .split(":", 1) with the maxsplit argument of 1 is important: passwords can contain colons, so splitting on the first colon only produces exactly two parts - username and password. Without the maxsplit, a password like p4ss:w0rd would incorrectly split into three parts.

    Real credential stuffing tools like Sentry MBA or Openbullet are used by attackers and add features like proxy rotation (to bypass IP-based rate limiting), CAPTCHA solving services, custom response parsing, and result categorization. This challenge simulates a simplified version of exactly what these tools do - understanding the attack helps defenders design appropriate countermeasures.

Flag

picoCTF{cr3d_stuf_succ3ss_...}

One credential pair in the dump is valid for the service - multi-threaded stuffing finds it quickly.

How to prevent this

You cannot stop attackers from having leaked credentials. You can stop those credentials from working on your service.

  • Check every signup and password change against HaveIBeenPwned's Pwned Passwords API (k-anonymous, 5-char hash prefix). Reject anything in known breach corpora; force a reset on existing accounts that match.
  • Require MFA on every account, ideally TOTP/WebAuthn rather than SMS. Stuffing attacks succeed at ~0.1-2% rates against password-only logins; MFA drops effective success below 0.01%.
  • Detect stuffing patterns: many accounts hit from one IP/ASN, low success rate, distinct user-agents per attempt. Trigger CAPTCHA or step-up auth on anomalies. Cloudflare Turnstile, hCaptcha, and Vercel BotID handle this off the shelf.

Want more picoCTF 2026 writeups?

Useful tools for Web Exploitation

Related reading

What to try next