codeql_zero_to_hero 学习
https://github.com/GitHubSecurityLab/codeql-zero-to-hero
Challenge 1
Enable code scanning with CodeQL on a public repository
方法一 直接fork出来一个仓库,然后直接用codeql扫
按下列步骤操作即可
选default
进入到下面的页面,然后Enable CodeQL
跳转到新的界面
往下滑就会看到这里,表示已经开始扫了,一般过几分钟就会出结果
方法二 fork 其他的仓库,并使用codeql进行扫描
这里我们以imagemagic
为例
这里需要注意的一个点是删除上图.github
中的workflows
目录,原因如下:
GitHub Actions
(自动化测试工具)会在代码库中定义工作流(workflows),如自动化测试、构建、部署等。工作流通常定义在 .github/workflows/
目录中,以 .yml
文件形式存在。
当 fork 一个开源项目的代码仓库时,其中的 Actions 工作流默认是被 禁用 的。这是出于 安全考虑,主要有以下原因:
1. 防止恶意代码执行:
• 原仓库的工作流可能包含危险命令(如删除文件、窃取密钥等),fork 后自动运行可能带来安全隐患。
2. 防止意外消耗资源:
• GitHub Actions 有免费使用限制(如 Actions minutes),自动运行可能消耗不必要的时间配额。
删除后 Actions 中开启 workflow
然后进入Security重复方法一中的操作。
References:
https://github.blog/developer-skills/github/codeql-zero-to-hero-part-2-getting-started-with-codeql/
Challenge 2
Set up VS Code CodeQL starter workspace
在vscode的扩展中安装codeql,安装完之后打开终端,创建一个测试文件夹用来使用,之后命令如下:
1 | $ git clone https://github.com/github/vscode-codeql-starter.git |
然后在 VS Code 中依次点击 File -> Open Workspace from File… vscode-codeql-starter.code-workspace
,界面如下:
后面进入到如下界面然后点击圆框中的图标,输入GitHubSecurityLab/codeql-zero-to-hero
回车。
回到 workspace folder中的 codeql-custom-queries-python
文件夹下,创建一个新的文件 test.ql,添加下面的内容 select "Hello World!"
,点击运行就会出现我们所需的结果。
Challenge 3
Create CodeQL database using CodeQL CLI locally
1 | gh extensions install github/gh-codeql |
进入到 VS Code CodeQL 扩展, 点击 “Choose Database from folder” 然后选中刚刚创建的 “example-codeql-db”
CodeQL基本用法
CodeQL 查询的基本语法和结构类似于 SQL 语法,由三个语句组成from
——、where
和select
,描述了我们要查找的内容。
from
定义要查询的类型和变量。where
以逻辑公式的形式定义这些变量的条件。where
如果没有条件,可以省略。select
定义查询的输出。
Challenge 4
选定 challenge 3 中创建的数据库,然后回到vscode工作目录,在codeql-custom-queries-python
中创建call.ql
,输入以下内容:
1 | import python |
1. import python
这一行表明查询要分析的是 Python 源代码,并导入了与 Python 分析相关的 CodeQL 模块。
CodeQL 支持多种语言(如 Java、C++、JavaScript 等),通过 import 来选择目标语言模块。
2. from Call call
Call
是 CodeQL 中的一个类,用于表示代码中的函数调用点。
call
是一个变量名,它代表查询时匹配到的函数调用点实例。
from Call call
的作用是从 CodeQL 数据库中选出所有属于 Call 类的函数调用点。
3. where call.getLocation().getFile().getRelativePath().regexpMatch(“2/challenge-1/.*“)
这一行定义了查询的条件,逐步解释如下:
call.getLocation()
:获取函数调用点所在的位置(location),例如代码的行号、文件等。
getFile()
:从位置中获取调用点所在的文件。
getRelativePath()
: 获取文件的相对路径(相对于项目根目录)。
regexpMatch("2/challenge-1/.*")
: 使用正则表达式匹配文件路径。
最终结果如下:
精确 QL 查询
1 | import python |
其中 Name
表示指向代码中的所有变量名,Call
表示指向所有方法调用,这里分别用 c,name表示,同时 QL 支持三种逻辑操作 and
,or
,not
。
这里主要引入了内容name.getId() = "eval" and c.getFunc() = name
,表示这里只关心 eval
这个方法调用。
Challenge 5
将上面的代码跑一遍,找到eval方法调用的位置
Challenge 6
1 | import python |
这个主要是用来实现搜索特定函数,比如在python中我们以def func
定义的函数,注意要与Call
进行区分。
Predicates
1 | predicate <name>(<variable type>:<variable name>) { |
Challenge 7
1 | import python |
这里定义了一个谓词 predicates 逻辑,其实就是将先前的两个判断逻辑加入到了里面,并进行了一个简单的封装并方便我们进行重用,结果依然与先前的结果一致。
Class
1 | class <name> extends <type> { |
每一个扩展类都应该配备一个父类,在下面的例子中就是 Call
,其中 this
表示的就是 Call
实例。
由于这里引入类之后,name变量不在存在,所以这里需要exists()
进行构造,它允许我们定义局部变量。首先定义局部变量,然后用竖线 将它们与条件分开|
。接下来的所有条件都可以用|
或 and
,形式如 exists( | | )
,比如 exists(Name name | this.getFunc() = name | name.getId() = "eval")
Challenge 8
1 | import python |
Challenge 9
简单把前面的知识过了一遍
1 | import python |
Challenge 10
Query the AST
这里一开始把我搞懵了,因为我没有找到所谓的 source archive,后面通过一通探索,操作如下:
首先找到我们建立的database,然后右键Add Database Source...
这时候我们就可以在工作目录中找到source archive
,然后选一个想查看AST的源码文件,右键点击Code QL: View AST
即可。
Challenge 11
需要学习codeql文档:https://codeql.github.com/docs/writing-codeql-queries/ql-tutorials/
一些聚合词学习
例子 | 结果 |
---|---|
`min(Person p | p.getLocation() = “east” |
`count(Person p | p.getLocation() = “south” |
`avg(Person p | |
`sum(Person p | p.getHairColor() = “brown” |
这里 override 可以用来覆盖原Person
中的isAllowedIn
方法
1 | class Child extends Person { |
Predicate | Description |
---|---|
parentOf(Person p) |
returns a parent of p |
我们知道国王自己没有孩子,但也许他有兄弟姐妹。写一个查询来找出答案:
1 | from Person p |
他确实有兄弟姐妹!但你需要检查他们中是否有人还活着……以下是你可能还需要的一个谓词:
Predicate | Description |
---|---|
isDeceased() |
holds if the person is deceased |
使用这个谓词来查看国王的兄弟姐妹是否还活着。
1 | from Person p |
不幸的是,巴西尔国王的兄弟姐妹都不在世了。
Challenge 12
随便找一个 security queries
运行就可以了python/ql/src/Security/CWE-089/SqlInjection.ql
- Title: codeql_zero_to_hero 学习
- Author: henry
- Created at : 2024-12-11 14:09:13
- Updated at : 2024-12-11 14:20:42
- Link: https://henrymartin262.github.io/2024/12/11/codeql_note/
- License: This work is licensed under CC BY-NC-SA 4.0.