Recently I competed in the Cyber Security Competition Australia 2013, representing Flinders University.
The competition consisted of identifying security vulnerabilities in a virtual environment (which I believe was hosted on Telstra's cloud platform; Telstra being a major sponsor of the competition). Each team was given access to a VPN upon which a fake company's infrastructure was simulated. Points were awarded for finding, exploiting and suggesting mitigation approaches for vulnerabilities in the simulated infrastructure.
Each teach competed remotely; our team was provided with a room for the 24 hour competition in Flinder's IST building by the university. This was a big gesture, as the competition started around midday on a Tuesday and ran until midday on a Wednesday -- which meant that two days worth of classes needed to be relocated. Flinders also procured several workstations for our team.
This had the side-effect of making me nervous about the competition: it took a significant amount of time for Flinders to arrange all of this, and three members of our team (myself included) hadn't undertaken any security topics. By and large, we were entering the competition because it sounded like fun.
I'm pleased to say that I think we exceeded all expectations for our team. Flinders Team 1 (Flinders' only team) came 6th out of the 43 teams which entered, placing only behind much larger universities including the University of New South Wales, the University of Sydney and the Australian National University. An amazing result, given this was Flinders first time in the competition and we practically entered on a whim.
The challenge in the competition which I focused most on was the web application (for which Flinders received all points).
The first flag for the web challenge was simply to find a 'secret file'. Poking around the website, I noticed a few files in a /uploads directory and wondered if directory listing was enabled. It turned out it was, and there was a file in the directory called 'secret.txt'. This file contained the flag.
Inserting a single-quote character into the phone number field showed a PHP mysql_query error, which revealed that the phone number was the second to last field in the query — followed by a conspicuous '0'.
By inserting the following
as our phone number, we overloaded the 0 (which we guessed might be the activated flag) with a 1, thereby activating our account. The second flag was on the index page after logging in.
Earlier, we had discovered that /admin wasn't secured: but it showed nothing for unregistered users. There was an admin.js file referenced from the page (which referenced 'activate.php', 'grant.php' and 'user.php'), which if I recall all accepted a user ID as a POST parameter (Looking back, I wonder if activate.php was secured like grant.php and user.php – which both required an administrator account – or whether it could have been used as an alternative solution to the second challenge)
It seemed clear that grant.php was for granting admin privileges. But, that was useless to our account – as it required the admin privileges we didn't yet have to use.
However, the index of the website throughout the competition had shown that the CEO of the company had been browsing the website ever few minutes. We hazarded a guess that this was a bot, meaning we could leverage the XSS injection found previously to get the CEO of the imaginary company ("Rob Mclean") to hit grant.php for us.
The fourth flag was more complicated still, but still achievable. This challenge involved obtaining Rob Mclean's password hash – which was the flag.
We thought this would be easy – we could just repurpose the SQL injection from checkpoint 2 to copy digits of his password hash to our phone number field. Naturally, this idea wasn't good enough. The phone number field wasn't protected against injection, but it did strip all left-parenthesis and equals characters. While I'm sure there was a clever way to encode the characters and work around this, we didn't find a way.
Instead, we turned our attention to the admin files – user.php, grant.php and activate.php. We tried these roughly, but no output was returned. On further inspection, we saw that user.php (which simply retrieved and displayed details like phone number for a given user) only returned any data when the user ID passed to it was numeric; e.g. 8 or 8.0.
We inspected this file further, and eventually tried the following user ID
3 AND SLEEP(5)
Which, to our surprise, slept for five seconds – meaning it was, after all, executing the SQL. Once we had found this, the rest of the challenge was simple. Using "AND SLEEP(5)" we found that there was a users table with a password field (as if we tried invalid table or column names, the query would error and not call SLEEP)
We then wrote a query which selected an individual character from Rob Mclean's password hash, retrieved its ASCII value, and slept that many seconds. Calling this 32 times, we found the ASCII value for every character in Rob Mclean's password hash. We converted these back to ASCII (what looked like a hex-encoded MD5 hash) and had the flag.
We're not sure if our solution to the fourth web application challenge (blind SQL injection) was the most elegant, but it was undoubtedly effective, and that completed the web apps challenges for our team.
I'd love to have a white-box look at the website's source and see what else I missed, though I don't see that happening.
Regardless, I have to thank the Australian government, Telstra, Microsoft for organizing the competition. It was a lot of fun, and I can imagine it going a long way to promote cyber security in Australia.
I also need to thank Flinders University, particularly Neville Williams, John Roddick and the entire CSEM IT staff for the support and faith they put in our team when we voiced an interest in the competition. You guys spent a lot of time enabling us to enter the competition even though we didn't know how we would perform, and our success wouldn't have been possible without you.