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
80
hosts awebpage
with a405 Method Not Allowed
in GET, POST, PUT … - Port
8065
is open but does not seem to run anything I know. Connecting to it withnetcat
gives us the responseUbuntu 22.04.3 LTS
and the connection closes immediately - Port
8075
responds with220 Operation successful
which shows than anFTP
server is listening - Port
8085
connects to a remoteVim
session ! We can type commands, open files … (see after) - Port
8095
is the same as8085
but 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
Vim
the file/tmp/ftp/sh
- Save it in
/tmp/sh
with: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 🤡.