How to fuzz MySQL looking for weird characters

Luca Di Domenico
3 min readNov 8, 2020

Introduction

In this article I will show you a simple technique I learned following this talk about SQL injection obfuscation and optimization: https://media.blackhat.com/us-13/US-13-Salgado-SQLi-Optimization-and-Obfuscation-Techniques-Slides.pdf

The talk is very interesting and I suggest you to give a look at the slides linked above.

During the talk, among other things, it’s explained how in some situations it can be very useful to write a little fuzzer for a DBMS (I will use MySQL in this exercise) in order to find some weird characters that may help you to bypass weak security filters or WAFs during a web security assessment.

Let’s simulate a situation where we have found an UNION based SQL injection vulnerability in a web site we are auditing but we noticed that some characters in our SQL payloads are blocked by the WAF. For example, let’s assume that the web application’s WAF implements the following security filters:

/union\s+all\s+select/i
/union\s+select/i

So all of the following payloads are being blocked by the WAF:

' union SELECT @@version-- -
' UnIoN SeLeCt @@version-- -
' union all SELECT @@version-- -
' UNION ALL SELECT @@version-- -
' UnIoN AlL SeLeCt @@version-- -

Suppose also that the WAF rejects payloads containing comments instead of space (the classic bypass used in sqlmap -tamper=space2comment.py) so that payloads like these below do not work:

' UnIoN/**/all/**/SeLeCt/**/@@version-- -
' union/*!12345 */SELECT/**/@@version;

In this situation, you need to find one or more characters that works as a valid keyword separator for MySQL queries, but that also are not blocked by the WAF.

Writing the fuzzer

To discover the separator character, we can build a simple fuzzer that tries to execute a given SQL query with all possible ASCII characters between the UNION and SELECT keywords. When the query doesn’t fail, the script prints the combination of 3 characters that were successfully used as keyword separators in that query.

So the fuzzer must return only those characters that we can use as valid keyword separators.

The code is showed below:

The script requires the mysql-connector for python3, which can be installed with pip:

pip install mysql-connector-python

Off course, to execute this script, you need to setup MySQL server on your machine. Also check the version of your MySQL installation as returned by the following query:

select version();

and write it in the script file, in the variable named VERSION (I used the version 5.6.49), because as you can see at line 26 the script will use this to understand if a character is a valid separator or not.

The template for the payload I used in the fuzzer is the following:

' UnIoN{a}SeLeCt{b}VERSION(){c}

the fuzzer will replace the symbols {a}{b}{c} with 3 different ASCII characters on each query, in order to find a valid combination of separator characters.

Once setup is done, run this script and wait until it finishes its execution. The output can be quite verbose, so you may find useful to redirect it to a file for further processing:

python3 fuzzer.py > output.txt

Once the fuzzer has finished the execution, open output.txt and look at the characters that are resulted to be valid separators in MySQL 5.6.49 (they are outlined in red in the image below), with their value printed in decimal, hexadecimal and ASCII notation:

Content of file output.txt

So now we can construct a payload the will bypass the filter, for example the following:

' UnIoN(SeLeCt VERSION())-- -

Note also that the plus “+” sign is a valid separator between the SELECT keyword and the VERSION() function, so this payload will also work:

' UnIoN(SeLeCt+VERSION())-- -

Conclusions

The scope of this article is to show how to write a custom fuzzer tool that can be useful when dealing with SQL injection’s filters.

Another similar but way more complex and advanced project is Shazzer: http://shazzer.co.uk/home

This project is a fuzzer for the Javascript engines of the most common browsers and can be used in order to bypass XSS security filters. I suggest to check it out if you are interested.

That’s all for now. Thanks for reading and see you in the next article.

References

--

--

Luca Di Domenico

Web security and Crypto. I’m a Software Security consultant and Freelance Web3 Developer. Follow me on Twitter! @luca_dd7