User:Shailesh maurya
SQL injection:- SQL injection is a technique for exploiting web applications that use client-supplied data in SQL queries, but without first stripping potentially harmful characters. Despite being remarkably simple to protect against, there is an astonishing number of production systems connected to the Internet that are vulnerable to this type of attack. The objective of this paper is to focus the professional security community on the techniques that can be used to take advantage of a web application that is vulnerable to SQL injection, and to make clear the correct mechanisms that should be put in place to protect against SQL injection and input validation problems in general. Testing for Vulnerability Thoroughly checking a web application for SQL injection vulnerability takes more effort than one might guess. It’s nice when you throw a single quote into the first argument of a script and the server returns a nice blank, white screen with nothing but an ODBC error on it, but such is not always the case You should always check every parameter of every script on the server. Developers and development teams can be awfully inconsistent. The programmer who designed Script A might have had nothing to do with the development of Script B, so where one might be immune to SQL injection, the other might be ripe for abuse. In fact, the programmer who worked on Function A in Script A might have nothing to do with Function B in Script A, so while one parameter in one script might be vulnerable, another might not. Even if an entire web application is conceived, designed, coded and tested by one programmer, one vulnerable parameter might be overlooked. You never can be sure. Test everything. Testing procedure Replace the argument of each parameter with a single quote and an SQL keyword (such as "‘ WHERE"). Each parameter needs to be tested individually. Not only that, but when testing each parameter, leave all of the other parameters unchanged, with valid data as their arguments. It can be tempting to simply delete everything you’re not working with to make things look simpler, particularly with applications that have parameter lines that go into many thousands of characters. Leaving out parameters or giving other parameters bad arguments while you’re testing another for SQL injection can break the application in other ways that prevent you from determining whether or not SQL injection is possible. For instance, assume that this is a completely valid, unaltered parameter line ContactName=Maria%20Anders&CompanyName=Alfreds%20Futterkiste while this parameter line gives you an ODBC error
ContactName=Maria%20Anders&CompanyName=‘%20OR and checking with this line might simply return an error indicating that you need to specify a ContactName value. CompanyName=‘ This line… ContactName=BadContactName&CompanyName=‘ …might give you the same page as the request that didn’t specify ContactName at all. Or, it might give you the site’s default homepage. Or, perhaps when the application couldn’t find the specified ContactName, it didn’t bother to look at CompanyName, so it didn’t even pass the argument of that parameter into an SQL statement. Or, it might give you something completely different. So, when testing for SQL injection, always use the full parameter line, giving every argument except the one that you are testing a legitimate value. Evaluating Results If the server returns a database error message of some kind, injection was definitely successful. However, the messages aren’t always obvious. Again, developers do some strange things, so you should look in every possible place for evidence of successful injection. First, search through the entire source of the returned page for phrases such as “ODBC,” “SQL Server,” “Syntax,” etc. More details on the nature of the error can be in hidden input, comments, etc. Check the headers. I have seen web applications on production systems that return an error message with absolutely no information in the body of the HTTP response, but that have the database error message in a header. Many web applications have these kinds of ‘ BadValue’ ‘BadValue ‘ OR ‘ ‘ OR ; 9,9,9 Parentheses If the syntax error contains a parenthesis in the cited string (such as the SQL Server message used in the following example) or features built into them for debugging and QA purposes, and then developers forget to remove or disable them before release. You should look not only on the immediately returned page, but also in linked pages. During a recent penetration test, I saw a web application that returned a generic error message page in response to an SQL injection attack. Clicking on a stop sign image next to the error retrieved another page giving the full SQL Server error message. Another thing to watch out for is a 302 page redirect. You may be whisked away from the database error message page before you even get a chance to notice it. Note that SQL injection may be successful even if the server returns an ODBC error messages. Many times the server returns a properly formatted, seemingly generic error message page telling you that there was “an internal server error” or a “problem processing your request.” Some web applications are designed to return the client to the site’s main page whenever any type of error occurs. If you receive a 500 Error page back, chances are that injection is occurring. Many sites have a default 500 Internal Server Error page that claims that the server is down for maintenance, or that politely asks the user to send an e-mail to their support staff. It can be possible to take advantage of these sites using stored procedure techniques Attacks This section describes the following SQL injection techniques: Authorization bypass Using the SELECT command Using the INSERT command Using SQL server stored procedures Authorization Bypass The simplest SQL injection technique is bypassing logon forms. Consider the following web application code: SQLQuery = "SELECT Username FROM Users WHERE Username = ‘" & strUsername & "‘ AND Password = ‘" & strPassword & "‘" strAuthCheck = GetQueryResult(SQLQuery) If strAuthCheck = "" Then boolAuthenticated = False Else boolAuthenticated = True End If Here’s what happens when a user submits a username and password. The query will go through the Users table to see if there is a row where the username and password in the row match those supplied by the user. If such a row is found, the username is stored in the variable strAuthCheck, which indicates that the user should be authenticated. If there is no row that the user-supplied data matches, strAuthCheck will be empty and the user will not be authenticated. If strUsername and strPassword can contain any characters that you want, you can modify the actual SQL query structure so that a valid name will be returned by the query even if you do not know a valid username or a password. How? Let’s say a user fills out the logon form like this: Login: ‘ OR ‘‘=‘ Password: ‘ OR ‘‘=‘ This will give SQLQuery the following value: SELECT Username FROM Users WHERE Username = ‘‘ OR ‘‘=‘‘ AND Password = ‘‘ OR ‘‘=‘‘ Instead of comparing the user-supplied data with that present in the Users table, the query compares a quotation mark (nothing) to another quotation mark (nothing). This, of course, will always return true. (Please note that nothing is different from null.) Since all of the qualifying conditions in the WHERE clause are now met, the application will select the username from the first row in the table that is searched. It will pass this username to strAuthCheck, which will ensure our validation. It is also possible to use another row’s data, using single result cycling techniques, which will be discussed later. Using the SELECT Command For other situations, you must reverse-engineer several parts of the vulnerable web application’s SQL query from the returned error messages. To do this, you must know how to interpret the error messages and how to modify your injection string to defeat them. Direct vs. Quoted The first error that you normally encounter is the syntax error. A syntax error indicates that the query does not conform to the proper structure of an SQL query. The first thing that you need to determine is whether injection is possible without escaping quotation. In a direct injection, whatever argument you submit will be used in the SQL query without any modification. Try taking the parameter’s legitimate value and appending a space and the word “OR” to it. If that generates an error, direct injection is possible. Direct values can be either numeric values used in WHERE statements, such as this… SQLString = "SELECT FirstName, LastName, Title FROM Employees WHERE Employee = " & intEmployeeID …or the argument of an SQL keyword, such as table or column name: SQLString = "SELECT FirstName, LastName, Title FROM Employees ORDER BY " & strColumn All other instances are quoted injection vulnerabilities. In a quoted injection, whatever argument you submit has a quote prefixed and appended to it by the application, like this: SQLString = "SELECT FirstName, LastName, Title FROM Employees WHERE EmployeeID = ‘" & strCity & "‘" To “break out” of the quotes and manipulate the query while maintaining valid syntax, your injection string must contain a single quote before you use an SQL keyword, and end in a WHERE statement that needs a quote appended to it. And now to address the problem of “cheating.” Yes, SQL Server will ignore everything after a “;--” but it’s the only server that does that. It’s
better to learn how to do this the “hard way” so that you’ll know how to handle an Oracle, DB/2, MySQL, or any other kind of database server. Basic UNION SELECT queries are used to retrieve information from a database. Most web applications that use dynamic content of any kind will build pages using information returned from SELECT queries. Most of the time, the part of the query that you will be able to manipulate will be the WHERE clause. To make the server return records other than those intended, modify a WHERE clause by injecting a UNION SELECT. This allows multiple SELECT queries to be specified in one statement. Here’s one example: SELECT CompanyName FROM Shippers WHERE 1 = 1 UNION ALL SELECT CompanyName FROM Customers WHERE 1 = 1 This will return the recordsets from the first query and the second query together. The ALL is necessary to escape certain kinds of SELECT DISTINCT statements. Just make sure that the first query (the one the web application’s developer intended to be executed) returns no records. Suppose you are working on a script with the following code: SQLString = "SELECT FirstName, LastName, Title FROM Employees WHERE City = ‘" & strCity & "‘" And you use this injection string: ‘ UNION ALL SELECT OtherField FROM OtherTable WHERE ‘‘=‘ The following query will be sent to the database server: SELECT FirstName, LastName, Title FROM Employees WHERE City = ‘‘ UNION ALL SELECT OtherField FROM OtherTable WHERE ‘‘=‘‘ The database engine will inspect the Employees table, looking for a row where City is set to “nothing.” Since it will not find it, no records will be returned. The only records that will be returned will be from the injected query. In some cases, using “nothing” will not work because there are entries in the table where “nothing” is used, or because specifying “nothing” makes the web application do something else. You simply need to specify a value that does not occur in the table. When a number is expected, zero and negative numbers often work well. For a text argument, simply use a string such as “NoSuchRecord” or “NotInTable.” The server returned the page in response to the following: http://localhost/simpleunquoted.asp?city=-1 UNION SELECT Otherfield FROM OtherTable WHERE 1=1 A similar response was obtained with the following quoted injection: http://localhost/simplequoted.asp?city=’UNION SELECT Otherfield FROM OtherTable WHERE “=’ Query Enumeration with Syntax Errors Some database servers return the portion of the query containing the syntax error in their error messages. In these cases you can “bully” fragments of the SQL query from the server by deliberately creating syntax errors. Depending on the way the query is designed, some strings will return useful information and others will not. Here’s list of suggested attack strings. Several will often return the same or no information, but there are instances where only one of them will give you helpful information. Try them all the message complains about missing parentheses, add a parenthesis to the bad value part of your injection string, and one to the WHERE clause. In some cases, you may need to use two or more parentheses. Here’s the code used in parenthesis.asp: mySQL="SELECT LastName, FirstName, Title, Notes, Extension FROM Employees WHERE (City = ‘" & strCity & "‘)" So, when you inject this value… “‘) UNION SELECT OtherField FROM OtherTable WHERE (‘‘=‘”, …the following query will be sent to the server: SELECT LastName, FirstName, Title, Notes, Extension FROM Employees WHERE (City = ‘‘) UNION SELECT OtherField From OtherTable WHERE (‘‘=‘‘)
The server returned the page in response to the following: http://localhost/parenthesis.asp?city=’ The same response was obtained with the following quoted injection: http://localhost/ parenthesis.asp?city=’) UNION SELECT Otherfield FROM OtherTable WHERE ( “=’
Subitted by- Shailesh