GoKart Go语言源代码漏洞静态分析工具

GoKart Go语言源代码漏洞静态分析工具

在 Praetorian,我们致力于促进开源安全项目,并从根本上专注于开发技术以提高网络安全的整体状态。我们喜欢我们的激情和业务承诺,所以今天我们很高兴宣布GoKart的初始版本- 一种更智能的Go语言安全扫描仪

GoKart Go语言源代码漏洞静态分析工具

GoKart 是我们首次涉足我们新的开源安全策略,我们的目标是为社区提供包含一组基线功能的工具,希望它能促进安全行业的进一步的发展。
我们没有尝试针对特定的安全问题制定规则,而是专注于使用Go 分析包发布几个高级分析器,这些分析器提供了我们发现现有开源项目中缺少的功能。
我们的目标是通过基于用户直接反馈的附加功能的第一个版本来吸引和激发社区。
我们的愿景是成为 GoKart 引擎的制造和维护组织——允许其他人在驾驶更高性能的机器的同时专注于微调和构建手推车。

静态分析工具是现代开发管道的关键部分,并在整个开发生命周期中以各种形式使用。在 IDE 中,语法检查器甚至会在您单击“编译”按钮之前捕获错误。在幕后,他们确定源代码是否具有有效的形式和结构,解析类型信息,并在编译期间进行优化。甚至代码自动完成方法也基于简单的静态分析,有助于提示程序员下一步做什么。所有这些 itools 都很棒……但是,至少对我们而言,当我们将这些方法应用于源代码以识别安全漏洞时,事情变得令人兴奋。如果做得好,静态应用程序安全测试 (SAST) 有可能在降低成本的同时提高安全性和生产力。这是一个相当不错的结果。

与实际运行程序的动态分析相比,动态分析要求代码完整且处于完全可构建的状态,静态测试更适合在开发过程的早期执行,并且经常在开发过程中执行。由于静态分析仅考虑源代码,因此无需设置自定义测试环境,从而减少了对生产 Web 服务器、防火墙、微服务等进行昂贵且复杂的复制和沙箱化的需要。就其本质而言,静态分析提供本地开发构建中包含的任何源文件的可见性和分析覆盖范围。尽管更高级的静态分析技术需要创建自定义规则和配置,这些规则和配置的设置和有效使用都很复杂,

在安全环境中,SAST 有助于尽早检测常见的不安全编程模式,并在整个开发生命周期中实施安全编码标准。SAST 具有可扩展和快速的优点,允许将其集成到 CI/CD 管道中。Praetorian 提供了自己的 CI/CD 安全平台Chariot,它可以将 SAST 应用于每次提交。随着 GoKart 的发展,它将作为 Chariot 的可用扫描器之一被包括在内,为开发人员添加额外的上下文,使他们不仅可以快速找到问题,而且还为他们提供有用的信息以帮助他们解决问题。更好的是,这项服务是免费提供的,是我们全面了解整个企业的基础设施和代码安全状况的基础。

在过去的十年中,静态分析技术已经从它们不起眼的起源演变而来。早期的 linting 服务可能只是将简单的 RegEx 规则应用于代码,而更现代的方法利用数据流分析,通过应用程序的调用图表示从用户输入跟踪用户可控数据,并传播到所有已知易受攻击的函数。特定类型的漏洞利用。在研究的最前沿,学术领域开发的静态分析技术已转向使用符号执行、模型检查、约束分析和形式化方法,以创建更强大的源代码建模和评估功能。与此同时,回到真实的安全世界,商业工具一直在努力真正利用这些更复杂和计算密集型的技术,通常选择增加语言广度而不是分析深度。更糟糕的是,对于依赖于在 Github 上搜索和定制我们的安全工具的其他开发世界,我们发现即使是 20 年前开创的数据流技术也尚未摆脱他们的企业牢笼。相反,大多数开源 SAST 工具已经恢复到类似 grep 的模式匹配策略,无论是直接在源代码上还是在程序的抽象语法树 (AST) 表示上。

我们为什么要制作GoKart?

在 Praetorian,我们吃自己的狗粮。鉴于我们使用 Go 进行攻击性工具开发的历史以及我们最近从基于 Java Spring 的微服务转向使用 Go 简化 Chariot 平台的更高效、灵活和安全、完全容器化、基于 Kubernetes 的架构,我们强烈希望改进自动化 Go 安全分析的当前状态。

