基础QL语法

CodeQL的查询语法有点像SQL,如果你学过基本的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

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

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

所有方法:

import javafrom Method method
select method

我们再通过Method类内置的一些方法,把结果过滤一下。比如我们获取名字为 CommandExec 的方法名称。

import javafrom Method method
where method.hasName("CommandExec")
select method.getName(), method.getDeclaringType()

谓词

和SQL一样,where部分的查询条件如果过长,会显得很乱。CodeQL提供一种机制可以让你把很长的查询语句封装成函数。

这个函数,就叫谓词。

比如上面的案例,我们可以写成如下,获得的结果跟上面是一样的:

import javapredicate isStudent(Method method) {
exists(|method.hasName("getStudent"))
}from Method method
where isStudent(method)
select method.getName(), method.getDeclaringType()

语法解释

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

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

设置Source和Sink

什么是source和sink

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

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

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

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

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

设置Source

在CodeQL中我们通过这个格式去设置

override predicate isSource(DataFlow::Node src) {
具体方法。。。
}

例如

正常的Spring Boot 框架

@RequestMapping(value="/list",method = {RequestMethod.GET, RequestMethod.POST})@ResponseBodypublic ResultData list(@ModelAttribute @ApiIgnore CategoryEntity category, HttpServletResponse response, HttpServletRequest request, @ApiIgnore ModelMap model, BindingResult result) {BasicUtil.startPage();List categoryList = categoryBiz.query(category);return ResultData.build().success(new EUListBean(categoryList,(int) BasicUtil.endPage(categoryList).getTotal()));}

本例中我们设置Source的代码为:

override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource }

这是SDK自带的规则,里面包含了大多常用的Source入口。我们使用的SpringBoot也包含在其中, 我们可以直接使用。

注: instanceof 语法是CodeQL提供的语法,后面在CodeQL进阶部分我们会讲到。

设置Sink

在CodeQL中我们通过 isSink

override predicate isSink(DataFlow::Node sink) {具体方法。。。
}

这里的 sink我们就正常的去定义一个construtorCall,然后这个construtorCall限定在processBuilder下就行。

codeql官方有一个ExternalProcess.qll库里面有一个ArgumentToExec类,这个类会覆盖到这个sink

那么就直接写一个

override predicate isSink(DataFlow::Node sink) {sink.asExpr() instanceof ArgumentToExec
}

这样就设置了一个命令执行的 Sink

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,系统就会自动帮我们判断是否存在漏洞了。

这一段其实基本上都是固定的,都是从Source到sink,不必深究。

简单demo

/*** @id java/examples/vuldemo* @name Rce* @description Rce* @kind path-problem* @problem.severity warning*/import java
import semmle.code.java.dataflow.FlowSources
import DataFlow::PathGraphclass VulConfig extends TaintTracking::Configuration {VulConfig() { this = "rceConfig" }override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource }override predicate isSink(DataFlow::Node sink) {sink.asExpr() instanceof ArgumentToExec}
}from VulConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select source.getNode(), source, sink, "source"

isSanitizer方法

从上面的demo中存在的一个数据,就是误报,这个参数其实是通过了安全函数过滤了,但是还是扫出来了,这种情况就得消除这种误报。就得使用isSanitizer

isSanitizer是CodeQL的类TaintTracking::Configuration提供的净化方法。

override predicate isSanitizer(DataFlow::Node node) {exists(...)
}

isAdditionalTaintStep方法

isAdditionalTaintStep方法是CodeQL的类TaintTracking::Configuration提供的的方法,它的原型是:

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

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

批量检测命令

CodeQL除了提供VSCode的检测插件,也提供了大量的命令行,来实现项目的集成检测。

比如:

codeql database analyze /Users/zy/Documents/project/codeql/vscode-codeql-starter-main/database/codeql_java-sec-code /Users/zy/Documents/project/codeql/vscode-codeql-starter-main/ql/java/ql/src/codeql-suites/java-security-extended.qls --format=csv --output=java-results.csv

查询制定类的的方法

import javafrom Method method
where method.hasName("Deserialize")
and
method.getDeclaringType().hasQualifiedName("org.joychou.controller", "Fastjson")select method

根据Method name 和 interface name 查询

比如我想查询ContentTypeHandler 的所有子类toObject方法

import javafrom Method method
where method.hasName("toObject") and method.getDeclaringType().getASupertype().hasQualifiedName("org.apache.struts2.rest.handler", "ContentTypeHandler")
select method

