PancakesCon is an excellent community online conference that I wish to never see again. It first began as an impromptu, virtual hacker con in March 2020 as a result of the closure of all the in-person conferences. Now in its 3rd rendition as we enter the 3rd year of the pandemic, it continues to be an incredible demonstration of the compassion present in much of the Information Security community. That being said, it would be wonderful if we could vaccinate (for those who can), take precautions, and make our way out of this pandemic, ending the tradition of creating a virtual conference to replace the in-person events not currently possible. The conference is made up of 40-minute presentations where each talk includes introductory infosec material and introductory non-infosec hobby material. For example, in 2022 we had talks such as “what to look for in a manager, and pottery” and “delicious pretzels and devious packets.”
Oh, and there’s a CTF! This year, there was a jeopardy-style capture-the-flag competition with “networks to enumerate, boxes to root, and other surprises.” The CTF was open for roughly 8 hours and encouraged team participation. I participated without a team, and while I wasn’t able to dedicate a full 8 hours to the CTF, I made it to 3rd place in the first hour and ended up in 9th by the end of the day. With another 30 minutes, I would have gotten root on PWN-4, but so it goes!
One particularly excellent part of this CTF was that you were not provided with specific servers per challenge on the jeopardy board.
Instead, we were given an OpenVPN connection file and the private network subnet range - 198.51.100.0/24
.
We had to discover live hosts on the network, identify to which challenge they belonged, and solve the challenges from there.
There were a number of hosts with the exact same ports open and, after investigating the open ports on one of those hosts, I determined they were decoys or additional noise on the network to distract from the real challenge servers.
I leveraged nmap
to enumerate the network:
nmap -sn 198.51.100.0/24
nmap -sS -T5 198.51.100.0/24
Once I discovered the live hosts, I typically ran the following on each:
nmap -sS -T5 -p- 198.51.100.0/24
nmapAutomator.sh -H 1908.51.100.X -t recon
I am a big fan of mind maps, and used Xmind while enumerating the network. I spent the first hour of the CTF enumerating the subnet, identifying hosts and ports, and generally information gathering. My mind map, at the end of the CTF, looked like this:
I’ll break down what I highlighted on each server as I step through them. In order to organize the servers, they are written out numerically and not by the order in which I solved them. My solve order was: NET-6, NET-1, PWN-4, PWN-3, NET-2. I had some progress on some of the other servers as well, but I neglected to take detailed enough notes, so I’m only talking about the ones I completed in this writeup.
NET
The NET-*
servers did not involve any compromise of user systems or exploitation of the servers.
They all required network enumeration.
NET-1
I am a big fan of nmapAutomator.
It runs an nmap scan then auto-runs the typical protocol-specific enumeration/recon tools for the popular services.
In this case, it caught the flag when scanning the 443/tcp
port:
This would have shown up in a regular nmap
scan as well.
I just so happened to capture it with the nmapAutomator
output.
How I captured this in my mind map:
NET-2
This is a server I had to come back to a couple hours into the CTF because I was using the wrong syntax or something and my initial enumeration of this server with onesixtyone wasn’t working. Clearly it should have, from the flag I eventually found.
The nmap
scan revealed an open web server and a robots.txt
file.
robots.txt
listed /another-flag.txt
as a disallowed route.
Going to that file returned the text It's not TCP this time
.
I re-ran nmap
with the UDP scan flags:
nmap -sU --top-ports 50 198.51.100.146
and found 1 open port, 161/udp
.
161 is - typically - the SNMP port.
https://infinitelogins.com/2021/02/21/enumerating-snmp-for-pentesting-udp-ports-161-162/ is a useful site with common enumeration commands for SNMP.
Using the following syntax, I received a dump of information in my terminal.
I paged around until I noticed this flag.
snmpwalk -v2c -c public 198.51.100.146
How I captured this in my mind map:
NET-6
The nmap
scan for this server returned the open ports 22/tcp
, 139/tcp
, and 445/tcp
.
Port 139 is typically NetBIOS, and nbtscan confirmed this was the NET-6 host.
Port 445 indicated that SMB was running, which is very interesting.
smbclient
is an FTP-like client to access SMB resources on a server.
smbmap is another very useful tool to enumerate SMB shares.
I don’t have any authentication credentials to NET-6, but let’s see if it will accept an anonymous connection - providing no username or password.
It does!
It looks like I have read-only access to the files
share.
I wonder what is in there?
flag.txt
looks very interesting!
It contained our flag for this challenge.
How I captured this in my mind map:
PWN
These servers required you to get a user and then a root flag. They were broken up into 2 challenges to score points on - e.g. “PWN-4 user,” “PWN-4 root.”
PWN-3
The nmap
scan for this server revealed an open web server on port 8000/tcp
.
The robots.txt
file disallowed entry to /fuel/
.
Well, let’s check that out.
I was presented with a blog site.
“Welcome to Fuel CMS” it said.
Thanks! I said.
Navigating to the /fuel/login/
page, I guessed admin / admin
and successfully logged into the CMS.
I’ve successfully hosted a PHP webshell in scenarios such as this, but before I proceeded to exploit the server I wanted to make sure my information gathering was complete.
If I dive too quickly into one path, I won’t become aware of alternatives.
https://www.exploit-db.com is an excellent resource when looking to determine whether a particular technology has exploitable vulnerabilities.
On Kali Linux hosts, there is a command-line tool to search the Exploit-DB database called searchsploit
.
And speaking of alternative paths, searchsploit
revealed that there were remote code execution (RCE) exploits against the version of Fuel CMS used on this site (1.4.1).
Well, let’s use that.
After modifying the url = "http://127.0.0.1:8881"
line hard-coded into the script to point to the target system,
I used the first exploit listed, https://www.exploit-db.com/exploits/47138, to get a user shell on the host as www-user
.
My shell commands were outputted within a PHP error inside HTML syntax. This is due to how this exploit script functions. I encourage you to look at the 47138 exploit-db link above and see if you can read how the script is executing.
I spawned a new TTY shell to begin gathering information on this host.
My first goal was to get a user flag, followed by identifying how to escalate to root and retrieve the root flag.
One of my first common enumeration steps is to see what else is running on the host.
ps aux
told me that I was almost certainly running inside a Docker container. (What else has an init script named entrypoint
?)
The hostname in my command line (www-data@40c422c94090
) was another suspicious indicator of running inside a container.
I also got the lay of the land inside www-data
’s common directories, such as /var/www/html
.
Hey, may as well see what was going on inside /usr/local/entrypoint.sh
, right?
I found MySQL credentials and could access the database behind the Fuel CMS instance, but the only data of note was the admin user’s password hash, and I already guessed the password above.
So nothing helpful here.
Another common enumeration step I use is to search for unusual SUID or SGID files.
find / -perm -g=s -o -perm -u=s -type f 2>/dev/null
The SUID bit is a special permission that allows other users to run an executable with the owner’s privileges.
Therefore, if I encounter an executable owned by root with the SUID bit set, invoking that executable as www-data
will run my command as if I was root
.
If there is a vulnerability or misconfiguration in the executable, I might be able to leverage that into a root shell.
My find
command returned one atypical SUID file - /var/www/html/fuel/install/helper
.
This executable prompted for a command and seemed to run whatever I gave it.
With the SUID bit set, it was running the command as root
.
helper bash
elevated me to a root shell :)
There was a flag I can now access. Hold on, it was invalid as the answer to the PWN-3 root challenge. Oh right… I was still in a Docker container. I entered the flag in the PWN-3 user challenge and was rewarded with points.
Now I needed to break out of the container to become root on the host.
https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/ was a really useful article describing a method to access host filesystem resources from a container run with --privileged
.
One way to check if you are in a privileged container is to see whether the contents of the typical filesystem block names (e.g. sda
) exist under /dev
.
From there, you can mount /dev/sda1
, or whatever is there, to an empty folder in your docker container to gain full access to the filesystem contents of the host.
However, I didn’t think of that during the challenge :) I leveraged Trail of Bit’s excellent article to write the root flag into the container. I learned some stuff and it was therefore useful, so that’s good!
Following the Trail of Bits article, I used the following cmd
script to expose the root flag into the container:
This created an /output
file inside the container that I could read.
I quickly cleaned up after myself as these files would have exposed the root flag to other players who only had www-data
access inside the container.
How I captured this in my mind map:
PWN-4
This server tricked me up for a long time. I saw the vulnerable server early and what the likely vulnerability was, but my initial exploitation attempts failed and I stopped to attempt other servers. Near the end of the CTF, a hint was provided for this server confirming my initial exploitation attempts. Re-attempting the “basic” exploit for the user access vulnerability worked this time, naturally. I ran out of time in the user shell and wasn’t able to escalate my access to root and finish the PWN-4 root challenge. I’m pretty confident I knew what the escalation path was, and would likely have solved it with another 15 minutes! Oh well. That’s how CTFs go.
The nmap
scan for this server revealed a lighthttp
web server running on port 80.
I began exploring the web server.
The robots.txt
file had a disallow listing for /maint
.
I navigated there and discovered directory listing revealing some very interesting files.
Not only was the user flag revealed in flag.txt
, but I had someone’s public and private SSH key.
Not just anyone’s SSH key, but the root
user!
This seemed too easy…
Sure enough, ssh -v -i id_rsa [email protected]
showed I successfully authenticated to the PWN-4 server as root.
I was shown a banner message, and then the SSH connection immediately closed.
Notably, and unfortunately I did not grab a screenshot, but the SSH banner before the connection closed disclosed that the version of bash running on the system was 4.3.8(1)
.
Googling “bash 4.3.8 exploit” returned articles about Shellshock.
This was very promising, but how could I trigger the shellshock vulnerability through my SSH connection before the connection was immediately terminated?
I used ssh’s -t
flag and executed bash through a shellshock exploit that then called a Bash reverse shell back to my machine.
This connected back to my machine and I got a shell on the server.
However, this was no normal shell environment.
I ran out of time here, but I am reasonably certain I was in a chroot jail.
Notably, /proc
didn’t exist.
This may have helped me escape the jail, but by this point the CTF had ended.
https://filippo.io/escaping-a-chroot-jail-slash-1/
How I captured this in my mind map:
Wrap-Up
This was a really enjoyable (and often frustrating!) CTF. I had not competed in a CTF where you had to enumerate the subnet before you could locate the challenge hosts. That was a lot of fun. I heard there was another NET challenge server that no one discovered, but was discoverable from one of the PWN servers. Sniffing network traffic from that host would have revealed another server pinging every few minutes. Unfortunately, I didn’t discover it, but it highlights how fun, thorough, and challenging this format for a CTF can be.
I hope to attend another PancakesCon next year, for both the talks and the CTF! Although, if I’m being honest, I’d rather the pandemic end than the community throw together another virtual PancakesCon in 2023.