Skip to content ↓ | Skip to navigation ↓

Tripwire VERT CTF logo 300cI’m happy to report that the first ever Tripwire VERT capture the flag contest was a huge success. With competitors registered from across the globe, our vulnerable application saw thousands of connections coming from dozens of unique addresses along with a non-stop flood of flags, questions,and gratitude coming in via email and direct message to @TripwireVERT.

Although only four participants walked away with prizes, I would have to say these were not the only winners. This is evidenced by the hundreds of emails and DMs we received thanking Tripwire for hosting this contest and happily expressing how much they learned as a result of their participation.

Many of the messages came from infosec students grateful for the opportunity to have hands on experience applying concepts they had discussed in the classroom. Some of this is also expressed in the excellent part 1 and part 2 write-ups submitted by students Dardo Rougier and Ilias Giechaskiel based on their experiences in the contest.

Based on our server logs, it would appear that a number of users have walked through the write-up, experimenting with the vulnerabilities and hopefully, learning in the process. Now that the traffic has died down (apart from Yahoo and Baidu crawling agents), I think the time is right to share a little more from behind the scenes of the VERT CTF.

The wonderful thing about hosting a CTF is getting to see all the different clever strategies people come up with to find your flags. Sometimes it works out that the vulnerability you expect people to find first turns out to be the overlooked as people focus in on the more difficult approach (In fact, this is what happened in the second part of our challenge, but I’ll get to that a little later.)

As Rougier described in his part 1 write-up, the vulnerable application was a guestbook application. Ironically, however, the error message that led him to find email as an injectable parameter was, in fact, a fake error message baked into the leavefeedback.php code, and the blind injection identified by sqlmap was far from the most effective tool for exploiting this particular SQL injection – the SQL injection output could actually be easily viewed when manually testing the page.

The automated scanning tool, however, apparently did not recognize the HTML based redirection to viewfeedback.php.  Naturally, this was no accident but rather a calculated design choice with the intention of getting people thinking about the tools they are using. Specifically in this case, there were two factors in play to make automated scan tools like sqlmap less effective. To understand this, it is first necessary to explain a little more about the CTF page setup.

The guestbook form posts data to the leavefeedback.php script responsible for inserting data into the database. An HTML meta tag included in the response directed web browsers to a subsequent page viewfeedback.php, where the guestbook data is displayed. While sqlmap is designed to recognize this type of redirection and prompt the user for an action, the regular expression used to recognize this condition is too specific in requiring that a <head> tag is surrounding the <meta> tag.

This meant that the sqlmap execution shown in the write-up never even knew to look at viewfeedback.php for output from the injection attempts. In effect, this meant that nothing better than a blind injection would be found. Analysis of incoming requests indicates that there were more than six times as many requests for leavefeedback.php from sqlmap than there were for viewfeedback.php.

The trickery, however, didn’t stop there, as the viewfeedback.php page also contained logic specifically to confuse automated scan engines. As several people pointed out, the guestbook entries were not returned in a plain format but rather were intertwined with HTML comments containing jumbled up bits of the data coming out of the back-end.

The mangling is described by preg_replace(‘/^(.{1})(.{3})(.{4})(.+)/’, ‘$1<!–$2–>$2<!–$1–>$3<!–$3$2$1–>$4’,htmlspecialchars($data)), which creates perfectly readable output in a web browser but would require likely a tamper plugin for a tool like sqlmap to handle properly. Adding to the difficulty of using an automated tool for this task is the fact that the query constructed on the back-end contains more fields than what are presented by the form, as well as the constraint that data is associated with a cookie SID value.

Some readers may think these were mean tricks but the reality is that there is only so much value in learning how to use an off-the-shelf tool, and so while I didn’t make challenge 1 impossible to complete with sqlmap, I did design the page to be easily exploited with manual testing.

To quantify this, my tests with various sqlmap usages tended to require 500-1000 requests just to confirm a blind injection and enumerate the back-end details. On the other hand, if you manually test each of the three form parameters by simply adding a quote mark to try and break the SQL query, you would quickly see that the ‘Handle’ field (this is the email parameter in the requests) does not handle the quote.

Looking at the page response, one might have also noticed a nice Easter egg like the following:

<img src=/images/fail.jpg ALT=SU5TRVJUIElOVE8gZmVlZGJhY2sobmFtZSwgZW1haWwsIGNvbW1lbnQsIGRhdGV0aW1lLCBTSUQpIFZBTFVFUygnQ3JhaWcnLCAnQENyYWlnVHdlZXRzJycsICdDb21tZW50JywgJzE1LTA1LTExIDA2OjI1OjE2JywgJzJiNTBoNHNsYWg0N2I3MjJ2dHIyMTc0aWowJyk=.jpg height=0 width=0>

The ALT attribute on that image tag base64 decodes into the actual query attempted by the server:

"INSERT INTO feedback(name, email, comment, datetime, SID) VALUES('Craig', %2

Stay tuned for part two of the official Capture the Flag summary coming soon…

Tripwire University