几个月前在一个SRC的一个夺旗赛看了一下,题目里遇到了他们用自己的云waf保护起来的靶机,不禁心里为出题人鼓掌。
0x00
直接对靶机奉上绕过策略当然有点蠢萌,不过作为探索研究决定继续往下看了看,当时运气不错,一顿测试后还真的找到了一个sql injection的bypass方法过了那题,觉得这个简单的绕过策略他们应该能抓到,等补了再写博客。
结果。。。这两天聊到云waf想起这件事来。去主站看了一下,发现和上次测试区别是防御规则加上了web客户端指纹,发现恶意以后直接长时间屏蔽掉来自这个web客户端的请求。然而上次用的方法并没有被补上,本来想把payload作为绕过实例的,现在只好略过这个具体方法写思路了。正巧前段时间看到锁师兄在ali峰会上讲的waf防御的非主流技术,那记录一下测试思路和友情吹一波锁师兄。
0x01
WAF大体上可以划分到硬件防护、软件防护和云防护。其实有waf测试经验的话可以比较明显的返回包和从拦截表现区分出保护waf是哪一类,硬防一般直接把你的请求包丢弃,软防和云防一般会有自己独特的拦截页和拦截头。
大概一年前测过师兄公司系统外署的绿盟ips绕过。只能说硬防的规则有种不可描述的感觉,像不是从http层做的流量清洗,最终在注入语句后构造一定的尾巴再以及对间隔符的替换(当时这个ips发现对各种间隔符非常敏感)绕过了防御。盲测规则感觉是件挺耗心力的事。小尾巴大概长/**/‘1’=1–这样,改一个字符前面的绕过都会功亏一篑。。。不过核心思想还是查看引入哪些字符、替换同类函数以及做各种编码等哪些操作能不失语义地引发waf判断的变化。
0x03
举个例子,从下面的图我们可以看到保护思路,一般的网站在接受云保护后是不会把进入流量限定到只为云waf所在位置,所以有一个比较简单粗暴的方法就是寻找到主机的真实IP,绕过云waf直接去访问网站主机。
不过正面突破也是有方法的,下面讲一个某waf注入绕过思路。
waf对sql注入的防御,做法将检测到的恶意流量进行过滤。那么问题的核心就在于恶意判断,由于攻击者可以在攻击向量中加入大量的冗余数据进行混淆,因此直接取原始流量判断效率低下。所以通常做法是先进行格式化、去冗余等。
那么假如一个无效字符没有被作为冗余数据被处理掉而进入waf判断器,则很有可能让攻击向量被判断器认为无害。(这里用锟来假设存在这样一个特殊字符,请求 “union锟%20select锟” 时可能被waf判断为无害的,因为 “union锟” 在判断器眼里和 “onion” 什么的差不多,然而sql执行时因为 “锟” 是一个无效的字符而被删除了),可以参考从容的 %23%0A+Emoji表情符 绕过方法。
同理,如果有效字符如果被认为是冗余字符而处理掉后进行判断,然而在sql执行器中却是起作用的,这样很可能让攻击向量逃过判断器审查,如紫苏叶的绕过方法:1
id =1 as '--+' union select 1,2,3%23
当然这些具体的绕过策略现在都已经修复了,但是只要这种存在缺陷的机制还在的话,这种漏洞仍会出现。
直接看实例吧,用主站演示,随便输一个语句被拦截了
(这个图还是隐藏了)
可以对比一下下面两张图,我们发现通过各种方式提交的一些冗余数据让waf规则变弱了,让本来无法通过的攻击向量生效了,当然,即使这样攻击向量也不能随意构造,必须使用一些混淆。稍微一点不注意还是会触发拦截,所以绕过测试需要很大的耐心和一点点运气。
前几天就这个方法和锁哥聊了一下,锁哥说union select这个地方绕过确实有办法,但查询如果使用information.schema这张表,会使waf变得更敏感,一些小细节都会触发规则。
这就意味着如果不是一个通用cms的话,我们将无法获得数据库结构,只能获取猜到的表名和字段名的内容。虽然from之后的混淆方法很少导致绕过困难,总归有办法的~
因为绕过方法还没修就隐去了一些具体细节,先记录思路,等修了再放测试图。
http://www.wooyun.org/bugs/wooyun-2016-0192841
http://www.wooyun.org/bugs/wooyun-2015-0159517