From 15c8fd89f3aa0328c06616065ca5d3a9c19ecd3a Mon Sep 17 00:00:00 2001 From: Cassidy Camp <109514575+CassidyCamp@users.noreply.github.com> Date: Sun, 3 Dec 2023 13:49:08 -0600 Subject: [PATCH] Fixed Grammatical Errors + Added List Of Known SQL Injection Strings (#1117) * Fixed Grammatical Errors + Added List Of Known SQL Injection Strings --------- Co-authored-by: Rick M --- .../05-Testing_for_SQL_Injection.md | 130 +++++++++--------- 1 file changed, 66 insertions(+), 64 deletions(-) diff --git a/document/4-Web_Application_Security_Testing/07-Input_Validation_Testing/05-Testing_for_SQL_Injection.md b/document/4-Web_Application_Security_Testing/07-Input_Validation_Testing/05-Testing_for_SQL_Injection.md index ec3565ee03..7c236b90a5 100644 --- a/document/4-Web_Application_Security_Testing/07-Input_Validation_Testing/05-Testing_for_SQL_Injection.md +++ b/document/4-Web_Application_Security_Testing/07-Input_Validation_Testing/05-Testing_for_SQL_Injection.md @@ -6,17 +6,17 @@ ## Summary -SQL injection testing checks if it is possible to inject data into the application so that it executes a user-controlled SQL query in the database. Testers find a SQL injection vulnerability if the application uses user input to create SQL queries without proper input validation. A successful exploitation of this class of vulnerability allows an unauthorized user to access or manipulate data in the database. +SQL injection testing checks if it is possible to inject data into an application/site so that it executes a user-controlled SQL query in the database. Testers find a SQL injection vulnerability if the application uses user input to create SQL queries without proper input validation. Successful exploitation of this class of vulnerability allows an unauthorized user to access or manipulate data in the database, which if you didn't know already is quite bad. -An [SQL injection](https://owasp.org/www-community/attacks/SQL_Injection) attack consists of insertion or "injection" of either a partial or complete SQL query via the data input or transmitted from the client (browser) to the web application. A successful SQL injection attack can read sensitive data from the database, modify database data (insert/update/delete), execute administration operations on the database (such as shutdown the DBMS), recover the content of a given file existing on the DBMS file system or write files into the file system, and, in some cases, issue commands to the operating system. SQL injection attacks are a type of injection attack, in which SQL commands are injected into data-plane input in order to affect the execution of predefined SQL commands. +An [SQL injection](https://owasp.org/www-community/attacks/SQL_Injection) attack consists of insertion or "injection" of either a partial or complete SQL query via the data input or transmitted from the client (browser) to the web application. A successful SQL injection attack can read sensitive data from the database, modify database data (insert/update/delete), execute administration operations on the database (such as shutdown the DBMS), recover the content of a given file existing on the DBMS file system or write files into the file system, and, in some cases, issue commands to the operating system. SQL injection attacks are a type of injection attack, in which SQL commands are injected into data-plane input to affect the execution of predefined SQL commands. -In general the way web applications construct SQL statements involving SQL syntax written by the programmers is mixed with user-supplied data. Example: +In general, the way web applications construct SQL statements involving SQL syntax written by the programmers is mixed with user-supplied data. Example: `select title, text from news where id=$id` In the example above the variable `$id` contains user-supplied data, while the remainder is the SQL static part supplied by the programmer; making the SQL statement dynamic. -Because the way it was constructed, the user can supply crafted input trying to make the original SQL statement execute further actions of the user's choice. The example below illustrates the user-supplied data "10 or 1=1", changing the logic of the SQL statement, modifying the WHERE clause adding a condition "or 1=1". +Because of the way it was constructed, the user can supply crafted input trying to make the original SQL statement execute further actions of the user's choice. The example below illustrates the user-supplied data "10 or 1=1", changing the logic of the SQL statement, modifying the WHERE clause adding a condition "or 1=1". `select title, text from news where id=10 or 1=1` @@ -24,19 +24,19 @@ Because the way it was constructed, the user can supply crafted input trying to SQL Injection attacks can be divided into the following three classes: -- Inband: data is extracted using the same channel that is used to inject the SQL code. This is the most straightforward kind of attack, in which the retrieved data is presented directly in the application web page. +- Inband: data is extracted using the same channel that is used to inject the SQL code. This is the most straightforward attack, in which the retrieved data is presented directly in the application web page. - Out-of-band: data is retrieved using a different channel (e.g., an email with the results of the query is generated and sent to the tester). -- Inferential or Blind: there is no actual transfer of data, but the tester is able to reconstruct the information by sending particular requests and observing the resulting behavior of the DB Server. +- Inferential or Blind: there is no actual transfer of data. Still, the tester can reconstruct the information by sending particular requests and observing the resulting behavior of the DB Server. A successful SQL Injection attack requires the attacker to craft a syntactically correct SQL Query. If the application returns an error message generated by an incorrect query, then it may be easier for an attacker to reconstruct the logic of the original query and, therefore, understand how to perform the injection correctly. However, if the application hides the error details, then the tester must be able to reverse engineer the logic of the original query. -About the techniques to exploit SQL injection flaws there are five commons techniques. Also those techniques sometimes can be used in a combined way (e.g. union operator and out-of-band): +About the techniques to exploit SQL injection flaws, there are five common techniques. Also, those techniques sometimes can be used in a combined way (e.g. union operator and out-of-band): - Union Operator: can be used when the SQL injection flaw happens in a SELECT statement, making it possible to combine two queries into a single result or result set. - Boolean: use Boolean condition(s) to verify whether certain conditions are true or false. -- Error based: this technique forces the database to generate an error, giving the attacker or tester information upon which to refine their injection. -- Out-of-band: technique used to retrieve data using a different channel (e.g., make a HTTP connection to send the results to a web server). -- Time delay: use database commands (e.g. sleep) to delay answers in conditional queries. It is useful when attacker doesn’t have some kind of answer (result, output, or error) from the application. +- Error-based: this technique forces the database to generate an error, giving the attacker or tester information upon which to refine their injection. +- Out-of-band: the technique used to retrieve data using a different channel (e.g., make an HTTP connection to send the results to a web server). +- Time delay: use database commands (e.g. sleep) to delay answers in conditional queries. It is useful when the attacker doesn’t have some answer (result, output, or error) from the application. ## Test Objectives @@ -47,13 +47,13 @@ About the techniques to exploit SQL injection flaws there are five commons techn ### Detection Techniques -The first step in this test is to understand when the application interacts with a DB Server in order to access some data. Typical examples of cases when an application needs to talk to a DB include: +The first step in this test is to understand when the application interacts with a DB Server to access some data. Typical examples of cases, when an application needs to talk to a DB, include: - Authentication forms: when authentication is performed using a web form, chances are that the user credentials are checked against a database that contains all usernames and passwords (or, better, password hashes). -- Search engines: the string submitted by the user could be used in a SQL query that extracts all relevant records from a database. +- Search engines: the string submitted by the user could be used in an SQL query that extracts all relevant records from a database. - E-Commerce sites: the products and their characteristics (price, description, availability, etc) are very likely to be stored in a database. -The tester has to make a list of all input fields whose values could be used in crafting a SQL query, including the hidden fields of POST requests and then test them separately, trying to interfere with the query and to generate an error. Consider also HTTP headers and Cookies. +The tester has to make a list of all input fields whose values could be used in crafting a SQL query, including the hidden fields of POST requests, and then test them separately, trying to interfere with the query and to generate an error. Consider also HTTP headers and Cookies. The very first test usually consists of adding a single quote `'` or a semicolon `;` to the field or parameter under test. The first is used in SQL as a string terminator and, if not filtered by the application, would lead to an incorrect query. The second is used to end a SQL statement and, if it is not filtered, it is also likely to generate an error. The output of a vulnerable field might resemble the following (on a Microsoft SQL Server, in this case): @@ -73,9 +73,9 @@ varchar value 'test' to a column of data type int. /target/target.asp, line 113 ``` -Monitor all the responses from the web server and have a look at the HTML/JavaScript source code. Sometimes the error is present inside them but for some reason (e.g. JavaScript error, HTML comments, etc) is not presented to the user. A full error message, like those in the examples, provides a wealth of information to the tester in order to mount a successful injection attack. However, applications often do not provide so much detail: a simple '500 Server Error' or a custom error page might be issued, meaning that we need to use blind injection techniques. In any case, it is very important to test each field separately: only one variable must vary while all the other remain constant, in order to precisely understand which parameters are vulnerable and which are not. +Monitor all the responses from the web server and have a look at the HTML/JavaScript source code. Sometimes the error is present inside them but for some reason (e.g. JavaScript error, HTML comments, etc) is not presented to the user. A full error message, like those in the examples, provides a wealth of information to the tester to mount a successful injection attack. However, applications often do not provide so much detail: a simple '500 Server Error' or a custom error page might be issued, meaning that we need to use blind injection techniques. In any case, it is very important to test each field separately: only one variable must vary while all the others remain constant, in order to precisely understand which parameters are vulnerable and which are not. -### Standard SQL Injection Testing +### Standard SQL Injection Testing Methods #### Classic SQL Injection @@ -83,7 +83,7 @@ Consider the following SQL query: `SELECT * FROM Users WHERE Username='$username' AND Password='$password'` -A similar query is generally used from the web application in order to authenticate a user. If the query returns a value it means that inside the database a user with that set of credentials exists, then the user is allowed to login to the system, otherwise access is denied. The values of the input fields are generally obtained from the user through a web form. Suppose we insert the following Username and Password values: +A similar query is generally used from the web application to authenticate a user. If the query returns a value it means that inside the database a user with that set of credentials exists, then the user is allowed to log-in to the system, otherwise access is denied. The values of the input fields are generally obtained from the user through a web form. Suppose we insert the following Username and Password values: `$username = 1' or '1' = '1` @@ -99,15 +99,15 @@ If we suppose that the values of the parameters are sent to the server through t `http://www.example.com/index.php?username=1'%20or%20'1'%20=%20'1&password=1'%20or%20'1'%20=%20'1` -After a short analysis we notice that the query returns a value (or a set of values) because the condition is always true (`OR 1=1`). In this way the system has authenticated the user without knowing the username and password. +After a short analysis, we notice that the query returns a value (or a set of values) because the condition is always true (`OR 1=1`). In this way, the system has authenticated the user without knowing the username and password. -> Note: In some systems the first row of a user table would be an administrator user. This may be the profile returned in some cases. +> Note: In some systems, the first row of a user table would be an administrator user. This may be the profile returned in some cases. Another example query is the following: `SELECT * FROM Users WHERE ((Username='$username') AND (Password=MD5('$password')))` -In this case, there are two problems, one due to the use of the parentheses and one due to the use of MD5 hash function. First of all, we resolve the problem of the parentheses. That simply consists of adding a number of closing parentheses until we obtain a corrected query. To resolve the second problem, we try to evade the second condition. We add to our query a final symbol that means that a comment is beginning. In this way, everything that follows such symbol is considered a comment. Every DBMS has its own syntax for comments, however, a common symbol for the greater majority of databases is `/*`. In Oracle the symbol is `--`. This said, the values that we'll use as Username and Password are: +In this case, there are two problems, one due to the use of the parentheses and one due to the use of the MD5 hash function. First of all, we resolve the problem of the parentheses. That simply consists of adding some closing parentheses until we obtain a corrected query. To resolve the second problem, we try to evade the second condition. We add to our query a final symbol that means that a comment is beginning. In this way, everything that follows such a symbol is considered a comment. Every DBMS has its own syntax for comments, however, a common symbol for the greater majority of databases is `/*`. In Oracle, the symbol is `--`. This said the values that we'll use as Username and Password are: `$username = 1' or '1' = '1'))/*` @@ -123,7 +123,7 @@ The request URL will be: `http://www.example.com/index.php?username=1'%20or%20'1'%20=%20'1'))/*&password=foo` -This may return a number of values. Sometimes, the authentication code verifies that the number of returned records/results is exactly equal to 1. In the previous examples, this situation would be difficult (in the database there is only one value per user). In order to get around this problem, it is enough to insert a SQL command that imposes a condition that the number of the returned results must be one (one record returned). In order to reach this goal, we use the operator `LIMIT `, where `` is the number of the results/records that we want to be returned. With respect to the previous example, the value of the fields Username and Password will be modified as follows: +This may return some values. Sometimes, the authentication code verifies that the number of returned records/results is exactly equal to 1. In the previous examples, this situation would be difficult (in the database there is only one value per user). To get around this problem, it is enough to insert an SQL command that imposes a condition that the number of the returned results must be one (one record returned). To reach this goal, we use the operator `LIMIT `, where `` is the number of the results/records that we want to be returned. Concerning the previous example, the value of the fields Username and Password will be modified as follows: `$username = 1' or '1' = '1')) LIMIT 1/*` @@ -139,11 +139,11 @@ Consider the following SQL query: `SELECT * FROM products WHERE id_product=$id_product` -Consider also the request to a script who executes the query above: +Consider also the request to a script that executes the query above: `http://www.example.com/product.php?id=10` -When the tester tries a valid value (e.g. 10 in this case), the application will return the description of a product. A good way to test if the application is vulnerable in this scenario is play with logic, using the operators AND and OR. +When the tester tries a valid value (e.g. 10 in this case), the application will return the description of a product. A good way to test if the application is vulnerable in this scenario is to play with logic, using the operators AND and OR. Consider the request: @@ -157,7 +157,7 @@ In this case, probably the application would return some message telling us ther #### Stacked Queries -Depending on the API which the web application is using and the DBMS (e.g. PHP + PostgreSQL, ASP+SQL SERVER) it may be possible to execute multiple queries in one call. +Depending on the API that the web application is using and the DBMS (e.g. PHP + PostgreSQL, ASP+SQL SERVER) it may be possible to execute multiple queries in one call. Consider the following SQL query: @@ -171,7 +171,7 @@ This way is possible to execute many queries in a row and independent of the fir ### Fingerprinting the Database -Even though the SQL language is a standard, every DBMS has its peculiarity and differs from each other in many aspects like special commands, functions to retrieve data such as users names and databases, features, comments line etc. +Even though the SQL language is a standard, every DBMS has its peculiarity and differs from each other in many aspects like special commands, and functions to retrieve data such as users' names and databases, features, comments lines, etc. When the testers move to a more advanced SQL injection exploitation they need to know what the backend database is. @@ -211,7 +211,7 @@ Query failed: ERROR: syntax error at or near "’" at character 56 in /www/site/test.php on line 121. ``` -If there is no error message or a custom error message, the tester can try to inject into string fields using varying concatenation techniques: +If there is no error message or a custom error message, the tester can try to inject it into string fields using varying concatenation techniques: - MySql: ‘test’ + ‘ing’ - SQL Server: ‘test’ ‘ing’ @@ -234,11 +234,11 @@ We will have the following query: `SELECT Name, Phone, Address FROM Users WHERE Id=1 UNION ALL SELECT creditCardNumber,1,1 FROM CreditCardTable` -Which will join the result of the original query with all the credit card numbers in the CreditCardTable table. The keyword `ALL` is necessary to get around queries that use the keyword `DISTINCT`. Moreover, we notice that beyond the credit card numbers, we have selected two other values. These two values are necessary because the two queries must have an equal number of parameters/columns in order to avoid a syntax error. +Which will join the result of the original query with all the credit card numbers in the CreditCardTable table. The keyword `ALL` is necessary to get around queries that use the keyword `DISTINCT`. Moreover, we notice that beyond the credit card numbers, we have selected two other values. These two values are necessary because the two queries must have an equal number of parameters/columns to avoid a syntax error. -The first detail a tester needs to find in order to exploit the SQL injection vulnerability using this technique is the right numbers of columns in the SELECT statement. +The first detail a tester needs to find to exploit the SQL injection vulnerability using this technique is the right number of columns in the SELECT statement. -In order to achieve this, the tester can use `ORDER BY` clause followed by a number indicating the numeration of database’s column selected: +To achieve this, the tester can use the `ORDER BY` clause followed by a number indicating the numeration of the database’s column selected: `http://www.example.com/product.php?id=10 ORDER BY 10--` @@ -246,7 +246,7 @@ If the query executes with success, the tester can assume in this example that t `Unknown column '10' in 'order clause'` -After the tester finds out the numbers of columns, the next step is to find out the type of columns. Assuming there were 3 columns in the example above, the tester could try each column type, using the NULL value to help them: +After the tester finds out the number of columns, the next step is to find out the type of columns. Assuming there were 3 columns in the example above, the tester could try each column type, using the NULL value to help them: `http://www.example.com/product.php?id=10 UNION SELECT 1,null,null--` @@ -258,13 +258,13 @@ If the query executes with success, the first column can be an integer. Then the `http://www.example.com/product.php?id=10 UNION SELECT 1,1,null--` -After the successful information gathering, depending on the application, it may only show the tester the first result, because the application treats only the first line of the result set. In this case, it is possible to use a `LIMIT` clause or the tester can set an invalid value, making only the second query valid (supposing there is no entry in the database which has an ID that equals 99999): +After the successful information gathering, depending on the application, it may only show the tester the first result, because the application treats only the first line of the result set. In this case, it is possible to use a `LIMIT` clause or the tester can set an invalid value, making only the second query valid (supposing there is no entry in the database that has an ID that equals 99999): `http://www.example.com/product.php?id=99999 UNION SELECT 1,1,null--` #### Hidden Union Exploitation Technique -It’s best when you can exploit a SQL injection with the [union technique](#union-exploitation-technique), because you can retrieve the result of your query in one request. +It’s best when you can exploit a SQL injection with the [union technique](#union-exploitation-technique) because you can retrieve the result of your query in one request. But most of the SQL injections in the wild are blind. Yet, you can turn some of them into union-based injections. **Identification** @@ -274,7 +274,7 @@ Either of the following methods can be used to identify these SQL injections: 2. The `ORDER BY` technique works, but you can't achieve a union-based injection. **Root Cause** -The reason you can’t use the usual Union techniques is the complexity of the vulnerable query. In the Union Technique, you comment the rest of the query after your `UNION` payload. It's fine for normal queries, but in more complicated queries it can be problematic. If the first part of the query depends on the second part of it, commenting the rest of it breaks the original query. +The reason you can’t use the usual Union techniques is the complexity of the vulnerable query. In the Union Technique, you comment on the rest of the query after your `UNION` payload. It's fine for normal queries, but in more complicated queries it can be problematic. If the first part of the query depends on the second part of it, commenting on the rest of it breaks the original query. **Scenario 1** The vulnerable query is a sub-query, and the parent query handles returning the data. @@ -316,7 +316,7 @@ GROUP BY s1.user_id ``` -- _Problem:_ You break the query when you comment the rest of the original query after your injected payload, because some aliases or variables become `undefined`. +- _Problem:_ You break the query when you comment the rest of the original query after your injected payload because some aliases or variables become `undefined`. - _Solution:_ You need to put appropriate keywords or aliases at the beginning of your payload. this way the first part of the original query stays valid. **Scenario 3** @@ -413,7 +413,7 @@ The vulnerable parameter is being used in several independent queries. ```text This example may seem unlikely due to the use of dynamic SQL to log in a user, but consider a dynamic reporting query where the user selects the columns to view. The user could insert malicious code into this scenario and compromise the data. +> This example may seem unlikely due to the use of dynamic SQL to log in a user but consider a dynamic reporting query where the user selects the columns to view. The user could insert malicious code into this scenario and compromise the data. Consider the following SQL Server Stored Procedure: @@ -656,7 +656,7 @@ This will result in the report running and all users’ passwords being updated. #### Automated Exploitation -Most of the situation and techniques presented here can be performed in a automated way using some tools. In this article the tester can find information how to perform an automated auditing using [SQLMap](https://wiki.owasp.org/index.php/Automated_Audit_using_SQLMap) +Most of the situations and techniques presented here can be performed in an automated way using some tools. In this article, the tester can find information on how to perform automated auditing using [SQLMap](https://wiki.owasp.org/index.php/Automated_Audit_using_SQLMap) ### SQL Injection Signature Evasion Techniques @@ -672,7 +672,7 @@ or 'a'='a' or 'a' = 'a' ``` -Adding special character like new line or tab that won't change the SQL statement execution. For example, +Adding special characters like a new line or tab that won't change the SQL statement execution. For example, ```sql or @@ -682,7 +682,7 @@ or #### Null Bytes -Use null byte (%00) prior to any characters that the filter is blocking. +Use null byte (%00) before any characters that the filter is blocking. For example, if the attacker may inject the following SQL @@ -694,7 +694,7 @@ to add Null Bytes will be #### SQL Comments -Adding SQL inline comments can also help the SQL statement to be valid and bypass the SQL injection filter. Take this SQL injection as example. +Adding SQL inline comments can also help the SQL statement to be valid and bypass the SQL injection filter. Take this SQL injection as an example. `' UNION SELECT password FROM Users WHERE name='admin'--` @@ -726,7 +726,7 @@ To apply the Char(), the SQL injection statement will be #### String Concatenation -Concatenation breaks up SQL keywords and evades filters. Concatenation syntax varies based on database engine. Take MS SQL engine as an example +Concatenation breaks up SQL keywords and evades filters. Concatenation syntax varies based on the database engine. Take the MS SQL engine as an example `select 1` @@ -736,11 +736,11 @@ The simple SQL statement can be changed as below by using concatenation #### Hex Encoding -Hex encoding technique uses Hexadecimal encoding to replace original SQL statement char. For example, `root` can be represented as `726F6F74` +Hex encoding technique uses Hexadecimal encoding to replace the original SQL statement char. For example, `root` can be represented as `726F6F74` `Select user from users where name = 'root'` -The SQL statement by using HEX value will be: +The SQL statement by using the HEX value will be: `Select user from users where name = 726F6F74` @@ -750,13 +750,13 @@ or #### Declare Variables -Declare the SQL injection statement into variable and execute it. +Declare the SQL injection statement into a variable and execute it. -For example, SQL injection statement below +For example, the SQL injection statement below `Union Select password` -Define the SQL statement into variable `SQLivar` +Define the SQL statement into the variable `SQLivar` ```sql ; declare @SQLivar nvarchar(80); set @myvar = N'UNI' + N'ON' + N' SELECT' + N'password'); @@ -797,13 +797,15 @@ For generic input validation security, refer to the [Input Validation CheatSheet - [sqlbftools](http://packetstormsecurity.org/files/43795/sqlbftools-1.2.tar.gz.html) - [Bernardo Damele A. G.: sqlmap, automatic SQL injection tool](http://sqlmap.org/) - [Muhaimin Dzulfakar: MySqloit, MySql Injection takeover tool](https://github.com/dtrip/mysqloit) +- [SQL Injection - PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection) ## References - [Top 10 2017-A1-Injection](https://owasp.org/www-project-top-ten/2017/A1_2017-Injection) - [SQL Injection](https://owasp.org/www-community/attacks/SQL_Injection) +- [SQL Injection](https://www.w3schools.com/sql/sql_injection.asp) -Technology specific Testing Guide pages have been created for the following DBMSs: +Technology-specific Testing Guide pages have been created for the following DBMSs: - [Oracle](05.1-Testing_for_Oracle.md) - [MySQL](05.2-Testing_for_MySQL.md)