In the first part of WAF Evasion Techniques #1, we’ve seen how to bypass a WAF rule using wildcards and, more specifically, 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 specific evasion technique. For example: using comment syntax inside a SQL Injection payload could bypass many filters. 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 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 specific 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.
Concatenation
In many programming languages, string concatenation is a binary infix 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 behaviour 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"'
NThis 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 bypass a filter (or a WAF rule) that is based on “match phrases”.
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 filenames 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 execution on 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