CodeQL基础语法相关推荐

  1. FPGA(2)基础语法 -- 按键控制led(alway@语句)

    目录 1.module 文件名(端口) 2.声明关键字 3.always@语句 代码 1.module 文件名(端口)  注:这里最好养成习惯,只在文件名后面的括号中声明引脚变量,输入输出.关键字类型 ...

  2. javascript基础语法——表达式

    前面的话 一般地,关于javascript基础语法,人们听得比较多的术语是操作符和语句.但是,其实还有一个术语经常使用,却很少被提到,这就是javascript表达式(expression).本文将详 ...

  3. Rust语言开发基础(六)基础语法

    2019独角兽企业重金招聘Python工程师标准>>> 一.变量的定义和使用 其它常见的编程语言对变量的定义通常是通过声明类型和使用关键new来创建一个变量,但Rust不是,Rust ...

  4. python列表嵌套字典取值_Python基础语法:你不得不知的几种变量类型

    (点击上方快速关注并设置为星标,一起学Python) 作者:kina_chen來源:简书 01. Python编码Python中默认的编码格式是 ASCII 格式,在没修改编码格式时无法正确打印汉字, ...

  5. python赋值语句的一般格式为_Python 基础语法

    Python 基础语法 Python 语言与 Perl,C 和 Java 等语言有许多相似之处.但是,也存在一些差异. 在本章中我们将来学习 Python 的基础语法,让你快速学会 Python 编程 ...

  6. 深入浅出CMake(二): 基础语法

    在<深入浅出CMake(一):基础篇>文章中,我们已经知道了怎么依葫芦画瓢编写简单的 CMake 构建文件了,但如果应对复杂的工程的话,这还是远远不够的. CMake 是一套编译构建体系, ...

  7. Python基础语法学习笔记

    Python基础语法学习笔记 想淘宝省钱看我简介,博客www.liangxin.name (一) 一.Print()函数 1.数字可以直接输出,无需加引号 只能理解数字,却读不懂文字.因为数字和数学运 ...

  8. Python的零基础超详细讲解(第三天)-Python的基础语法

    多行语句 Python 通常是一行写完一条语句,但如果语句很长,我们可以使用反斜杠 \ 来实现多行语句,例如: duohang = item_one + \item_two + \item_three ...

  9. Python的零基础超详细讲解(第二天)-Python的基础语法1

    Python 基础语法 打开python的编辑器 这里注意的是,之前下载的python在电脑主页上没有快捷方式,需要在win开始界面中打开 最终打开效果是一个白色的跟终端类似的编辑器,我们输入的时候是 ...

最新文章

  1. python【蓝桥杯vip练习题库】BASIC-20 数的读法
  2. [:zh]<界面编程>任务二 用户注册界面设计[:]2018-01-24
  3. UDP(首部)和TCP(首部、三次握手、四次挥手、可靠传输、滑动窗口、流量控制、拥塞控制(慢开始、拥塞避免、快重传、快恢复))
  4. 洛谷——P1342 请柬
  5. html模板 循环里if,django模板里循环变量table里想要两个一行如何控制
  6. 中文字体其实也可以用在网页上的
  7. 解决Failed to load the JNI shared library xxx/xxx/jvm.dll 错误
  8. IEC_60068-2-64基本环境试验规程第2-64部分试验试验Fh振动、宽带随机抽样
  9. 《怎样解题》读书笔记
  10. Word中插入分隔线
  11. 德保罗大学计算机科学专业,德保罗大学专业
  12. 苹果html 闪退,iPhone6 App闪退的解决办法 掌握这4点苹果App不再闪退
  13. 五猴分桃python_猴子分桃问题 | 学步园
  14. 兰德系数(Rand Index)
  15. DbVisualizer 解决中文乱码问题
  16. SQL Server事务日志分析
  17. css内行样式、外部样式、内部样式
  18. Manifest merger failed with multiple errors问题解决
  19. Python实现电话号码的数字组合
  20. R绘图基础指南 | 2.折线图

热门文章

  1. 虚拟创业云|BBC幼儿英语启蒙动画Nina and the Neurons妮娜和神经元
  2. 计算机预测自己未来的相貌,新软件30秒预测未来样貌 完全可以以假乱真
  3. 【IoT】创业:智能硬件企业如何开始?
  4. 【送内裤】千奈美 专柜正品 深V挂脖聚拢调整型文胸 中小胸内衣-tmall.com天猫...
  5. 反馈线性化类有哪些最新发表的毕业论文呢?
  6. 简单有效的科学健脑方法
  7. 金融监管背后有何真实意图?“数字人民币”是真正的金融创新吗?
  8. 决议要素_2006年决议-准备
  9. SRMUVS-100VAC-2H2D电压继电器
  10. 安东尼罗宾--激发你的无限潜能[连载]--11 12章