SQLite Order By Blind Injection - Flaskmetal Alchemist - NahamCon CTF 2022

Flaskmetal Alchemist was a web medium challenge in which we were given the source code for a Python application based on the Flask framework and the SQLAlchemy ORM library. As the name was suggesting this application has a SQL injection vulnerability and some quick testing showed the order clause to be injectable.

Since our injection is in the order clause we cannot select data directly but can do a subquery to affect the order, or even better, the limit.

While reading other writeups about the challenges I was surprised to find that in every case ( iwanflagz, ghostccamm, DauHoangTai ) they had taken a blind binary search exfiltration approach, and since I did it differently, I wanted to share my way.

Since we are told in the challenge description that:

NOTE: this flag does not follow the usual MD5 hash style format, but instead is a short style with lower case flag{letters_with_underscores}

And we have around 100 results to the search I figured it would be faster to get directly the ASCII code of each letter by using it in the limit clause, one request per character, instead of the 8 request per character for binary search (or more if you simply bruteforce the character). Since the largest code we are expected to get is 125 for } I subtracted 40 to it and used it in the limit like so:

atomic_number limit (SELECT unicode(substr(flag, 1, 1)) - 40 FROM flag)

After getting the results we simply count the items, add 40 and convert back to ASCII.

And we get flag{order_by_blind} although we peeked a bit.