zoukankan      html  css  js  c++  java
  • TSRC挑战赛:WAF之SQL注入绕过挑战实录

    转自腾讯

    博文作者:TSRC白帽子

    发布日期:2014-09-03

    阅读次数:1338

    博文内容:

    博文作者:lol [TSRC 白帽子]

    第二作者:Conqu3r、花开若相惜

    来自团队:[Pax.Mac Team]

    应邀参加TSRC WAF防御绕过挑战赛,由于之前曾经和Team小伙伴一起参加过安全宝WAF挑战,而且自己平时接触WAF的机会也比较多,对于WAF绕过的方法还是有一定积累的。


    比赛规则就是绕过四台被tencent WAF保护的测试服务器(分别为:apache GET、apache POST、nginx GET、nginx POST)。用一种方法绕过其中一台即可,如果可以执行任意SQL语句即为通用绕过,视为高危,若有其他利用条件限制则视为中低危。


    比赛之前,首先要熟悉tencent WAF的部署环境,是在网络层,还是在应用层,如果在应用层是在到达apache(或nginx)之前还是之后。不同的部署环境决定了不同的绕过方法。通过在TSRC上查看《主流WAF架构分析与探索》一文了解了tencent WAF 实现于服务器的安全模块内,这样的话,类似于十进制ip地址绕过网络层WAF防护、gzip等一系列编码绕过也就无从谈起。


    首先想到通过畸形http包来绕过,尝试LOL /sql.php?id=1 and 1=1HTTP/1.1等,发现基本都被服务器过滤了,说明tencent WAF 在开发时还是吸取了不少经验的。经过不断尝试发现畸形数据包,参数污染等方法均告失败。只能把主要精力放在mysql一些语法特性上了,下面的几种思路基本都是利用了mysql 自身语法特性来实现的。


    首先介绍一下Pax.Mac Team猥琐牛花开、若相惜的一种绕过思路——采用%a0绕过。id=-1 union%a0select 1,2。服务器检测了union和select之间是否含有空格,如果union select同时存在且还有空格则视为一次sql注入攻击行为。但是有许多方法可以进行绕过例如union/**/select、union%0dselect等,这里基本上都被过滤了,但是不知道是开发人员粗心还是故意放水,唯独留下了union%a0select 这个没有过滤。


    除了union%a0select似乎已经没有其他可以绕过检测的了,fuzz了一遍这次应该是真的了,但是功夫不负有心人,一种神奇的方法出现了——union/*%aa*/select。咦?这个不是属于/*xxx*/应该是被防护了的怎么还可以呢?这是中文字符的特性利用,中文字符配合注释符bypass 所有规则。利用%e4等只要是中文字符开头的,就可以完成绕过检测!%a0之类的,已经补了。测试发现。union select可以共存,只要让检测不要认识是union 空格select就行。所以这里这样构造出一个特别的字符串。我们通过union+“特殊字符”+select拼出一个新字符串,让正则认为这是个类似unionxxooselect这种,而不是union select 。 这样就能bypass检测。但是,要让数据库识别这个,就要想办法干掉这个多余的字符。服务在检测的时候,并不把/**/作为攻击特征,当然,这本身也不是特征,但是如果我们利用这个符号把这个多余的字符干掉,就可以让语句正常执行了。因为,这里就是利用union/*中文字符*/select,完全bypass。当然,还要保证这种中文字符不能构造一个汉字。这种方法来自于Pax.MacTeam团队的Conqu3r。


    以上两种方法均可以绕过union select,以及select from进行随心所欲的注入,后面介绍的这几种就比较鸡肋了,仅仅能绕过mysql函数限制进行loadfile,或者获取一些环境信息。


    由于WAF对敏感函数进行了检测,导致我们的version(),load_file()等函数无法使用,但是由于是正则匹配,我们可以使用% 0b进行轻松绕过。例如:version()% 0b(%和0b之间的空格是编辑显示需要,实际并不存在),其他的特殊字符均被过滤了,% 0b在这里成为了漏网之鱼。


    同样的绕过函数的思路,我们可以使用`version`()的方法再次避免WAF的正则匹配,由于mysql 语法特性`函数名`()等价于函数名()再一次完美bypass。绕过了函数名我们如何select呢?这里我们需要用到十六进制盲注:

    id=1 and(select `load_file`(0x2f6574632f706173737764) is not null)

    首先判断服务器某文件是否存在,例如这里我们用/etc/passwd文件。0x2f6574632f706173737764是/etc/passwd的十六进制格式。在判断确实存在该文件之后,我们可以通过:

    id=1 and(select `load_file`(0x2f6574632f706173737764)>0x726f66)

    根据页面返回修改大于号之后的十六进制值,从而获取到该文件的十六进制内容。


    最后一种思路是获取服务器的配置信息,通过id=instr(@@global.version,1)来获取global变量。@@global包含很多敏感信息,过滤了ascii,substr函数,仍可用instr来盲注。


    以上就是笔者对于本次tencent WAF 绕过挑战赛的一些总结和思考,不足之处还望大家积极指出,如果有其他绕过WAF的“奇技淫巧”也欢迎与我切磋交流。

  • 相关阅读:
    2016"百度之星"
    codeforces 55 div2 C.Title 模拟
    codeforces 98 div2 C.History 水题
    codeforces 97 div2 C.Replacement 水题
    codeforces 200 div2 C. Rational Resistance 思路题
    bzoj 2226 LCMSum 欧拉函数
    hdu 1163 九余数定理
    51nod 1225 余数的和 数学
    bzoj 2818 gcd 线性欧拉函数
    Codeforces Round #332 (Div. 2)D. Spongebob and Squares 数学
  • 原文地址:https://www.cnblogs.com/dongchi/p/4067953.html
Copyright © 2011-2022 走看看