在过去十年中,商业 SAST 工具因使用过于复杂、嘈杂和不准确以及获取和维护成本高而闻名。他们基于编译器的分析引擎对 C++、Java 和 C# 等静态类型语言运行良好,但一直在努力将他们的技术应用于 JavaScript 或 Python 等动态类型语言,并且在接受 Docker、Kubernetes 和 Go 等云原生范例方面进展缓慢. 另一方面,开源安全扫描器是成群创建的,但通常不够复杂,无法证明给定的发现确实是安全威胁,或者工作可靠和准确,足以信任以自动、无人协助的方式运行.

所有采用工具的最显着挑战是高误报率和缺乏确切原因的证据标记的项目易受攻击例如,许多安全扫描器只会报告特定代码行存在安全问题,而不会显示攻击者将采取的漏洞利用路径其他工具具有更复杂的功能,但需要安全敏锐度和查询语言编程专业知识。在实践中,这些缺点导致了误报疲劳和需要与扫描仪搏斗直到警告消失的心态。GoKart 旨在通过提供用户友好、更准确和噪音更少的体验来解决这些问题,并帮助开发人员快速、自信地发现和理解高影响问题的完整攻击路径。

在创建GoKart 时,我们受到了gosec 的启发,目前使用最广泛的 Go 安全扫描器,对其易用性印象深刻,但想看看我们是否可以改进其当前的结果。

Gosec 包含 30 条规则,这些规则将模式匹配应用于 Go 代码的抽象语法树 (AST) 表示。使用该语言的 AST 有助于 gosec 准确了解每个表达式、常量和函数与其他语言结构的关系,并防止对代码结构的任何“误读”。在安全方面,gosec 处理各种问题,从 SQL 注入和解压炸弹到较短的加密密钥长度和过时的 TLS 设置。

gosec 目前缺乏的主要分析能力是执行“污点跟踪”或确定用户可控数据可能到达易受攻击功能的代码路径的能力。添加污点跟踪将允许以一种方式编写规则,以大大减少与更简单的签名、文本或 AST 模式匹配相关的误报结果。此外,如果问题没有准确地包含在预期的位置,gosec 可能不会揭示潜在的攻击路径,从而为用户产生错误的安全感,并在安全专业人员之间引发进一步的不信任。

例如,攻击者可能会控制一个字符串,该字符串稍后用于构造导致 SQL 注入的查询,该查询在程序执行的时间比执行 SQL 查询时要早得多;类似地,用作创建 RSA 密钥的大小参数的常量值可以由一个函数初始化,由第二个函数修改,然后由第三个函数使用。在每种情况下,攻击路径或安全漏洞可能源自不同的功能甚至不同的文件,如果没有污点跟踪或数据流分析,这些情况可能不会被发现。

从 gosec 停止的地方开始,GoKart 首先识别源代码中潜在的易受攻击的函数,然后将这些函数的输入追溯到它们的源头。如果输入源可能由用户控制(例如在 SQL 注入中),或者如果输入源以其他方式定义为“易受攻击”(例如 RSA 密钥生成器中的短密钥长度),GoKart 将输出该漏洞。然后将这些函数的输入追溯到它们的源头。如果输入源可能由用户控制(例如在 SQL 注入中),或者如果输入源以其他方式定义为“易受攻击”(例如 RSA 密钥生成器中的短密钥长度),GoKart 将输出该漏洞。然后将这些函数的输入追溯到它们的源头。如果输入源可能由用户控制(例如在 SQL 注入中),或者如果输入源以其他方式定义为“易受攻击”(例如 RSA 密钥生成器中的短密钥长度),GoKart 将输出该漏洞。

GoKart工作原理

在设计 GoKart 时,我们的重点是提供对 Go 中高影响结果的可见性,这为我们在现场执行代码审查的安全工程师以及我们自己的开发人员构建新工具提供了重要价值。我们添加了执行轻量级污点传播和分析器的功能,利用这些功能解决我们在对 Go 中开发的应用程序执行手动代码审查时发现的几个最有趣和最普遍的漏洞:命令注入、路径遍历和服务器端请求伪造。通过添加使用新接收器自定义 GoKart 的功能,以创建其他漏洞类型以及针对特定企业威胁模型定制的用户输入源。根据我们有限的测试,我们相信我们已经在工具灵活性和可用性之间取得了正确的平衡,

