Friday, August 16, 2013

Altamira CTF 2013: Lessons Learned

Last weekend, I participated in the first annual Altamira CTF competition, and I'm posting a review of my experience for those that would like to know what it was like and for those that may be interested in attending next year.  The general overview of the game can be found on Altamira's Game Information Page, but the synopsis can be parsed down to three core objectives:

  • Defend a nuclear reactor from attack as well as maintain services and generate energy
  • Actively exploit and attack opponents to obtain flags
  • Scan network and identify hidden assets and obtain flags

Before the game began, we were provided with the rules of the game along with our internal/external IP space.  Each team had a similar set up.


All team members used Kali 1.0.4 as their operating system of choice for game play.  Tools within Kali used in the game included: metasploit 4.7.0 with postgres 9.1, armitage, nessus 5.0.3, and ufw/gufw.

Special note.  If using metasploit 4.7.0 as your framework, you must use Nessus 5.0.3 if you want to load the Nessus plug-in.  Visiting Tenable's download page only leads you to links for 5.2.x.  Here are a couple shortcuts to 5.0.3 to save you time from analyzing their site code and finding the package names:

Sharing the Database

Prior to the competition, the team agreed that to eliminate duplication of effort, we needed to use a shared database for offensive purposes.  At the same time, the shared database needed to be protected.  We set up the postgres database, nessus, and an armitage team server instance to all be accessible remotely.  To protect the centralized infrastructure, we leveraged ufw/gufw, which works great since it starts out with a default deny for incoming traffic.  When the competition started, team members quickly fed me their IP addresses, and I loaded the rules into gufw.  I'll be posting a separate guide on how to share out the database, which is simple once you've done it a couple times.


Once the game began, offense provided the defense the results of scanning the team Scram server with the identified ports (80, 22).  Accessing the team server via HTTP on port 80 showed us the web page where the actual Scram game was running:

Check out the video above for the full briefing, or click here to jump to what our interface looked like.

After logging in to the server via SSH, the root password was changed.  With the password changed, the defenders set about learning how to play the Scram game since megawatts per hour (MwH) was a scored component.


We learned about halfway through the game that another team analyzed their team server's game code and found a way to accelerate their point gain.  We did not dedicate enough resources to emulating this approach until the last hour of the game (fail!). 

The Scrame game itself was built in python and had multiple components.  There was an script which contained variables and formulas in which the score was calculated.  In another directory was a script which took the results and sent them to the scorebot.  The packet was ultimately crafted using scapy in another python script.  The service for these python scripts was something called "twisted" that utilized websocket initialization scripts, also written in python.  A danger in altering the game code was that depending on the alteration, teams would need to restart the service components and do so in the right order.  Failure to do so would result in a loss of accumulation of points.  Note to self, learn things...


As soon as the team was wired in, offense scanned both the internal network and the external network to identify hosts.  The scan was run using Armitage, and because we didn't know of any hosts, we included the whole ranges.  Results populated "live" hosts and "ghost" hosts.  Scanning a "ghost" host resulted in no open ports.  Not having read Armitage's documentation, Armitage may automatically place an entry for each host in the range through its scanning script.  For cleaning our visual display, we set the view to table view and removed "ghost" hosts.  Note to self, learn to avoid this in the future.

With the remaining live targets, we ran multiple port scans and nessus scans against them.  We were able to get shells on two or three linux machines.  All Windows machines were running Windows 7.  More on that in the next paragraph.


From one of the shells, there was limited command line access.  Commands like "ls" worked, but "cd" and pretty much anything else did not.  We did not attempt to load another shell (fail!).
Several of the Windows machines were Windows 7 Service Pack 1, build 7601.  The default install of Metasploit 4.7.0 does not have any exploits for that build.  MS_09_50 did not work.  Enumerating these machines using the endpoint mapper auxiliary module revealed 6 to 7 machines were part of the same domain (PONY_GROUP), while 3 to 4 were part of another domain (NOVAC).  Had we gained access to one Windows 7 machine in either domain, we could've used pass the hash to get access to the others.  Shoulda, coulda, woulda...

Lessons Learned

  • CTFs in this format are "unknowns", meaning be prepared the best you can and expect something new and different
  • In CTFs where hacking the game mechanism itself is allowed, resources should be devoted to analyzing the game code at the start
  • Where CTFs provide information about the infrastructure, such as in this case the game Scram, study and any all related resources prior to the start of the competition
  • Have a tool such as WinSCP or know how to secure copy in Linux to copy files and folders from an SSH session
  • Identify all known metasploit modules/exploits built by others for use against Windows 7 and test usage 

Additional Information