I’ll let the author describe it in his words:
Ever fantasized about playing with docker misconfigurations, privilege escalation, etc. within a container? Download this VM, pull out your pentest hats and get started 🙂
We have 2 Modes:
HARD: This would require you to combine your docker skills as well as your pen-testing skills to achieve host compromise.
EASY: Relatively easier path, knowing docker would be enough to compromise the machine and gain root on the host machines.
We have planted 3 flag files across the various machines / systems that are available to you. Your mission if you choose to accept would be as follows:
1. Identify all the flags (3 in total)
2. Gain id=0 shell access on the host machine.
I chose to solve the “hard” variation of the VM as I love my puzzles as challenging as possible.
The challenge begins after we launch the VM and get presented with an IP address;
my VM received the IP address of 192.168.1.135.
I scanned the IP for open ports and found that the only open port is 8000 and it serves a WordPress blog.
I decided to quickly scan the WordPress site with wpscan – an open source tool that detects vulnerabilities in WordPress instances; the WordPress version is the latest, there are no active plugins and apart from some information disclosures the website was technically secure. However, the results showed something interesting for me – the WordPress API was available at /wp-json/ so i decided to utilize it in order to leak the usernames of the WordPress site, which can be done by simply visiting the api at:
The result return only one user and his name is: bob, and being the only user probably makes bob our Admin!
As there were no other visible entry points I decided to bruteforce the password of bob, I ran hydra with a list of top 100,000 passwords, and after some time hydra got a hit, the password for bob is: Welcome1
I logged in and this is where I found the first flag_1:
And a hint that the other flags are in files.
I uploaded a webshell by editing one of the WordPress plugin’s files – Hello Dolly. By replacing the content of hello.php with a webshell I could now execute commands inside the WordPress host, so I began to look for a second flag but I did not find it anywhere on the system, at first I thought that it might be the lack of root permissions but it later turned out to not be the case.
I suspected that the kernel is exploitable by the dirtyc0w exploit and spend some time trying to utilize the exploit and a few others that fit the target description. I finally decided to leave it be and looked around for neighbors on this host’s network. I was so obsessed with getting root through an exploit that I completely forgot about much easier ways of gaining control!
I transferred a copy of ifconfig from my own machine into the WordPress host in order to figure out the internal ip and also dropped a copy of nmap in order to scan the IP range and to discover new friends.
Before moving forward I created a proxy in order to pivot my way inside the local network of the containers, in order to be able to issue commands such as ssh firstname.lastname@example.org from my host and avoiding address resolving problems.
I found 3 additional IP addresses, one of which was 172.18.0.3 with port 22 serving SSH. I later discovered that there is also a web ssh console at 172.18.0.3:8020.
And as stated above, I tried to connect to it through SSH and voilà, we have a root inside a different container, this one was Ubuntu flavored and had apt present. I decided to try out my luck and installed the Docker client inside of the container and to my surprise the Docker socket was mounted inside! I could now talk directly to the Docker daemon on the host vm and inspect all other containers with root privileges.
I proceed in executing a privileged container and mounted the host FS into /root
I walked the /root directory and there it was – flag_3 :
For the last step in order to get root shell on the host I added my attacker vm’s ssh key to the list of authorized keys, as I mounted the host FS editing it would result in a correspondent edited host file.
Although I could not locate flag_2 among the FS of the containers nor the host FS into /root (if someone did found it please ping me! I would love to know where it was laid), I gained root access to the host and of course all of the containers as well – Game over!
Prevention of lateral movement, container escape and more
In all of our research, we think about how Twistlock can detect and prevent real world attacks and this CTF was a good illustration of how powerful multiple layers of defense in depth can be.
For example, our compliance features would have detected the misconfigurations of the containers and prevented me from running a container as root or mounting the Docker socket. Our Cloud Native App Firewall would have detected and prevented the brute force attack on the WordPress site. Finally, our runtime defense features would have kicked in at the stage of gaining the first shell on the WordPress container and would not allow to me pivot any further by preventing anomalous system calls and blocking the foreign binaries I uploaded.
The really powerful part of this runtime defense is that no person would have needed to configure rules to protect WordPress; Twistlock would create the model of the app automatically and be able to instantly identify anomalous activities outside the model. You’ll see even more cool automated runtime defense coming soon in Twistlock 2.2, so stay tuned to the blog for details.