GoKart 使用 Go 分析包构建调用图,并将 Go 代码放入单一静态赋值 (SSA) 形式,将程序计算的每个值构造为对唯一变量的赋值。SSA 在编译器中用于优化,在安全上下文中它可以帮助我们追溯用作输入的数据源。与简单地使用 AST 相比,以 SSA 形式进行分析有一些好处。GoKart 的 SSA 表单更适合查看数据流,因为所有值分配都只完成一次。能够在数据流经程序时跟踪数据,在对象和模块中进出,是 GoKart 的主要功能之一,也是 GoKart 如此强大的原因。它可以追踪到所有包含的包和模块。

GoKart Go语言源代码漏洞静态分析工具

SSA 还具有在分析期间使恒定传播成为可能的优势。一些错误配置和设计漏洞仅在使用特定参数时才适用,例如创建长度太短的 RSA 密钥,使密钥可破解。静态分析传统上无法评估不是文字的表达式,但通过常量传播,可以在不运行代码的情况下评估常量属性和参数。因此,如果您将变量而不是文字传递给 `rsa.GenerateKey`,那么安全扫描器就无法确定是否真的存在问题。现在,假设变量是一个常量或一个在编译时可以计算其操作的常量,GoKart 可以确定 RSA 密钥长度是多少

GoKart 包含一个可定制的输入源和易受攻击的接收器列表,并且由于它进行污点跟踪,它可以准确显示易受攻击的输入源在代码中的哪个位置被馈送到应用程序中。污点跟踪不仅大大降低了静态分析的误报率,而且使用 GoKart 生成的数据路径使修复变得更加容易。

尽管在使用 SSA 进行常量和污点传播方面取得了一些进步,但我们基于 AST 的调用图实现有许多自身的局限性。如果没有正确的调用流图 (CFG) 构造,我们的污点分析将无法正确考虑计算机程序将进入的所有路径;例如,导致方法内的流量不敏感以及在单个调用路径中错误地找到来自两个分支的节点的情况。还需要执行一定级别的指针分析以更准确地模拟 Go 通道的并发性——我们目前通过假设从通道返回的数据被污染而过度近似,从而导致潜在的误报。全局变量也带来了巨大的挑战,因为它们打破了 SSA 对潜在状态变化的假设。

结果

对于四种实验性漏洞类型,与其他 Go 扫描仪相比,GoKart 能够降低误报率和误报率。特别是,GoKart 比 gosec 更准确,因为它使用污点跟踪进行操作,对编程风格的假设较少,并且仅在潜在漏洞实际上来自被认为是用户可控或有可能是恶意的输入源时才发出警报。

从我们的实验测试台转移到一个样本易受攻击的应用程序表明我们对降噪和信号放大的直觉是正确的。扫描 Contrast Security 开发的 go-test-bench 应用程序表明信噪比有了显着改善https://github.com/Contrast-Security-OSS/go-test-bench,GoKart 从我们的三个中发现了 8 个真阳性最常见的漏洞类型:路径遍历、命令注入和服务器端请求伪造 (SSRF),每种类型都有支持证据,形式为从用户可控输入到易受攻击函数的痕迹。

GoKart Go语言源代码漏洞静态分析工具
跟踪显示 Handler 方法接收类型为 httpRequest 的指针并将其分配给 userInput 并最终用于调用易受攻击的函数 ioutil.WriteFile()
GoKart Go语言源代码漏洞静态分析工具
跟踪显示函数 osExecHandler 接收类型为 http.Request 的指针,将其分配给 userInput,然后直接用于调用易受攻击的方法 exec.Command()
GoKart Go语言源代码漏洞静态分析工具
跟踪显示函数 httpHandler 接收类型为 http.Request 的画家,将其分配给 userInput,然后用于创建用于调用易受攻击的方法 http.Get() 的 URL

乍一看,仅运行等效检查的 gosec 的总体结果非常相似(总共 7 个结果;不存在针对 SSRF 的检查),但进一步深入研究了由 gosec 识别但在 GoKart 中缺失的特定命令注入漏洞证明了其价值正确跟踪用户对易受攻击功能的输入:

GoKart Go语言源代码漏洞静态分析工具

虽然将其标记为仅基于调用站点的漏洞似乎是合理的,因为如果userInput变量来自外部可控源(例如 http.Request),这将是一个漏洞。

