<<< Date Index >>>     <<< Thread Index >>>

RE: Intresting case of SQL Injection



Martin,
  I've run into this, and my solution for MSSQL was to use Java
PreparedStatements). It ties the data to a particular 
field, so you can pass in whatever you'd like, extra quotes, slashes,
escape characters, and it doesn't make a difference. I actually pass
that into a stored procedure, but that's more of just a good programming
practice in an enterprise environment (IMHO). I'm not sure what
other languages have something like a PreparedStatement, but I think
it would be a big help to ending this SQL Injection thing. As soon
as you can say:
 $x = new PreparedStatement("select * from table where username = ?");
 $x->setString(1, $_GET['username']);

then I don't see where the SQL Injection can come into play. Bad data,
sure, but you can't jump out of the '?' area.

Michael Scovetta


-----Original Message-----
From: Martin Sarsale (runa@sytes) [mailto:runa@xxxxxxxxxxxxxx]
Sent: Thursday, December 04, 2003 2:39 PM
To: bugtraq@xxxxxxxxxxxxxxxxx
Subject: Intresting case of SQL Injection


Yesterday, we found an interesting case of SQL Injection.

The application was developed under PHP 4.2.1, Apache and MSSQL.

We started our tests by adding a ' (single quote) to the POST info.

Since PHP escapes ' and " , turning the ' into a \' but SQL Server uses 2
single quotes ('') to escape a quote (') we were allowed to execute our
code:

select * from users where username='\'; sql code to execute here;--

Then, we wanted to insert a record on the "users" table (fields username
and password, both varchar).

We found that the application used md5 to store the user passwords but
there was a problem: since PHP was auto escaping quotes, we couldn't set
the md5 password as a string because sending:

insert into users values ('username','password');

would be escaped into

insert into users values (\'username\',\'password\');

resulting in a sql error.

So, we had to figure out how to insert the username and password as
numeric values. Since both fields are varchar, when inserting a number SQL
server will cast the number into a string.

This is:
inserting 123 (numeric) into a varchar field is the same as inserting
'123' (string).

The username part is easy, we could insert '12345' as the username (any
number will work here), but we found a problem with the password: We need
a known string which it's md5 hash is ALL NUMERIC.

Then, we coded a simple PHP script and found that md5(1518375) =
93240121540327474319550261818423

After that, we sent to the app:

'; insert into users (username,password) values
(12345,93240121540327474319550261818423);--

which escaped became into:

\'; insert into users (username,password) values
(12345,93240121540327474319550261818423);--

(valid SQL)

Finally, we logged into the webapp using '12345' as username and '1518375'
as password.

The main problem here was that developers where trusting in PHP auto
escaping which worked in MySQL (and probably PostgreSQL) but not in MSSQL.

Alejandro Pomeraniec (apomeraniec at buenosaires.gov.ar)
Martin Sarsale (msarsale at buenosaires.gov.ar)