您现在的位置是:首页 > 文章详情

教你怎么开发一个基于java的语义waf

日期:2021-06-21点击:713

今天在看腾讯介绍自己jdk的文章,其中提到了腾讯的waf是java写的,所以到github上搜索了一下,发现了一个java开发的语义waf

https://github.com/Kanatoko/libinjection-Java

这个项目的作者实在是太强了,使用的是libinjection的开发思路,所以我拿来研究了一下,产生了本文。

首先我写了一个有sql注入的接口如下,代码逻辑是name是sql拼接点,如果sql被库识别为sql注入,那么就直接拦截掉。

其中的我们要注意,因为本次是研究性质的,所以我会用sqlmap直接跑这个接口,对未发现的payload直接在 Dirty SQLi found 中打印出来。

 @RequestMapping("list2") public User getList2(String name) { //sql语句是 "select * from user where name='${name}'" if (name == null) { name = "dato"; } boolean isSQLi = com.client9.libinjection.SQLParse.isSQLi(name); if (isSQLi) { return userMapper.getUserByName3("dato"); } // 如果没有发现sql注入,则打印sql语句 System.out.println("Dirty SQLi found : " + name); return userMapper.getUserByName3(name); }

好,我们开始跑sqlmap了

 ./sqlmap.py -u "http://localhost:8082/list2?name=dato" --dbs -v 3 --level=5 --risk=3 -p name --dbms mysql

很遗憾已经出现了可以注入的payload

其中最终导致注入的 payload 是

[PAYLOAD] dato' AND GTID_SUBSET(CONCAT(0x71716a7171,(SELECT MID((IFNULL(CAST(schema_name AS NCHAR),0x20)),1,190) FROM INFORMATION

因为百度上分析libinjection的原理文章实在是太多了,我就不在这里反复写了

依照网上文章的解析可以发现,默认规则里少了一个GTID_SUBSET函数,所以我们需要在 SQLParse.java 增加这个函数的策略

加完这一行以后我们再试试,yeah!没办法注入了!

那么我们继续分析一下日志,上文我提到,我会把sqlmap投入的payload中没有拦截的打印在 Dirty SQLi found 中

所以我们可以看到很多类似于下图中的打印内容(数量太多,我只能讲一部分了)

很明显,一些探测是否是sql注入的payload还是很容易被放过去

所以我认为语义waf的趋势:

1)语义waf可以与rasp进行一次嵌入。因为rasp可以获取的输入数据都是层层转码后的数据,可以有效的避免各种sql绕过的手法。而且转码后再使用语义进行分析可以大大增加防护作用并减少整个系统的算力支出,所以将语义策略嵌入rasp是未来很好的降本增效的设计。

2)openrasp本身就存在常见的sql注入屏蔽策略,与我分析的sqlmap注入日志中部分payload是重合的,尤其是openrasp可以屏蔽sql报错,这本身就能防护住较多的sql注入场景。尤其是sql注入前期探测阶段时如果rasp屏蔽了sql报错,可以大大增加攻击者进行sql注入的难度。

没有kpi吗?本文又给了你们思路了哦。

禁止转载

原文链接:https://my.oschina.net/9199771/blog/5085337
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章