然而,通过代码跟踪清楚地表明,这userInput显然是在使用之前直接从函数内部创建的局部变量,恶意输入没有可能到达易受攻击的函数,因此这种分类是一个误报结果,需要一定程度的安全专业知识来识别,即使在如此小的和故意易受攻击的应用程序中也存在。

GoKart Go语言源代码漏洞静态分析工具

离开测试赛道并在现实世界中驾驶 GoKart 让我们了解它在大型企业代码库上的表现。我们已经开始扫描一些我们最喜欢的 Go 应用程序,并发现从可用性的角度来看,结果非常鼓舞人心。

在 grpc-go ( https://github.com/grpc/grpc-go )上运行表明 GoKart只显示了 2 个路径遍历结果,这两个结果似乎都是合理的,只是它们是在基准测试中发现的,因此我们不会向客户报告。整个扫描和结果可以显示在单页屏幕截图中,这一事实让我们有一种温暖的模糊感觉,我们在这里走的是正确的道路:

GoKart Go语言源代码漏洞静态分析工具

我们刚刚在 GitHub 上来回与 GoKart 比赛,并发现结果以及整体驾驶体验值得与世界分享。我们计划更深入地研究一些现实世界的发现并在不久的将来分享这些发现,但对于那些对预览感兴趣的人,这里有一些比赛结果(项目细节已被编辑以实践我们负责任的披露政策) :

GoKart Go语言源代码漏洞静态分析工具
跟踪真实世界项目 1 运行了 8 秒,扫描了 3,830 个文件,并确定了 16 个潜在漏洞
GoKart Go语言源代码漏洞静态分析工具
跟踪真实世界项目 2 运行了 1 分 5 秒,扫描了 7,307 个文件,并确定了 21 个潜在漏洞
GoKart Go语言源代码漏洞静态分析工具
跟踪真实世界项目 3 运行了 4 秒,扫描了 1,570 个文件,并确定了 13 个潜在漏洞

在我们的每次测试中,GoKart 运行速度都非常快,完成度很高,使用开箱即用的配置[默认配置],它能够正确扫描所有可构建的模块而不会出错,并产生了一些合理的结果。

未来的工作

今天的发布是在知道该工具还处于起步阶段的情况下完成的。我们计划在不久的将来对整体可用性和可扩展性进行多项改进(在公共回购中可见为问题)),以及我们刚刚定义的许多分析功能和更强大的规则创建功能。我们之前在静态分析方面的经验告诉我们,根据 URL 路由发现和建模应用程序的过程,然后使用符号分析和模型检查来模拟沿这些路由的程序执行是实现“面向目标”分析策略的非常强大的方法. 展望未来,将通过一种技术(例如动态或网络分析)获得的分析知识整合到后续分析阶段使用的附加上下文中的能力将成为实现我们将单一窗格视图创建到应用程序的完整安全配置文件。实现全球 IBM 和 HP 十年前承诺的静态和动态分析之间的结果相关性水平是我们分析道路上的一个直接里程碑。但是,我们还通过研究如何将机器学习技术的使用与一些新颖的静态和动态分析技术结合到人工智能增强型应用程序和基础设施分析的新范式中来推动登月计划。从更具体的角度来看,GoKart 将配备用于在 SARIF 中生成完整跟踪结果的新轮胎,在不需要完全可构建的模块的情况下处理扫描单个 Go 文件的一些冲击,以及用于正确处理 Go 通道的程序并发的分析增压器.

Praetorian 对 GoKart 的持续所有权和开发旨在表达我们对开源安全社区的热爱和尊重,因此请提供您的反馈,以帮助我们确保 GoKart 与我们的使命保持一致:寻找、修复和帮助最终解决网络安全问题。

如果您想参与其中——我们希望您能参与其中!— GoKart 已向 GitHub 开源,任何人都可以在其中做出贡献。拉取请求和新想法总是受欢迎的。如果您发现错误,请随时创建问题。此外,Praetorian 正在招聘新的“开源开发人员职位”——如果您想全职为 GoKart 和其他开源安全应用程序做出贡献,请联系我们。

GoKart下载地址

①GitHub:

gokart_0.2.0_darwin_macOS_x86_64.tar.gz 4.9 MB
gokart_0.2.0_linux_x86_64.tar.gz 4.72 MB

②云中转:

yunzhongzhuan.com/#sharefile=dQg9j7Yg_…
解压密码 www.ddosi.org

