△△△点击上方“蓝字”关注我****们了解更多精彩
以java-sec-code为例子,对CodeQL提供的官方规则进行修改优化,更契合项目本身的规则。
在官方的规则下
\ql\src\experimental\Security\CWE\CWE-089
有个是关于MyBatisMapper注入规则,现在我们看下效果如何
可以看到,一共找到了9个注入点,那我们去看看这9个是不是都是注入点,人工验证一下。
在CodeQL的插件这里,右键点击我们导入的数据库,将源码添加到我们的工作区
接下来就会在工作区发现我们的java项目
点进Controller目录,找到对应的类右键View AST,通过语法树有助于我们学习CodeQL语法,更好理解规则编写,不然老感觉很空,没具体效果。
原本是在左下角,有点小,看得很麻烦,可以直接拖到控制台,放大看我们可以看到,刚刚好有9个,那就是CodeQL官方规则扫描发现这9个都存在注入,实际上并不是全部存在注入,明显存在误报,所以接下来我们要对官方的规则进行优化。
分析一下MyBatisMapperXmlSqlInjectionLib
,在
\ql\java\ql\src\experimental\Security\CWE\CWE-089
这里,点击Quick Evaluation进行查询
这段查询语句,在 MyBatisMapperMethodCallAnArgument
构造函数使用了exists
关键字,其作用是在CodeQL查询中定义存在某种关联关系或满足某种条件的情况,从而影响查询结果。
在 exists
中,定义了两个变量 MyBatisMapperSqlOperation mbmxe
和 MethodCall ma
,它们分别表示 MyBatis 映射器的 SQL 操作和方法调用。
mbmxe.getMapperMethod() = ma.getMethod()
指定了 mbmxe
的映射方法与 ma
的调用方法相匹配。
ma.getAnArgument() = this.asExpr()
指定了方法调用m*
的一个参数与当前实例相匹配。
最终结果如下:找到了调用MyBatis Mapper
的sink
但是从这个结果看来存在着对应的问题,就是可以看到,这个传参的类型的Integer类型,这种是不可能存在注入的
还有就是使用了filter进行过滤,此时我们也需要对其进行排除在外
这时候就需要用到我们的isSanitizer
方法,isSanitizer是CodeQL的类TaintTracking::Configuration提供的净化方法。
它的函数原型是:override predicate isSanitizer(DataFlow::Node node) {},
其实在函数原型中已经对基础类型进行了判断(忘记在哪个qll下面了,有空找找),
这里直接使用了freebuf师傅上写的规则(妙啊,前人栽树后人乘凉,怪偷)。
CodeQL从入门到放弃 - FreeBuf网络安全行业门户
override predicate isSanitizer(DataFlow::Node sink){
查找一个executeQuery()方法的调用点,并把它的第一个参数设置为sink
predicate querySink(DataFlow::Node sink) {
最终结合语句如下:找到了三处存在注入的点,
注意:
由于我们引用了import MyBatisMapperXmlSqlInjectionLib
所以必须要与MyBatisMapperXmlSqlInjectionLib.qll
同级目录
import java
https://www.freebuf.com/articles/web/283795.html
END
如您有任何投稿、问题、需求、建议
请NOVASEC公众号后台留言!
或添加 NOVASEC 联系人
感谢您对我们的支持、点赞和关注
加入我们与萌新一起成长吧!
本团队任何技术及文件仅用于学习分享,请勿用于任何违法活动,感谢大家的支持!!