Takeaways from solving CryptoHack

Just over a month ago I learnt about a new “fun platform for learning modern cryptography” called CryptoHack. The platform looked fun indeed offering a gamified experience to master cryptography. A while ago I had a try at Matasano crypto challenges, which are now known as CryptoPals. In original Matasano challenges you had to mail your solutions for verification in order to obtain the next set of challenges which now seems ridiculous. I managed to solve just a couple of sets and abandoned it for good. I have no profound math background other than from high school and a little bit of combinatorics at the university. In order to proceed with the next sets it seemed to me that I really lack some necessary math knowledge.

However in CryptoHack there is another approach. It’s not just about challenges, but learning things. All the tasks are divided into logical categories: block ciphers, RSA, Diffie-Hellman, elliptic curves and others. Each category starts with preliminary tasks that teach you the basics that are behind well-known crypto algorithms. You start reading different sources: Wikipedia, crypto StackExchange, CTF writeups, obscure papers on arxiv.org to name the least. After enough reading you start to connect the dots and come up with solutions. I don’t remember a moment when I was more obsessed with mastering something than this time.

Here are some things that I learnt and really improved at for the past month thanks to CryptoHack:

Python 3. Endless hex and big number manipulation make you understand and remember gmpy2, PyCryptoDome and native Python 3 APIs. Python 2 seems barbaric as for now.

SageMath. Sage is a large piece of math software written in Python that covers different areas, particularly number theory which is very useful for solving CryptoHack challenges.

Fundamentals. Yeah, this is the most important one. Modular arithmetic, Chinese remainder theorem, Fermat’s little theorem, extended GCD and many others – these are the basics without which cryptography could not be imagined. And you will feel really comfortable with it.

An insight into the history of major crypto vulnerabilities. Playstation 3 hack, NSA’s Dual EC DRBG backdoor, Windows CryptoAPI failure, and others – this is something you may have heard but never understood in depth. When you try to implement the attack with bare hands you achieve another level of understanding.

I would like to thank @hyperreality and Jack for putting their efforts into creating this platform, and looking forward for the new challenges to be added.

DEFCON CTF 2013 Quals “grandprix” Writeup

This time at DEFCON CTF quals there was a special task category, namely OMGACM or competitive programming. Here is a solution to OMGACM 3 task. We have a remote host that offers to play a race game:

Connected to grandprix.shallweplayaga.me.
Escape character is '^]'.
Use 'l' and 'r' to move. Don't crash.
Press return to start

OK, we send ‘\n’ to start and see a 5×8 track with different obstacles:

PHDays 2013 CTF “Blade” Writeup

We have a simple form with login and password. There is an SQL injection, but a WAF blocks any attempt to bypass it. First step to solve this task was to reveal the contents of the script by requesting index.phps:

include 'flag.php';

if (!isset($_POST['username']) || !isset($_POST['password'])) {
    print <<<FORM
<form method=POST>
<input type=text name=username></input>
<input type=password name=password></input>
<input type=submit></input>

$this_is_baaad = array(
foreach ($this_is_baaad as $srsly) {
    if (stripos($_POST['username'], $srsly) !== false) {
        print "Do not try to trick me!";

$q = mysql_query("SELECT * FROM users WHERE username = '{$_POST['username']}'");
if (mysql_num_rows($q) == 1) {
    $user = mysql_fetch_array($q);
    if ($user['password'] == $_POST['password']) {
        print $flag;
    } else {
        print "Login failed!";
} else {
    print "Login failed!";

The first thing we see is that the password does not get into the SQL query, so we need to use at least UNION, but it is blocked. Guys from PPP tried time delaying heavy queries that do not rely on sleep() or becnhmark(), however the right way to solve this task is as follows. Firstly, one notices that passwords are compared using == operator, and secondly the GROUP operator is not filtered. In MySQL this operator can be used with some interesting modifier: WITH ROLLUP

The GROUP BY clause permits a WITH ROLLUP modifier that causes extra rows to be added to the summary output.

If you use column password on GROUP BY WITH ROLLUP, you will get an extra empty row. And as NULL and empty string if compared with operator == are equal it is possible to bypass the authorization using the following query:

admin' GROUP BY password WITH ROLLUP LIMIT 1 OFFSET 1-- -