GoKart安装方法

您可以使用下列任一选项在本地安装 GoKart。

使用go install安装

go install github.com/praetorian-inc/gokart@latest

使用发布的二进制文件安装

  1. 发布页面下载适用于您的操作系统的二进制文件。
  2. (可选)下载checksums.txt文件以验证存档的完整性
#检查下载档案的校验值
shasum -a 256 gokart_${VERSION}_${ARCH}.tar.gz
b05c4d7895be260aa16336f29249c50b84897dab90e1221c9e96af9233751f22  gokart_${VERSION}_${ARCH}.tar.gz

cat gokart_${VERSION}_${ARCH}_checksums.txt | grep gokart_${VERSION}_${ARCH}.tar.gz
b05c4d7895be260aa16336f29249c50b84897dab90e1221c9e96af9233751f22  gokart_${VERSION}_${ARCH}.tar.gz
  1. 解压
tar -xvf gokart_ ${VERSION} _ ${ARCH} .tar.gz
  1. gokart二进制文件移动到您的路径中:
mv ./gokart /usr/local/bin/

克隆并构建

#克隆 GoKart 存储库
git clone https://github.com/praetorian-inc/gokart.git

#导航到 repo 目录并构建
cd gokart
go build

#将 gokart 二进制文件移动到您的路径中
mv ./gokart /usr/local/bin

GoKart用法

在当前目录中的 Go 模块上运行 GoKart

#在没有指定目录的情况下运行默认为 '.' 
gokart scan <flags>

扫描不同目录中的 Go 模块

gokart scan <directory> <flags> 

显示帮助信息

gokart help

入门 – 扫描示例应用程序

您可以按照以下步骤在Go Test Bench上运行 GoKart ,这是 Contrast Security 团队有意设计的易受攻击的 Go 应用程序。

#克隆易受攻击的示例应用程序
git clone https://github.com/Contrast-Security-OSS/go-test-bench.git
gokart scan go-test-bench/

输出会显示一些已识别的漏洞,每个漏洞都有一个易受攻击的功能和已识别的用户输入来源。

要测试一些额外的 GoKart 功能,您可以使用下面建议的 CLI 标志进行扫描。

#使用详细标志显示这些漏洞的完整痕迹
gokart scan go-test-bench/ -v

#使用 globalsTainted 标志忽略列入白名单的来源
#可能会增加误报结果
gokart scan go-test-bench/ -v -g

#使用 debug 标志显示内部分析信息
#这对开发和调试很有用
gokart scan go-test-bench/ -d

#以sarif格式输出结果
gokart scan go-test-bench/ -s

#输出结果到文件
gokart scan go-test-bench/ -o gokart-go-test-bench.txt

#输出scarif结果到文件
gokart scan go-test-bench/ -o gokart-go-test-bench.txt -s

#扫描远程仓库(私有仓库需要适当的身份验证)
#仓库将被克隆到本地,之后扫描并删除
gokart scan -r github.com/ShiftLeftSecurity/shiftleft-go-demo -v

# 一起使用远程扫描和输出标志进行无缝安全审查
gokart scan -r github.com/ShiftLeftSecurity/shiftleft-go-demo -o gokart-shiftleft-go-demo.txt -v 

#使用远程扫描、输出和 sarif 标志无缝集成到 CI/CD 
gokart scan -r github.com/ShiftLeftSecurity/shiftleft-go-demo -o gokart-shiftleft-go-demo.txt -s

要测试 GoKart 的可扩展性,您可以修改 GoKart 用于将新的易受攻击的接收器引入分析的配置文件。在包含的默认配置文件中定义了一个测试接收器分析器util/analyzers.yml。修改util/analyzers.yml以删除测试接收器分析器上的注释,然后指示 GoKart 使用带有-i标志的修改后的配置文件。

#使用修改后的analyzers.yml 文件进行扫描并输出完整的跟踪
gokart scan go-test-bench/ -v -i <path-to-gokart>/util/analyzers.yml

输出现在应该包含其他漏洞,包括新的“用户输入可访问的测试接收器”漏洞。

运行 GoKart 测试

您可以使用以下命令运行包含的测试,从 GoKart 根目录调用。

go test -v ./...

项目地址:

GitHub: github.com/praetorian-inc/gokart

Leave a Reply

您的电子邮箱地址不会被公开。 必填项已用 * 标注