How to Test For SQL Injection Vulnerabilities
Applies To
*Web applications and services connected to a database
*Database facing thick client applications
Summary
SQL injection is a vulnerability that allows an attacker to execute SQL commands in a SQL database. The vulnerability occurs due to poor input validation allowing an attacker to inject SQL into a legitimate query.
Testing for SQL injection involves the following 5 steps:
- Identify entry points
- Discover database schema details
- Craft attack data for each entry point
- Pass attack data to each entry point
- Confirm impact
1. Identify entry points
Entry points are the means by which you can provide input to the application under test. The following are common entry points for attack:
*Browser address bar
(URLs) *Web service methods
*Application UI input fields (text fields)
*Public
APIs *COM/DCOM methods
As you explore the set of entry points look for the ability to provide string input or data that can be used to inject a malicious SQL statement.
A SQL Injection vulnerability requires that the application uses input, without proper validation, in its interaction with a SQL database. If you have access to the code look for untrusted input that is able to control one of the following:
*SQL dynamic query generation (construction and concatenation of SQL queries)
*Stored procedures
*Access to functions such as OPENROWSET, OPENDATASOURCE, or xp_cmdshell (in Microsoft SQL Server only)
*SQL injection data in interaction other applications (through COM, DCOM, kernel objects such as pipes or other methods
2. Discover Database Schema Details
Before attacking a database with SQL injection it is important to know its schema such as table names, field names, field types, stored procedure names, and access to extended system procedures.
Step 1: Find the database vendor and version!!!
SQL syntax has the same structure but varies across servers (SQL Server, DB2, Oracle, MySQL). These methods can be used for database version discovery:
*Use product specific syntax. For instance concatenation in SQL Server is denoted by the + sing while oracle uses ||. If SQL injection occurs, the attacker can manipulate the injected SQL code so that it attempts to concatenate both ways and differentiate products.
*Sniff HTTP traffic. This is a useful technique to discover SQL Server databases since one can be almost certain that any ASP or ASP.NET service has SQL Server backend.
*Scan server ports. An IP scan that returns 1433 tells that the target is MS SQL Server (unless the IT is using a social engineering trick). Scans are easily done using tools like nmap.
*Force basic error messages. An invalid SQL query returns error messages. Some web application forward these messages to the web client. For instance, injecting one or more of the boxed characters causes a vulnerable web application to throw a SQL exception.
SELECT * FROM Users WHERE name = ’
)=+-<>”;%!(* ‘
The ODBC exceptions sent back to web clients often reveal table names and sometimes fields.
Step 2: Discover the database structure
In most cases, queries that work and don’t return an error message can be broken to divulge database names, tables, columns, and field types. Testers need to follow these methods:
*Brute forcing database structure. Brute forcing for SQL target discovery is a common method used by testers that can be automated to increase discovery speed.
SELECT * FROM Users WHERE field = ‘x’ AND field_name_iteration IS NULL;--
A successful result tells the attacker that the field iterated is valid in the database schema.
*Use special queries and functions. Some queries show as SHOW TABLE or special functions yield database schema. For instance injecting any of the below will divulge intrinsic information about the database under attack:
SHOW TABLE known table
EXEC master.dbo.sysobjects
EXEC master.dbo.sysdatabases
3. Craft attack data for an entry point
Use the following two steps to craft effective attack data:
Step 1: Construct valid SQL statements based on the context of the vulnerability.
Depending on the SQL statement you are attacking, different combinations of attack data are needed to successfully alter the SQL statement while maintaining its validity to the SQL parser. Below are the most common techniques:
*Inject OR operand to change the logic of a SQL statement. Use the OR operand to add SQL condition to the WHERE clauses if a non-empty result is needed. SQL server executes the altered WHERE and returns results based on the condition injected. Usually the syntax involved is a string followed by a single quote and the new operand. For instance the following query:
stmt = “SELECT * FROM users WHERE user_name = ‘“ + user ‘”
Can be altered by passing
a’ OR 1=1 in the user variable so that the final query looks like this
SELECT * FROM users WHERE user = ‘
a’ OR 1=1 *Inject AND statements into a single SQL statement. Using AND operands allows you to construct a single statement containing two queries. For instance the following statement
stmt = “SELECT * FROM Users WHERE field = “ + field_name + “ IS NULL—
Can be altered with
x AND field_name IS NULL;-- in the field_name statement so that the final query looks like this:
SELECT * FROM Users WHERE field =
x AND field_name IS NULL;-- *Inject UNION SELECT into a single SQL statement. Using UNION SELECT it is possible to construct a valid single SQL command that queries for additional information without having to execute more than one command statements. For instance, the following SQL statement
stmt = “SELECT * FROM policies WHERE rule = ‘“ + rule_ID + ‘”
Can be altered with the boxed string into
SELECT * FROM policies WHERE rule = ‘
345’ UNION SELECT user, password FROM users *Add additional SQL statements. In most database it is possible to execute concurrent SQL statements by adding a semicolon between them. For instance, this query:
stmt = “SELECT * FROM policies WHERE rule = ‘“ + rule_ID + ‘”
Can be altered with the boxed string to drop the users table
SELECT * FROM Logon WHERE (pdw = ‘
a’); DROP TABLE Customers;--
Step 2: Tune your attack data depending on syntax variations
It is important to put the following delimiter characters in the right order and place to execute an attack that meets your goals:
‘ “ ( ) ; , . -- \ %
Explore the different combinations that may result in SQL injection by trying different permutations of number, position, and content of these delimitations.
For instance, you could try all possible combination of
a’ OR 1 = 1: *' or 1=1--
*" or 1=1--
*or 1=1--
*' or 'a'='a
*" or "a"="a
*') or ('a'='a
Step 3: Tune your attack data depending on attack goal
If you are trying to prove damage potential of a SQL Injection attack you may have a specific goal in mind, such as information disclosure or to bypass authorization. Depending on your goal, the attack data can be tuned for the best chance of success. Common options of tuning data for specific goals include:
*Authorization bypass. Injecting an OR can lead to bypass of login web pages. Attackers may also use INSERT to add themselves to the login table with high privileges.
*Information disclosure. Injecting AND, UNION SELECT, and SELECT operands results in extra records from the victim database. The attack’s success depends on how much the attacker knows about the database.
*Tampering. Data loss or modification attacks require an extra statement containing a DROP, INSERT, or UPDATE operand.
*Accessing the shell. Attackers can use SQL injection to execute special functions such as SQL Server’s xp_cmdshell. If attackers get shell access they can invoke powerful system functions to map network drives, manipulate files and folders, and cause serious damage to the victim.
4. Pass attack data to an entry point
As you explore the set of entry points look for the ability to provide string input in a way that gives you control over the application’s interaction with a SQL database.
*Web Forms. Input text fields in an HTML form are the most common entry points for malicious data. Typing
a’ OR 1 =1)-- in the texts field asking for user names or passwords can lead to authorization bypass.
*URL Parameters. A browser can be used to perform SQL injection by manipulating application URL’s in the browser address bar.
URLs often contain variable names and values as URL parameters. For instance a valid parameterized URL looks like this:
http://www.vulnsoft.com/results.asp?nm=name&em=test@vulnsofft.net
An attacker can manipulate special parts of the URL such as “em” variable and send it directly to the server without filling any web forms.
POST results.asp?nm=name&em=’
test@vulnsoft.net'%20OR%201%20=1 *Proxies and Replication Servers A big segment of the Internet consists of proxy servers. A proxy server is a fast machine dedicated at single tasks such as redirecting Internet addresses to sites, load balancing network traffic, backing up a domain controller or database server, and providing emergency failover to critical nodes.
Attackers can insert or modify a database proxy to manipulate the data server. This allows any legitimate query to be changed from benign to malicious. Since, proxies work as a server side node, any client-side sanitation filters can be bypassed by inserting any filtered attack data.
Executing a proxy or Man in The Middle (MiTM) attack can result in total theft of a remote database. As an example, consider executing a MiTM attack between tow SQL Servers that have no authentication. Even if SSL is used, it is possible to insert proxies that inject malicious queries by faking a valid SSL certificate.
*System entry points (public API’s, COM interfaces, Kernel objects) SQL server use is not restricted to web applications; it is growing in client-side applications too. For fast file access, even operating systems are even building file systems based on SQL structure and using SQL queries. You must look at all entry point, network-facing or not. Public API calls or transmitting data application through kernel objects can easily result in SQL injection.
5. Confirm Impact
Prior to analyzing the success of different SQL injection attacks it is important that you know that the presence of SQL error messages is a reaction that indicates a high probability of successful SQL injection.
After executing an attack it is necessary to determine success or failure. The method for verifying if the attack was successful depends upon the goal of the attack.
*Authorization AttacksIn an authorization attack verify that you are given access to resources you wouldn’t otherwise have access to. In most cases a successful attack results in a welcome or login-success page. A failed attack will result in access denied errors.
*Information Disclosure AttacksA successful information disclosure attacker requires the result-set to travel back to the attacker. Many times you will see the information displayed in the application UI, sometimes it is necessary to use a network sniffer to view the information directly in the HTTP stream. A failed attack will result in no useful information returned to you.
*Tampering AttacksSuccessful tampering attacks will result in modification of database data or table structure. If you have direct access to the database (through another account) you can look at the data and see if it has been modified by your attack. If you do not have direct access to the data, look for application failures or indirect impact from the modified data. For instance a dropped table may results in complete application failure. Modification of table data may result in changed application logic or a change in the data that is displayed to a normal user.
Repro Example
Flawed Code
In this example the coder builds a SQL statement to query a password in the Users table without validating the input for in the
password variable:
stmt = “SELECT * FROM Users WHERE pwd = ‘” + password + “‘”
Test Examples
*Authorization bypass SELECT * FROM Users WHERE pwd = ‘
a’ OR 1=1 If a user exists, the transformed query returns mores than one record. A web application that assumes that non-zero means valid credentials will grant access to the attacker.
*Information Disclosure SELECT * FROM Users WHERE pwd = ‘
123’ UNION SELECT name, credit_card, address FROM Costumers Instead of returning results when id is 123 only, the above statement leads to unwanted disclosure of names, credit card numbers, and addresses from all customers.
*Tampering SELECT * FROM Users WHERE pwd = ‘
a’; DROP TABLE Customers;-- This drops the
Customers table from the victim. Attackers use it this SQL injection attack to deny web application service and cause serious data loss.
SELECT * FROM Users WHERE pwd = ‘
a’); INSERT INTO Accounts VALUES (‘1000’, ‘hacker’, 100)-- This injection creates a new user named hacker in the
Accounts table
SELECT * FROM Users WHERE pwd = ‘
a’); UPDATE Accounts SET balance = 987654321 WHERE User = ‘hacker’)— Sets the “hacker” account to $987,654,321
*Shell access SELECT * FROM Users WHERE (pdw = ‘
a’); EXEC xp_cmdshell dir C: -- Executes a dir command in Windows.