官网
-
安装
3. 为了方便使用,可以添加环境变量
-
使用
-
下载CodeQL的demo文件
git clone --recursive https://github.com/github/vscode-codeql-starter/
TIPS:这里需要带上 --recursive 参数
下载完成后,在vscode中 open object
-
进入到待审计代码的目录下,创建CodeQL数据库
codeql database create <database> --language=<language-identifier>
-
<database>
:要创建的新数据库的路径。执行命令时将创建此目录,无法指定现有目录。 -
--language
:用于为其创建数据库的语言的标识符。 -
VScode 中侧边栏打开 CodeQL, add a codeql database :From a folder,选择数据库目录即可
-
找到对应语言的 Demo ql文件,右键 -> Run Query
-
云平台
-
选择语言类型
这里有许多的测试项目,也可以打开Github上的开源项目
更多语法查询见官网:https://codeql.github.com/codeql-standard-libraries/
from /* ... 变量声明... */
where /* ... 逻辑公式 ... */
select /* ... 表达式 ... */
eg.
from int a, int b
where a = 1 and b = 2
select a + b
TIPS:需要注意的是,from 语句只声明变量,不赋值
上述的 Demo 仅仅是最基本的语法,QL语句还支持定义谓词、类等。除此之外,还有相关聚合操作等,在此就不做赘述。
var param = unescape(location.hash);
document.write(param);
获取 location.hash 的值,并直接document.write输出
-
编写QL语句查找 Sink import javascript
from Expr dollarArg,CallExpr dollarCall
where dollarCall.getCalleeName() = "write" and
dollarCall.getReceiver().toString() = "document" and
dollarArg = dollarCall.getArgument(0)
select dollarArg查找函数名为 write,同时输出第一个参数
-
根据Sink输出的参数,编写QL语句查找Source
import javascript
from CallExpr dollarCall
where dollarCall.getCalleeName() = "unescape" and
dollarCall.getArgument(0).toString() = "location.hash"
select dollarCall查找调用的函数名为
unescape
,同时第一个参数为 location.hash
class XSSTracker extends TaintTracking::Configuration {
XSSTracker() {
// unique identifier for this configuration
this = "XSSTracker"
}
override predicate isSource(DataFlow::Node nd) {
exists(CallExpr dollarCall |
nd.asExpr() instanceof CallExpr and
dollarCall.getCalleeName() = "unescape" and
dollarCall.getArgument(0).toString() = "location.hash" and
nd.asExpr() = dollarCall
)
}
override predicate isSink(DataFlow::Node nd) {
exists(CallExpr dollarCall |
dollarCall.getCalleeName() = "write" and
dollarCall.getReceiver().toString() = "document" and
nd.asExpr() = dollarCall.getArgument(0)
)
}
}
from XSSTracker pt, DataFlow::Node source, DataFlow::Node sink
where pt.hasFlow(source, sink)
select source,sink
-
定位source
通过 Params 函数获取参数,直接定位到相应的调用
import go
private class Mysource extends DataFlow::Node{
Mysource(){
exists( DataFlow::CallExpr call|call.getCalleeName().toString() = "Params"| call =this.asExpr())
}
}
from Mysource s
select s -
定位 sink
private class Mysink extends DataFlow::Node{
Mysink(){
exists( Function f,CallExpr call |f.hasQualifiedName("os", "Open") and call.getTarget() = f and call.getAnArgument()
=this.asExpr())
}
} -
套进模板里,查找调用链
import go
import semmle.go.security.TaintedPathCustomizations::TaintedPath
import DataFlow::PathGraph
private class Mysource extends DataFlow::Node{
Mysource(){
exists( DataFlow::CallExpr call|call.getCalleeName().toString() = "Params"| call =this.asExpr())
}
}
private class Mysink extends DataFlow::Node{
Mysink(){
exists( Function f,CallExpr call |f.hasQualifiedName("os", "Open") and call.getTarget() = f and call.getAnArgument()
=this.asExpr())
}
}
class Configuration extends TaintTracking::Configuration{
Configuration(){ this = "xxx"}
override predicate isSource(DataFlow::Node source) { source instanceof Mysource }
override predicate isSink(DataFlow::Node sink) { sink instanceof Mysink }
}
from Configuration cfg, DataFlow::PathNode sink, DataFlow::PathNode source
where cfg.hasFlowPath(source, sink)
select sink.getNode(),source,sink,"file travel logic path is @",source.getNode(),"Here"
原文始发于微信公众号(SAINTSEC):利用CodeQL进行源代码安全审计
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论