TryHackMe's Advent of Cyber 2023 - Side Quest 3 - Frosteau Busy with Vim - Writeup
ï—¬ 2023-12-16
Hiya ! Time for the Side Quest 3 writeup ! This challenge is named Frosteau Busy with Vim and is rated insane. If you want to skip the part where I explain how to get the QR code, click here.
Link to the challenge : https://tryhackme.com/room/busyvimfrosteau
Link to the meta-article about the side quests : https://eyexion.fr/posts/thm_aoc_2023_meta/
Crop away the secret (or don’t)
The QR code was hidden in the day 11 of the Advent of Cyber. After using a misconfigured Active Directory and abuse the rights of a user to access the Adaministrator's data, we were left with a file chatlog.html and a directory chatlog-files leading us to have the following page :

So we can see that we have in our hands a cropped image from the Snip & Sketch tool in Windows 10. Now, I was lucky to already have encountered this sort of challenge in a CTF, so I directly knew what to do.
Earlier this year, a vulnerability called Acropalypse allowed anyone to go back to the un-cropped image if it was cropped using various tools, including the Snip & Sketch in Windows 10. What these tools did was only add an IEND field in the middle of the data of png file, leaving the rest of the image data as is.
It is thus possible to revert the cropping using various tools including https://acropalypse.app/. Unofortunalty (and it was the same with the previous challenge), this website did not function. I used https://github.com/frankthetank-music/Acropalypse-Multi-Tool instead. This gives us the following result with the format 2560x1080 based on the second screenshot in the files :

