弈 - Codeql 自动运行和项目监控工具

前言

代码审计总是离不开一些神器,笔者常用 Codeql[1] 这款工具辅助挖洞。当我每写一个规则都需要对其它项目手动运行检查一遍,效率很低,再加上 lgtm[2] 的关闭,此项目诞生了 --- 弈(Yi)[3] 。

CVE-2021-43798

这里以 Graana 的任意文件读取漏洞举例说明使用方法(初学 Codeql,如有错误之处,轻点喷)。

该漏洞版本为 8.0.0 - 8.3.0 , 修复版本为 8.3.1, 8.2.7, 8.1.8, 8.0.7。

git clone https://github.com/grafana/grafana
git checkout v8.2.6

这个漏洞发生在 /public/plugins/:pluginId/* api 中,当输入的 pluginId存在时,会匹配*内容,使用filepath.Clean清理路径中的多余字符后,直接拼接到pluginFilePath,然后使用os.open(pluginFilePath)打开该文件,最终回显到页面。而且plugins api权限为public,是未授权的,任何人都可以查看。

图片

fmt.Println(filepath.Clean("./.../../../../../../../etc/passwd"))

输出:../../../../../etc/passwd 只清除了前面的./.../../

Codeql分析

生成 codeql 数据库:

codeql database create /Users/yhy/CodeQL/database/go/grafana/v8.2.6 -s ./ --language=go

sink

os.open(),这个显而易见。

import go
import DataFlow::PathGraphclass Sink extends DataFlow::Node {Sink() {exists(DataFlow::CallNode call |call.getTarget().hasQualifiedName("os", "Open") |call.getArgument(0) = this // 标记 sink 为 os.Open 第一个参数)}
}

图片

 

source

我将 Source 点定在了macaron.Params()函数。

网上的文章都是以github.com/grafana/grafana/pkg/api/routing.RouteRegister作为起始点,这就导致一个问题,写完的规则只对grafana项目起作用,不通用。

仔细研究会发现,RouteRegister的实现是以gopkg.in/macaron.v1框架为基础的,但是官方的go/ql/lib/semmle/go/frameworks/Macaron.qll,只是实现了一个重定向相关的检测规则,emmm,只能自己动手写了。

写着写着忽然发现,怎么也获取不到macaron.Params, 去看 macaron[4] 源码才发现,这个函数就根本没有,是Grafana自己实现的。我们来分析一下这个 Params 函数。

图片

其实就是获取net/httpRequest.Context的值,而参数r,又是通过pkg/macaron/context.go

图片

也就是 macaron[5] 框架中的Context结构体中的Req成员,这个Req就是我们要找的Source点。

修改go/ql/lib/semmle/go/frameworks/Macaron.qll文件,加入如下代码:

  private class UserControlledRequestField extends UntrustedFlowSource::Range, DataFlow::FieldReadNode {UserControlledRequestField() {exists(string fieldName | this.getField().hasQualifiedName("gopkg.in/macaron.v1", "Context", fieldName) | fieldName = "Req")}}

单独执行,可以找到污染点。

图片

直接将 sink、source 拼接跑,并没有出结果,因此需要一些处理来连接数据流。

isAdditionalTaintStep

这里 tyskill[6] 师傅说的很详细,引用一下:

  1. 限制函数为Params。

  2. 函数可被污染就说明参数可控,那么就让pred节点作为参数。

  3. SimpleAssignStmt结构表示一个赋值表达式,如a+=b,Rhs表示等号右边,通过查看源码可知Params函数调用几乎都是在等号右边,因此可以通过该结构减少误报。

  4. 最后将输出节点连接到赋值表达式。

    override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {exists(CallExpr call, SimpleAssignStmt sas |// call.getTarget().getName() = "Params" and// 限制为 Params 函数会产生局限性,去除call.getAnArgument() = pred.asExpr() andsas.getRhs().getAChild() = call.getParent*().getAChild() and// 使用getParent*()是因为等号右边不止有光秃秃的Params方法调用,如漏洞点就存在Jion函数拼接操作,需要通过传递闭包getParent*()来获取完整表达式// 使用getAChild()则是要获取Params的方法调用,不过测试发现用不用效果差不多,所以也不懂为什么还要加这个sas.getRhs() = succ.asExpr())
    }
    

    运行,成功发现该漏洞。

图片

加入工具监控、扫描

因为项目中调用 Codeql 将扫描结果保存为文件,这里需在文件头添加一些描述,完整代码如下:

/*** @name read file* @description read file* @kind path-problem* @problem.severity error* @security-severity 6.1* @sub-severity high* @id yhy0/read-file* @tags security* @precision high*/
import go
import DataFlow::PathGraphclass ReadFileSink extends DataFlow::Node {ReadFileSink() {exists(DataFlow::CallNode call |call.getTarget().hasQualifiedName("os", "Open") |call.getArgument(0) = this // 标记 sink 为 os.Open 第一个参数)}
}class ReadFileConfig extends TaintTracking::Configuration {ReadFileConfig() { this = "read file" }// 这里的 source 实现 UntrustedFlowSource ,方便其他框架通用, 对于Grafana ,我们已经修改了go/ql/lib/semmle/go/frameworks/Macaron.qll文件override predicate isSource(DataFlow::Node source) { source instanceof UntrustedFlowSource }override predicate isSink(DataFlow::Node sink) { sink instanceof ReadFileSink }override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {exists(CallExpr call, SimpleAssignStmt sas |// call.getTarget().getName() = "Params" and// 限制为 Params 函数会产生局限性,去除call.getAnArgument() = pred.asExpr() andsas.getRhs().getAChild() = call.getParent*().getAChild() and// 使用getParent*()是因为等号右边不止有光秃秃的Params方法调用,如漏洞点就存在Jion函数拼接操作,需要通过传递闭包getParent*()来获取完整表达式// 使用getAChild()则是要获取Params的方法调用,不过测试发现用不用效果差不多,所以也不懂为什么还要加这个sas.getRhs() = succ.asExpr())}
}from ReadFileConfig rfc, DataFlow::PathNode sink, DataFlow::PathNode source
where rfc.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "read file find on $@.", source.getNode(), "user-provided value"

将此 ql 文件路径加入配置文件config.yaml中, - go/ql/src/myRules/ReadFile.ql ,之后程序会自动对监控的项目运行此条规则,等待捡洞即可(笔者已经捡到了^_^)。

效果图

图片

 

图片

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/616160.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql主从复制教程

1、介绍 1.1 是什么 主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库 1.2 有什么用 数据备份:通过主从复制,可以将主数据库的数据复制到一个或多个从数据库中,以实现数据备份和灾难恢复。当主…

认识异常及异常处理机制之try-catch

异常类 什么是异常?就像人会犯错一样,程序在运行的过程中也会犯错。程序中的错误有两类,一类称为Error(错误),另一类称为Exception(异常)。Error类和Exception类都为Throwable的子类…

git: Updates were rejected because the tip of your current branch is behind

一、报错含义 由于本地分支的tip落后远程分支,push操作被拒绝。 二、产生原因 我再本地拉去了新的分支并未同步到远程仓库,在新分支进行开发,由于前几天同步也创建了该分支并同步到了远程仓库,导致我本次push失败 三、解决方…

解决uni-app小程序获取路由及路由参数

代码: this.id = this.$route.query.id;错误信息: 解决方案: // 获取query对象// #ifdef H5this.id = this.$route

部署ATS(Apache Traffic Server)和Nginx正向代理服务性能对比

部署ATS(Apache Traffic Server)和Nginx正向代理服务&性能对比 1. 正向代理的用途2. ATS(Apache Traffic Server)正向代理服务器部署3. Nginx正向代理服务器部署4. 性能对比 1. 正向代理的用途 正向代理一般是用于内部网络出去,反向代理一…

【LeetCode每日一题】2085. 统计出现过一次的公共字符串(哈希表)

2024-1-12 文章目录 [2085. 统计出现过一次的公共字符串](https://leetcode.cn/problems/count-common-words-with-one-occurrence/)思路:哈希表计算 2085. 统计出现过一次的公共字符串 思路:哈希表计算 1.用两个哈希表分别统计word1和word2中字符出现的…

大模型学习与实践笔记(五)

一、环境配置 1. huggingface 镜像下载 sentence-transformers 开源词向量模型 import os# 设置环境变量 os.environ[HF_ENDPOINT] https://hf-mirror.com# 下载模型 os.system(huggingface-cli download --resume-download sentence-transformers/paraphrase-multilingual-…

【算法】动态中位数(对顶堆)

题目 依次读入一个整数序列,每当已经读入的整数个数为奇数时,输出已读入的整数构成的序列的中位数。 输入格式 第一行输入一个整数 P,代表后面数据集的个数,接下来若干行输入各个数据集。 每个数据集的第一行首先输入一个代表…

使用CentOS搭建高性能静态HTTP服务器

在互联网应用中,静态内容是广泛存在的,例如HTML页面、图片、视频等。为了提供高效、稳定和安全的静态内容服务,我们可以使用CentOS来搭建高性能的静态HTTP服务器。 1. 选择合适的软件 Nginx和Apache是两个流行的HTTP服务器软件。Nginx以其高…

【深入挖掘Java技术】「源码原理体系」盲点问题解析之HashMap工作原理全揭秘(上)

HashMap工作原理全揭秘 — 核心源码解析 知识盲点概念介绍数据结构数组链表数组VS链表哈希表不同JVM版本HashMap的展现形式 HashMap VS HashTable特性区别对比 hashcodehashCode的作用equals方法和hashcode的关系key为null怎么办执行步骤 核心参数容量探讨负载因子探讨加载因子…

第21集《佛法修学概要》

乙三、修行篇第三分三:丙一、总标五乘要义;丙二、别明五乘解脱法门;丙三、结归一佛乘 请大家打开讲义第五十八页。我们讲到乙三,修行篇第三。 大乘佛法有八万四千个法门,但是我们可以把它归纳成两个重点:…

3-微信小程序组件基本用法

小程序组件是由宿主环境提供的,开发者可以基于组件快速搭建出页面结构。官方把小程序组件分为9类。 视图容器基础内容表单组件导航组件媒体组件map地图组件canvas画布组件开放能力无障碍访问 常用视图组件 view 官网传送门 普通视图区域 类似于HTML中div&#x…

Python基础语法(中)—— python列表、字符串、函数

文章目录 5. python中的列表5.1 列表的初始化5.1.1 直接初始化5.1.2 通过append函数初始化5.1.3 通过for语句初始化列表长度和每个位置的数值 5.2访问列表元素5.3使用循环语句遍历列表5.4列表的切片操作5.5列表的复制5.6列表的运算5.7列表的常用操作5.8嵌套列表5.9列表其他小知…

基于springboot+vue的网上花卉商城系统(Java毕业设计)

大家好,我是DeBug,很高兴你能来阅读!作为一名热爱编程的程序员,我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里,我将会结合实际项目经验,分享编程技巧、最佳实践以及解决问题的方法。无论你是…

「 网络安全术语解读 」点击劫持Clickjacking详解

引言:要想深入理解点击劫持攻击,我们需要先清楚iframe的用途及优缺点。 1. 关于iframe iframe是HTML语言中的一部分,通常用于在网页中嵌入其他网页的内容,如图像、视频、音频、链接等。它允许在一个网页中插入另一个网页&#xf…

高性能mysql 第三版 读书笔记

MySQL中的tmp_table_size和max_heap_table_size|极客笔记 mysql占用内存过高调优方法_tmp_table_size过大阻塞-CSDN博客 查看mysql分配的内存 mysql查看内存利用状态_mob6454cc6d81c9的技术博客_51CTO博客 https://www.cnblogs.com/stronger-xsw/p/13632505.html

国企石油化工单位任职资格体系搭建案例

传统的任职资格体系主要考虑年限、经验、资历等因素,部分企业在任职资格体系中也引入了能力指标,但是,实际管理过程中仍然存在很多问题:员工“熬年头”意识严重、工作积极性差、优秀人员因得不到晋升而流失、各方面能力都不错的人…

【一文详解】知识分享:(C#开发学习快速入门)

面向对象(OOP) c语言是面向过程。 c是面向过程面向对象。 c#是纯粹的面向对象: 核心思想是以人的思维习惯来分析和解决问题。万物皆对象。 面向对象开发步骤: 分析对象 特征行为关系(对象关系/类关系) 写代码: 特征–>成员变量 方法–>成员方法 实例化–具体对象 …

Python商业数据挖掘实战——爬取网页并将其转为Markdown

前言 「作者主页」:雪碧有白泡泡 「个人网站」:雪碧的个人网站 ChatGPT体验地址 文章目录 前言前言正则表达式进行转换送书活动 前言 在信息爆炸的时代,互联网上的海量文字信息如同无尽的沙滩。然而,其中真正有价值的信息往往埋…