Pipeline Git
The web root has an exposed .git directory. Commit history shows credentials that were added and then 'deleted' — but git history is forever. Root escalation is sudo cp to create a SUID bash.
Launches calculating…
RatCTF
Release Schedule
8 weeks · 8 new targets · 8 retirements. Every Friday a new machine drops and an old one leaves rotation.
| Week | Date | New Machine | Retiring | Status |
|---|---|---|---|---|
| Week 1 | 9 May | Easy Porthaven | 🔴 Easy Retrogate | ✓ Released |
| Week 2 | 16 May | Medium Glasswork | 🔴 Hard Keyspace | ✓ Released |
| Week 3 | 23 May | Medium Sharehouse | 🔴 Easy Bootleak | ✓ Released |
| Week 4 | 30 May | Medium Irongrep | 🔴 Easy Axferia | ✓ Released |
| Week 5 | 5 Jun | Medium Shapeshifter Special drop | — | ✓ Released |
| Week 6 | 6 Jun | Easy Shellcast | 🔴 Easy Listeria | ✓ Released |
| Week 7 | 13 Jun | Insane Darkpulse Premium | 🔴 Medium Postmark | ✓ Released |
| Week 8 | 20 Jun | Medium Foxhole | 🔴 Medium Rootbase | ✓ Released |
| Week 9 | 27 Jun This week | Hard Tracewire Premium | 🔴 Medium Driftsync | 🟢 Live now |
Themed Series
Launching Soon
The web root has an exposed .git directory. Commit history shows credentials that were added and then 'deleted' — but git history is forever. Root escalation is sudo cp to create a SUID bash.
Launches calculating…
Two credential leaks in one host: Flask /health dumps os.environ as JSON, and nginx serves the .env file directly. SSH password is in both. Node GTFObins gives root.
Launches calculating…
A Flask stub mimicking a Docker registry serves unauthenticated /v2/_catalog and layer endpoints. An image layer's ENV instruction contains SSH credentials. A world-writable cron script gives root.
Launches calculating…
An artifact server exposes backup.tar.gz which contains a build environment including an SSH private key. SUID python3 (chmod 4755) allows direct root escalation.
Launches calculating…
A Jenkins-simulating Flask app with default admin:admin credentials. The /ci/execute endpoint runs shell commands as www-data. Sudo docker with volume mount gives a clean host filesystem escape.
Launches calculating…
Classic BOLA/IDOR on a user API. GET /api/v1/users/2 returns the admin object which includes an ssh_password field. Root is sudo ruby GTFObins.
Launches calculating…
Mass assignment vulnerability on the profile update endpoint. Adding role=admin to the PUT request body grants admin status, which unlocks an admin panel exposing SSH credentials. Root via sudo perl.
Launches calculating…
JWT authentication with HS256 using secret='secret'. The alg:none attack is also accepted. Forge an admin JWT to access protected routes that expose SSH credentials. cap_setuid python3 for root.
Launches calculating…
Broken Function Level Authorization — admin routes return 403 to regular users. Adding X-Internal-Request: true header bypasses the check. The admin route exposes SSH credentials. Root via world-writable /etc/cron.d/.
Launches calculating…
POST /api/v1/fetch makes outbound HTTP requests with user-supplied URLs. SSRF against localhost:8080/internal/dump returns an SSH private key. SUID /usr/bin/curl can read local files via file://.
Launches calculating…
Session tokens are generated as MD5(username + epoch//60). Within the same 60-second window you can predict the admin token and impersonate admin to extract SSH credentials. Root via sudo python3.
Launches calculating…
HS256 JWT with secret 'password123' — crackable with hashcat mode 16500 and rockyou.txt. Forge a token with role:admin to unlock the admin panel which exposes SSH credentials. Root via sudo ruby.
Launches calculating…
SHA1 HMAC with a known secret='secret'. Hash length extension attack using hlextend or hashpumpy appends admin=1 to a signed message, granting admin access and exposing SSH credentials. cap_setuid python3 for root.
Launches calculating…
AES-CBC encrypted session cookie. The /check endpoint returns HTTP 400 for bad padding vs 403 for valid padding — a classic padding oracle. Decrypt and re-encrypt a forged admin cookie for SSH credential access. SUID find for root.
Launches calculating…
512-bit RSA public key served at /pubkey. Factor the modulus using msieve or yafu (feasible under a minute for 512-bit), reconstruct the private key, and decrypt the /challenge ciphertext for SSH credentials. World-writable cron gives root.
Launches calculating…
python3 has cap_dac_read_search, which bypasses all filesystem permission checks. The user flag is readable normally; the root flag requires using the capability to open /root/root.txt directly.
Launches calculating…
Flask /debug/env leaks environment variables including SSH_PASS. The container has SYS_PTRACE capability and the root flag is stored in PID 1's environment — readable via /proc/1/environ.
Launches calculating…
A simulated hostPath bind mount exposes /hostpath/etc/cron.d/ as world-writable. A copy-cron helper script runs files dropped there as root, simulating the real-world Kubernetes hostPath escape pattern.
Launches calculating…
The user is in the docker group and /var/run/docker.sock is mounted into the container. Classic Docker socket escape via privileged container with host root mounted gives full host filesystem access.
Launches calculating…
SYS_ADMIN capability is present. The classic cgroups v1 notify_on_release escape uses the release_agent file to execute a command as root on the host when a cgroup empties. Writes the root flag to /tmp.
Launches calculating…
32-bit SUID binary with no protections (no canary, no NX, no PIE). A gets() call overflows the stack. win() at a fixed address gives a root shell when the return address is overwritten.
Launches calculating…
32-bit SUID binary compiled with execstack and ASLR disabled. The binary prints the buffer address before reading input. Inject shellcode and overwrite the return address with the leaked buffer address.
Launches calculating…
32-bit SUID binary with NX enabled (no shellcode). The system() address, /bin/sh string address, and exit() address are provided in hints.txt for a clean ret2libc chain.
Launches calculating…
32-bit SUID binary calling printf(user_input) without a format string. Use %p/%x to leak stack values and locate a GOT entry address, then use %n to overwrite a GOT function pointer to redirect execution to win().
Launches calculating…
32-bit SUID binary with a use-after-free vulnerability. A struct with a function pointer is freed and then reallocated. Control the reallocation to overwrite the function pointer and redirect execution to win().
Launches calculating…
Every HTTP response includes an X-Debug-Pass header containing the SSH password in plaintext. A single curl -I reveals the credential. Root via sudo python3.
Launches calculating…
robots.txt disallows /backup/config.bak. That file contains plaintext SSH credentials. Root via sudo ruby GTFObins.
Launches calculating…
A report.docx is available for download. EXIF/document metadata contains a description field with ssh_temp_pass:user123. cap_setuid python3 for root escalation.
Launches calculating…
Flask /logs endpoint returns the application log file. A DEBUG entry shows ssh_auth user=devops pass=DevPass2026!. /etc/passwd is world-writable for root escalation.
Launches calculating…
A hidden CSV export endpoint is protected by Referer header check. Combined with an X-Internal-Hostname header discovery, the exported CSV contains SSH credentials. Root via sudo awk GTFObins.
Launches calculating…
Leaving Rotation
Every enterprise has a directory. Bindforge's directory holds the full map of who has access to what — accounts, groups, and a few fields that the original engineer populated a little too liberally. It was only ever meant to be accessed from inside the building.
Retires calculating…
Neuravex is CorpTech's shiny new internal AI assistant. The engineers shipped it fast, the executives loved it, and nobody asked too many questions about how it was built. It knows a lot. It's happy to talk. The question is how to make it tell you the right things.
Retires calculating…
Relay is a beginner-friendly pivot box: ten user accounts, ten flags, one flag per user. You are handed the first account — SSH in directly as relay01 with password R3lay_St4rt_01 (no exploit needed to land the first user), grab the flag, and find the clue each user leaves behind for the next. Walk the chain relay01 → relay02 → … → relay10. NOTE: there is NO root on this machine and no privilege-escalation path. The whole challenge is lateral movement between users — do not waste time hunting for root.
Retires calculating…
The employee portal was built by a contractor in 2019, accepted without a security review, and has been quietly running ever since. It handles timesheets, leave requests, and a few internal tools nobody fully remembers adding. The codebase has never been audited.
Retires calculating…
The binary on this machine is old. Older than most of the team. It was compiled once, deployed, and forgotten — a relic of infrastructure debt that nobody wanted to touch. It still runs as root. It always has.
Retires calculating…
The SolarGate incident team flagged unusual activity on prod-web-01. A file-upload vulnerability gave an attacker a foothold as www-data, and the logs show things escalated from there. Your job: step into the analyst's seat, reconstruct what happened, and finish the job the attacker started.
Retires calculating…