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.
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.
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 '.
Assuming that you understood the above logic, let's see what does insert() function actually do.
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 'A'=INSERT('ABCDEFGHI', 2, 255, SPACE(0)); # SPACE(0) = Nothing..
>> SELECT 'A'=INSERT('ABCDEFGHI', 2, 255, ''); # SPACE(0) = Nothing..
Well, BECAUSE THIS COMPARISON RULE IS NOT LIMITED IN MYSQL!
on the right of one or more pad characters, where the pad character is chosen based on CS.
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.