For part 1, go here: Part 1
For part 2, go here: Part 2
This will cover the Programming and Exploit Challenges:
Exploit-1 is not being covered here since I think there was a problem with the design or execution of the problem. No teams were able to solve this, so I am going to try and fix this and re-use it next semester.
Can you beat my bot? Only other non-human players accepted!
First off, I messed this one up a bit. The actual IP address was 172.18.20.51, not 172.18.20.1 but the port number was correct. I didn't realize this during the competition and the mistake was only pointed out to me after the fact. That being said a number of teams were able to discover the correct IP and solved this. Here's how the challenge worked:
When connecting to the service, a message is received which read:
Rock, Paper, Scissors!
You have to beat me 100 times to receive the flag. However, if I win 75 times, it's game over!
If we tie, we have to shoot again until there is a winner. Can you figure out my strategy?
Make your selection: (1) Rock, (2) Paper, (3) Scissors:
However, the socket had a super short timeout, so the players had to respond within 1 second or the socket was closed and the game was over. This required that the player be fast at their selection, ideally scripting their logic to play the game. The player was also at a disadvantage since they had to win 100 times before the computer won 75 times. So while possible to win via random chance, the scales were tipped to the computer side a bit to push the player to find a way to predict the computer's moves in order to gain an advantage. The computer logic was broken down as follows:
If the last result was not a tie, choose randomly* from (Rock, Paper, Scissors). Over time, this would result in the computer winning roughly 1/3 of the matches via random chance and the player winning 1/3 of the matches as well. However, there was a 1/3 chance of both players selecting the same option, and this is where the flaw could be discovered. On the computer side, there was a special bit of logic on how to handle a tie. In the case of a tie, the computer was programmed to always choose their next option to be the result that would beat the tie, meaning:
If both players chose rock, the computer would always choose paper next, if both chose paper, the computer would choose scissors, and if both chose scissors, the computer would choose rock. By evaluating the results of the selections made after a tie, the player should have identified this flaw which essentially resulted in them being able to win 2/3 of all matches. It's also possible that by random chance the player could win but just choosing randomly every time. After winning 100 matches, the program will spit out the flag:
One host, three progressively harder flags to obtain.
This was a late addition to the CTF as I wanted to add a multi-stage challenge into the mix where the players built off the initial phases to work toward progressively harder flags. This also built off testing out enumeration skills, exploitation, and privilege escalation. This challenge was also built off of vulnerabilities I discovered during some of the tests I've performed.
First off, the player needs to determine what services are available on the identified host. Here, Nmap is helpful:
Available services are: ssh, rpcbind, and nfs. Pretty straightforward. Next is enumeration of the services. NFS should be the first target since these typically may contain useful information. For this step 'showmount' can be used to determine whether there are shares that are available to view.
The results show that there are two shares available to all hosts (indicated by the *): shared and backups. These can be mounted with the mount command:
Once mounted doing a file listing should result in one file of interest:
The backup file can be copied locally and extracted to view the contents:
So there's a flag file, and a few of the sensitive files from the /etc directory. The flag file gives the player the first of the three available flags:
Next the player should cat the 'shadow' file which contains system user account password hashes. The file contains a number of hashes but conveniently leaves out the root hash.
Any of the user account passwords should be easily cracked with john or hashcat and the rockyou.txt word list. Players only needed to crack one of the accounts since all users ended up with the same permissions. In retrospect I probably should have configured the system to use a less CPU intensive hashing algorithm due to the limitations on the player provided systems, but it only took a few minutes to get a valid hit. The easiest password to crack was for user 'steve' who's password was just 'steve'.
Once cracking some credentials, the player needed to use them to SSH into the system. The second flag is waiting in the shared home directory.
The final part of this challenge requires escalating to root to read the third flag file (located in /root). The key to this part required use of the second NFS share. The configuration for the NFS shares is listed in /etc/exports, and by viewing this configuration one thing in particular should stick out:
Specifically, the "shared" folder has two specific options set: "rw" and "no_root_squash". The "rw" option indicates that the folder is writable by anyone that has access to it. But what about "no_root_squash"? Well Google gives us a few hints:
Essentially, "no_root_squash" maintains the permissions of files being uploaded to the shared folder. If a user has root on any box, they can create a file or executable with root permissions, upload it to the share, and maintain those privileges on the system they uploaded the file to. This can be leveraged in a few ways, the first is to create an executable as root, and set the sticky bit so that it executes as root, and then upload and run the executable on the system as an unprivileged user. As a result, the executable will execute as root and can be used to read the final flag.
In order to exploit this, the share needs to be mounted so that files can be written to it. Then you need a binary that can be used to provide the escalation. A simple setuid exec /bin/sh C program can do the trick.
Once it's compiled and set with the root sticky bit, it can be executed from the remote system as an unprivileged user which results in full root access to the system.
Thanks for reading this three part series! Looking forward to coming up with new challenges next semester.