Frank & Herby make an app | Writeup | TryHackMe
Join me in this writeup on solving this TryHackMe room called Frank & Herby make an app which involves poor configuration of MicroK8s containers and escalating to root.
For the actual writeup, click here to skip through me dumping my inner thoughts.
Foreword
In case anyone has wondered why I am so infrequent with these writeups, I have been pretty inactive on TryHackMe for the past year with me finally graduating and then getting a job (which is kind of fun but makes me just want to do nothing during my free time.)
I only came upon this room because I have been researching and reading up on containers, microservices, Kubernetes and the like and stumbled upon this release from the creator through their LinkedIn feed post.
Writeup
For this particular room, you would need some basic knowledge of how Kubernetes work, and the typical enumeration methods along with some average Linux knowledge.
The room can be found over on TryHackMe. If you are a free user, you might want to increase the time available on the machine after you start it and get a cup of coffee before coming back in 15-20 minutes.
Task 1: Frank & Herb Make an App!
The question begins with asking us what port with a web application listening is open on the machine. Easy
Running rustscan
on the machine IP, we get a list of open ports.
If you look carefully there is only one port that fits what we need. Alternatively you can visit each of them in the browser until you find the one that connects 😈
One question done, now we can visit the URL and get a template sample website. We can use dirsearch
to see what other directories are there (Also our next question)
That was quick, you can view the file whichever way you like. This is another reason why you should always double check or even use an automated tool to scan through your repos/images for secrets before you commit and push them somewhere public.
The format of the file is : <scheme><username>:<password>@<ip>
in case you are lost
Now you might be tempted to try the credentials into one of the other exposed website for Rocket Chat, unfortunately that seems to be red herring and it will not work (other than the fact that you need to URL decode the password portion from the file. YES. Homework for you)
SSH
Now we have nothing much to do except using the credentials for SSH. I will be using pwncat
which you can find at GitHub.
You might be thinking: "I'll be frank, it has been easy so far." Well until here it has been a smooth trip, but what happens next depends on how much container orchestration or Google prowess you have.
Since we are already in as frank, we can list the files and sadly, the user flag is right there for the picking.
Now we have to get the root flag somehow. You may try to run sudo -l
to see what frank can run as sudo
with, unfortunately, frank is neither in the sudoers file nor the sudo
group.
Well, the hint is pretty much the image of the room. There is microk8s
on the machine used to deploy the app we got the secret credentials from earlier.
You can list all the relevant deployments, pods etc. with microk8s kubectl get all
Exploring around a little, we find a ~/repos/dk-ml
folder which contains the resources as well as the Kubernetes deployment file
If we take a look at the test.yaml
file, the image for Nginx is pulled locally from localhost:32000
For the way forward, you need to realize that we can create deployments. If you do a quick Google for microk8s escalate to root
or a similar query, chances are you would have seen a link to MICROK8S - PRIVILEGE ESCALATION (CVE-2019-15789) which in a nutshell allows a low privilege user who can create deployments to escalate themselves as root.
You can read through the POC in the link above, however in the POC, there is a need for internet connection to pull the image used. This is not an issue as we can simply reuse the existing deployment file with some minor changes as can be seen below
You can either delete the existing deployment to hopefully save some resources if your instance is lagging and slow with :microk8s kubectl delete deploy nginx-deployment
or you can just create the deployment using :microk8s kubectl apply -f exp.yaml
Run microk8s kubectl get pod
periodically until you see the pod for our deployment. And then you can get a TTY input to a bash shell with microk8s kubectl exec -it <pod_name_from_prev_command> /bin/bash
We can then add frank to the sudoers
file.
You might be thinking, aren't we just editing the sudoers
file of the pod? As we mounted the hostPath
as /
to /opt/root
, we are actually modifying the host sudoers file at /etc/sudoers
. The following is a screenshot of the Kubernetes docs for hostPath, when not used properly, it can have disastrous effects as we are going to find out
After quitting from the shell, you can now attempt to run sudo su -
and realize that you can now run commands as root and get the root flag
That is all we have for this room, you can learn more about Kubernetes, Kubernetes Security, etc. from the documentation itself or from the many great resources out there (YouTube 😉). You can also read more about MicroK8s here
Hope that you have as much fun reading this writeup as I had doing the room. Till next time!