CodeQL基本语法

基础QL语法

CodeQL的查询语句比较像SQL

结构

import java // 导入使用的库

from int i /* ... 变量声明... */
where i = 100 /* ... 逻辑公式 ... */
select i /* ... 表达式 ... */

解析

import java,导入使用的库,因为分析的项目是java的

from int i,表示我们定义一个变量i,它的类型是int,表示获取所有的int类型的数据;

where i = 100, 表示当i等于1的时候,符合条件;(这是= 是一个等于的意思 == ,不是赋值)

select i,就是输出 i

结果

image-20230529161859865

常用类库

经常会用到的ql类库大体如下:

名称 解释
Method 方法类,Method method表示获取当前项目中所有的方法
MethodAccess 方法调用类,MethodAccess call表示获取当前项目当中的所有方法调用
Parameter 参数类,Parameter表示获取当前项目当中所有的参数

以查询所有方法为例

结构

import java

from Method method
select method

结果

image-20230529162753328

这个项目被查询到的方法有46361个,显然这个结果太多了,那么接下来就要进行过滤的操作了

过滤

和sql语句一样,想要对查询结果进行过滤可以使用where语句

获取名字为 getValue的方法名称。

结构

import java

from Method method
where method.hasName("getValue")
select method.getName(), method.getDeclaringType()

结果

image-20230529163134385

谓词

在进行过滤的时候显然不会是一段简单的语句,经常来说会是一段很长的语句,CodeQL提供一种机制可以让你把很长的查询语句封装成函数。

这个函数在CodeQL中交过谓词。

上面的过滤示例可以进行如下改写:

结构

import java

predicate hasgetValue(Method method) {
    exists(|method.hasName("getValue"))
}

from Method method
where hasgetValue(method)
select method.getName(), method.getDeclaringType()

解析

predicate 表示当前方法没有返回值。

exists子查询,是CodeQL谓词语法里非常常见的语法结构,它根据内部的子查询返回true or false,来决定筛选出哪些数据。

结果

image-20230529163825422

污点分析

使用CodeQL进行审计,污点分析肯定是要的

什么是source和sink

在代码自动化安全审计的理论当中,有一个最核心的三元组概念,就是(source,sink和sanitizer)。

source是指漏洞污染链条的输入点。比如获取http请求的参数部分,就是非常明显的Source。

sink是指漏洞污染链条的执行点,比如SQL注入漏洞,最终执行SQL语句的函数就是sink(这个函数可能叫query或者exeSql,或者其它)。

sanitizer又叫净化函数,是指在整个的漏洞链条当中,如果存在一个方法阻断了整个传递链,那么这个方法就叫sanitizer。

只有当source和sink同时存在,并且从source到sink的链路是通的,才表示当前漏洞是存在的。

image-20220313165135513

设置Source

override predicate isSource(DataFlow::Node source) {
    exists(....)
  }

设置Sink

override predicate isSink(DataFlow::Node sink) {
    exists(....)
  }

Flow数据流

设置好Source和Sink后,如果一个受污染的变量,能够毫无阻拦的流转到危险函数,就表示存在漏洞。

from VulConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select source.getNode(), source, sink, "source"

我们传递给config.hasFlowPath(source, sink)之前定义好的source和sink,系统就会判断是否存在漏洞了。

isAdditionalTaintStep方法

在有些情况下CodeQL在检测的时候会将两个节点认为是不连通的,这就需要我们人为设置他们是连通的

isAdditionalTaintStep方法是CodeQL的类TaintTracking::Configuration提供的的方法

作用

将一个可控节点A强制传递给另外一个节点B,那么节点B也就成了可控节点。

原型

override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
    isTaintedString(node1.asExpr(), node2.asExpr())
  }
}

误报解决(净化函数)

在分析的时候会发现有的调用链不存在漏洞

这就属于误报,那么我们就需要消除误报,消除的方法就是利用isSanitizer函数,重写TaintTracking::Configuration中的isSanitizer函数,当流到达这个节点后中断

instanceof

和java类似,比如sink instanceof QueryInjectionSink表示判断sinkQueryInjectionSink类型

我们要实现这种机制,只需要创建一个abstract抽象类,如下图,不过这里和java的抽象类有区别,只要我们的子类继承了这个类,那么所有子类都会被调用

递归

CodeQL里面的递归调用语法是:在谓词方法的后面跟*或者+,来表示调用0次以上和1次以上(和正则类似),0次会打印自己。

类型过滤

CodeQL通过.(type)进行类型过滤,可以理解成filter,它的意思是将前面的结果符合Type的数据保留

.(RefType),就是保留RefType类的内容

lombok

开发过java的应该都清楚,由于java的封装特性,每一个变量都要写settersetter很麻烦,所以就有了lombok,引入以来后通过@Data注解就可以自动实现gettersetter(不是自动补全代码的方式实现)

但是codeql不能识别lombokgettersetter,所以可能存在问题也发现不了,因此用codeql分析代码的时候,如果存在lombok,那么可以通过如下的方法快速还原settergetter方法,来自github issue

# get a copy of lombok.jar
wget https://projectlombok.org/downloads/lombok.jar -O "lombok.jar"
# run "delombok" on the source files and write the generated files to a folder named "delombok"
java -jar "lombok.jar" delombok -n --onlyChanged . -d "delombok"
# remove "generated by" comments
find "delombok" -name '*.java' -exec sed '/Generated by delombok/d' -i '{}' ';'
# remove any left-over import statements
find "delombok" -name '*.java' -exec sed '/import lombok/d' -i '{}' ';'
# copy delombok'd files over the original ones
cp -r "delombok/." "./"
# remove the "delombok" folder
rm -rf "delombok"
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