We get the QR code ! Really fun idea by the way, and cool way to use recent vulnerabilities !
Statement (of the Side Quest)
The actual challenge gives us the objective to ice Frosteau's machine 🧊, nothing more. During the challenge, an unintended solution was found and fixed, and a hint was given for us to find the third flag. There were 4 + 1 flags to find without any indications, but the challenge “flowed” and the flags were in “classic” locations, only needed to reach them somehow !
Network scan and services
A simple SYN scan gave us the following result :
└─$ sudo nmap -sS -p1-65365 10.10.20.11
[sudo] password for kali:
Starting Nmap 7.94SVN ( https://nmap.org ) at 2023-12-17 16:03 EST
Nmap scan report for 10.10.20.11
Host is up (0.034s latency).
Not shown: 65359 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
8065/tcp open unknown
8075/tcp open unknown
8085/tcp open unknown
8095/tcp open unknown
So as we can see, we have a lot of ports open, trying to connect to each of them gives us the following results
- Port
80hosts awebpagewith a405 Method Not Allowedin GET, POST, PUT … - Port
8065is open but does not seem to run anything I know. Connecting to it withnetcatgives us the responseUbuntu 22.04.3 LTSand the connection closes immediately - Port
8075responds with220 Operation successfulwhich shows than anFTPserver is listening - Port
8085connects to a remoteVimsession ! We can type commands, open files … (see after) - Port
8095is the same as8085but forNano(they needed to please everyone !)
So a lot of things, but we like that 🎉.
Flags To Pocket (FTP)
Ok, so first thing we try is to connect to the FTP server anonymously and, well it works ! So we get this :
└─$ ftp 10.10.20.11 -P 8075 -a -v
Connected to 10.10.20.11.
220 Operation successful
230 Operation successful
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 Operation successful
150 Directory listing
total 8132
-rw-r--r-- 1 0 0 3010 Nov 5 18:49 FROST-2247-SP.txt
-rw-r--r-- 1 0 0 3211 Nov 5 18:50 YETI-1125-SP.txt
-rw-r--r-- 1 0 0 24 Nov 5 19:06 flag-1-of-4.txt
-rw-r--r-- 1 0 0 12 Nov 5 19:07 flag-2-of-4.sh
-rw-r--r-- 1 0 0 2127524 Nov 5 18:54 frostling_base.png
-rw-r--r-- 1 0 0 2305908 Nov 5 18:54 frostling_five.png
-rw-r--r-- 1 0 0 1589463 Nov 5 18:54 yeti_footage.png
-rw-r--r-- 1 0 0 2277409 Nov 5 18:54 yeti_mugshot.png
226 Operation successful
ftp> get flag-1-of-4.txt
local: flag-1-of-4.txt remote: flag-1-of-4.txt
200 Operation successful
So we get the first flag ! And we have a curious looking second flag containing a bash script with only echo $FLAG2 inside, so an environment variable.
Anyway, we can also upload files in the directory with FTP, that will come in handy later.
Vim > all
Now back to Vim. We can connect to the Vim session using netcat. We then need to be able to send our signals (escape, Ctrl-c,…) to the remote machine. To do that, we only need to put the process in background (Ctrl-z) and execute stty raw -echo; fg. We can now do whatever we want !
So the first thing we try is using shell commands like :!id but very quickly we notice that we do not have a working shell executable ! The default $SHELL variable is set to /tmp/sh. Trying to set it to /bin/sh & co does not function. Nonetheless, we can still explore the file system with :e / and see what we’re dealing with.
Quickly we see that we are in a Docker container (presence of /.dockerenv). We also have access to a lot of directories, but nothing interesting to open. But as we explore, we can notice a file /etc/busybox which is a known shell executable embedding a lot of common commands directly in it (used in Docker a lot). But do not have the right to execute it (nor see it).
In the Vim instance we can use the :py3 command to run python commands too. It did not help me solve this challenge, but maybe it had a use. Also, we notice that the FTP root directory is located in /tmp/ftp.
Uploading a shell to the machine
So this is where the hint from the third flag comes in handy. We can indeed upload to the machine a busybox executable, and use it ! But we have one problem. busybox does not support the -c and vim uses the $SHELL -c <cmd> format when using a command with :!. So I could not just upload the busybox executable and run it. So I did a very messy and disgusting thing but hey it worked. There was probably a way to use python or even nano but hey I found this randomly.
So basically I uploaded my own /bin/sh from my VM (same architecture) knowing that I would not get anything but I only wanted a way to execute busybox afterwards (using :py3 could have probably done the job as well). After uploading my /bin/sh via FTP, I did the following
- Open in
Vimthe file/tmp/ftp/sh - Save it in
/tmp/shwith:w /tmp/sh - Set it executable with
:call setfperm("/tmp/sh","rwxrwxrwx") - Run
:!/tmp/sh
And I have a “SHELL”, with almost no commands but that is enough. (I have the really basic ones like cd or pwd, built-in commands). I can also check out the second flag with $FLAG2 in the shell.
Now, I can perform the same steps but uploading a busybox standalone executable ! So using https://busybox.net/downloads/binaries/1.35.0-x86_64-linux-musl/busybox I get a usable busybox executable. So upload, save in /tmp/busybox, set executable and run /tmp/busybox ash in the previous shell we opened and we have a decent shell !

As you can see, we need to add the prefix busybox before all commands but it works.
Privilege escalation in the container
So now the challenge becomes more classic. After looking around a little bit, we see a juicy process running as root :

So that explains the weird stuff we had on port 8065 before ! So now all we have to do is move the file /tmp/busybox we have to /usr/frosty/sh and connect to port 8065 of the machine, we should be root in the container. Because it’s fun you get a GIF.

We can get the third flag in /root after that in the root shell.
Docker escape 101
So now onto the easiest part of the challenge IMO. The natural next step after being root in a Docker container is to try and escape from it to access the host's rootfs.
In my case the first thing I check are mountable devices, it is not uncommon in “easy” Docker challenges to be able to mount the hosts rootfs. After checking the /dev directory, we can see the juicy looking /dev/root device. So of course I try to mount it, and to my surprise I got into the host’s rootfs. Here is a GIF to sum it up. But basically you only need to mount /dev/root and access the flags in /tmp/mount/root if your mount point is /tmp/mount.

Et voilà , you even get a 2 flags for 1 deal.
Conclusion
So overall an original first part of the challenge, I personally found it not too hard and rather “classic” with some twists. I did not use the website running on port 80 nor the nano service, there are probably other ways to get the flags I guess. But overall enjoyable, curious to read other writeups on this one.
Side note, I really think my way of solving it is disgusting with the /bin/sh, there has to be a more elegant way to do it but was proud to find something randomly so 🤡.