某次SQL注入绕WAF的经历
渗透测试
一次同时绕过代码层过滤和云WAF的SQL注入记录
**0x01** **基友你好** ----------------- 说来你说巧不巧,刚好干完客户的项目,就看到基友的消息。难道,这就是传说中的心有灵犀?  那么,我们得到了基础消息,有过滤和WAF:  既然是通用,虽然说这里失败了,但我们先用这个Payload打过去看看什么情况,不行再构造:  好的,响应中有回显报错信息,那么我们观察对比一下就会发现,关键词select、from、where均被过滤掉了:  **0x02** **注入探测** ----------------- 先用我们的插件探一手,看什么情况,不行我们再深入构造一下子Payload进行测试:  我们可以看到在order by判断1和300的时候,响应是不同的,那么我们手动发包来看一下具体情况:  判断1列正常,超出列数就会报找不到:  是的,就只有1列…而且model的值会拼接到默认表名前缀里作为最终表名:  也就是说model如果乱赋值,在拼接后数据库里没有这个表名的话,会报错找不到表名,此时直接无缘注入:  所以在不知道其他表名的情况下,这个值只能是news,它必然存在!为什么?因为是加载功能时默认赋值的…  **0x03** **开始注入** ----------------- 通过前面的内容,我们得知系统在代码层有关键词过滤。这里的话,我想看下sleep函数是否可用:  嗯,拉闸了。同时在此处省略大量测试步骤,很多函数都用不了,要么被代码层过滤,要么被WAF拦截:  甚至,内联注释直接拦掉:  **0x04** **构造语句** ----------------- 经过我的探测,case when是可以用的,此时我已经看到八成希望了,那我们如何进行构造呢?  通过前面内容能看到,order by是可以用的,我们可以通过它来拼接case when构造Payload实现注入: ```php '+ORDER+BY+CASE+WHEN+(1=2)+THEN+exp(710)+ELSE+1+END--+ ```  但是不对劲,正常来说1=1和1=2返回应该是不一样的。但实际上…返回的结果一样,那完全不对啊:  没事,小问题。其实我们构造的语句,聪明的小伙伴已经看出来这很明显是排序注入Payload了:  所以我们照着排序注入的手法来,把1随便先改成字符串内容,然后另外一个结果我们让他返回exp(710),让他产生报错:  此时返回的内容就不一样了,现在报错的是没有找到a这个列名。想要实现注入,我们还需要找到一个存在的列名:  去哪找呢?FUZZ参数?大错特错,你睁眼看一下响应里面的报错,这不是列名是什么?  所以,此时的Payload是: ```php '+ORDER+BY+CASE+WHEN+(1=2)+THEN+exp(710)+ELSE+hits+END--+ ```  没毛病,跟我的预期结果是一样的。此时我再把判断条件改成1=1,就应该返回exp函数的结果,也就是报错:  没毛病啊,成功一半了:  **0x05** **最后冲刺** ----------------- 接下来,先看length函数能不能用:  length能用不意外,database居然也没拦:  OK,跑一下具体库名长度:  这里还是可以得出来长度是8,但是为什么有302状态码的结果呢?  不知道是WAF还是代码层,反正访问速率过快就会触发302重定向。所以我们后续如果用BP跑的话,如果跑完发现结果不对劲,就需要调整一下爆破时的速率了:  OK,直接拿下了就是说:  没毛病帖子,下机了: 
发表于 2026-03-30 09:19:14
阅读 ( 3219 )
分类:
漏洞分析
3 推荐
收藏
0 条评论
犀利猪安全
1 篇文章
×
温馨提示
您当前没有「奇安信攻防社区」的账号,注册后可获取更多的使用权限。
×
温馨提示
您当前没有「奇安信攻防社区」的账号,注册后可获取更多的使用权限。
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!