SANS Holiday Hack Challenge 2019 Postmortem — Part 1

Bjorn Lim
CSG @ GovTech
Published in
4 min readApr 13, 2020

Recently, my colleague Kee Hock and I participated in the SANS Holiday Hack Challenge 2019 and obtained a Super Honorable Mention (our submission can be found here). In this article, I’d like to share one of our more interesting challenges when we decided to manually exploit it instead of using automated tools.

Reconnaissance

The only information given about the challenge is provided by the challenge prompt:

Gain access to the data on the Student Portal server and retrieve the paper scraps hosted there. What is the name of Santa’s cutting-edge sleigh guidance system?

For hints on achieving this objective, please visit the dorm and talk with Pepper Minstix.

Pepper Minstix helpfully informs us that that we can use a tool called sqlmap to help with SQL injections. Based on this hint, it is reasonable to assume that SQL injection might be required to gain access to the data we want. We’re not going to use the tool though.

Exploring the Student Portal website, we can see that it contains 2 pages with forms, the application form and the application status form.

the two forms on the site

The application status form is simpler so let’s study it. There is some basic input sanitisation in the inputbox that is currently preventing us from submitting any value we want. This is due to the input box specifying type="email" which attempts to ensure that the value is a properly formatted email address. This, though, can easily be bypassed within the browser itself. Using the browser’s Devtools, we can edit the type from email to text.

Let’s try to trigger a trivial SQL injection.

simple bypass of form validation
SQL error message when we submit an unclosed quote, note the token parameter in the URL

Fantastic, the application helpfully gives us an error message. This tells us what the original SQL query is, which will be useful in crafting our exploit. We also note that the URL bar contains a token parameter: https://studentportal.elfu.org/application-check.php?elfmail='&token=MTAx…, but more on that later. Let’s try to exploit this vulnerability with our own script.

Writing an error based SQLi script

Here is the original SQL query in full from the error message:

SELECT status FROM applications WHERE elfmail = '{INJECTION}';

To inject the WHERE clause, we can simply do something like 1' AND (SELECT user());-- - and replace the SELECT user() with a query we want to run.

SELECT status FROM applications WHERE elfmail = '1' AND (SELECT user());-- -';

As we can see, 1' closes the quote, allowing us to place our own SQL query after the AND. To deal with the '; in the original query, we can add -- to the end of our injection, turning the rest of the statement into a comment. With the two steps above, the statement is now valid SQL.

However, simply executing valid SQL is not sufficient as we need to be able to retrieve the results of the SQL query. Since there’s an error message, lets see if we can use that to our advantage. We can try to provide our SQL query as an invalid input to a database function; doing so can cause the application to error out and return the results of our query as an error message. One method to do this is via the UpdateXML() function in MySQL.

1' AND (UpdateXML(1, concat(0x7e, (SELECT user())), 0));-- -
as we can see, the application has executed our inner SQL query and gave us the user of the database

The second argument of the UpdateXML() function expects a valid XPath. Since concat(0x7e, (SELECT user())) does not return one, we instead see the error message above with the output of our query.

Another thing that we have to note is the token parameter in the URL, commonly known as a CSRF token. The token is a unique value that cannot be repeated or reused. If we attempt to request the data without the token or attempt to reuse an old token, we’d simply get an error message. This prevents an attacker from trying to request from the URL directly as they would need to acquire a valid token first. We can see where this token variable is generated from by taking a look at the network tab of our browser’s console.

we need to request for a token from validator.php and use that in our GET request on application-check.php

We now have all the pieces to create a simple python script:

executing our SQL queries (asciinema link)

Success! In less than 10 requests to application-check.php, we’ve now obtained a list of URLs to help us get the answer to the challenge prompt and complete this challenge.

/krampus/0f5f510e.png
/krampus/1cc7e121.png
/krampus/439f15e6.png
/krampus/667d6896.png
/krampus/adb798ca.png
/krampus/ba417715.png
piecing together the images from the URLs that we obtained, we discover that the guidance system is called the Super Sled-o-matic

--

--

Bjorn Lim
CSG @ GovTech

Associate Cybersecurity Specialist @ Govtech Singapore