审计GitLab:内部网络中的公开GitLab项目
在内部渗透测试中,一个容易被忽视的宝藏是那些隐藏在众目睽睽之下的秘密。也就是说,内部网络中许多情况下无需身份验证即可访问的地方。我指的是源代码管理平台,特别是GitLab。其他自托管平台可能也容易受到这种未认证技术的攻击,但本文将重点讨论GitLab。
我听过这样一句话: 高级开发人员先生——“如果攻击者已经访问了我们的内部网络,那我们就有更大的问题了。” 最大的问题正是这种思维!是的,黑客进入内部网络是一个需要立即关注的问题,但作为组织,在这种事件发生之前实施的防御措施才是真正重要的。一个常见的误解是,一旦对手获得了组织网络的初始访问权限,游戏就结束了。实际上,我告诉你,好邻居,情况并非如此!你可以做很多事情来防御内部网络中的攻击者。例如,通过canary令牌和其他很棒的东西在每个角落设置安全地雷。但在这篇博客文章中,我们将讨论攻击和防御(但主要是攻击)自托管的GitLab实例。
我在组织的内部网络中无数次遇到内部GitLab实例,其中许多有一个共同点:它们的许多项目都设置为“公开”。有人可能会想或脱口而出:“嗯,首先你需要一个有效的账户登录GitLab才能访问这些项目,”对此,我充满活力地说:“错误!”
在GitLab中,当项目范围设置为“公开”时,任何有网络访问权限的人仍然可以访问。更好的是,可以通过GitLab项目API在URL https://<gitlab.example.com>/api/v4/projects 发现它。
剧透警告:找到所有公开GitLab项目并下载所有内容的过程可以快速自动化,无需身份验证。在一个有趣的旁注轶事中,Nessus不会告诉你这一点,但你组织的皇冠上的宝石完全暴露了!因为这是一个功能,而不是一个错误。但这并不是说Nessus完全没有成果。Nessus仍然会为你识别所有GitLab实例,也就是说,如果你在使用Nessus的话。无论你是否使用Nessus,我们仍然可以轻松地使用Nuclei识别内部网络上的所有GitLab实例,更具体地说,是一个Nuclei GitLab工作流:
|
|
下面的截图显示了上述命令的部分输出。 Nuclei GitLab工作流部分输出(已编辑)
有许多代码秘密扫描工具,如Trufflehog、Gitleaks、NoseyParker等。在这篇博客文章中,我们将使用Gitleaks,但作为练习,我鼓励你使用所有三个工具并比较结果。在撰写本文时,许多这些工具的一个缺点是依赖于身份验证进行大规模自动化扫描,但这也可以从未认证的上下文中完成(当GitLab公共仓库API可访问时)。如果你在内部渗透测试中遇到过GitLab实例,但不确定如何自动化并实现那种甜蜜多汁的pwnage,那么这篇博客就是为你准备的。
正如Pastor Manul Laphroaig所说,PoC || GTFO!
掠夺GitLab
原谅我,邻居们,如果这个功能已经存在于任何开源工具中,但请允许我讨论从头开始自动化这个过程。我们将使用Python和Go的杂牌团队。
克隆所有东西
这理想情况下应该作为一些工具的功能包含——或者也许已经包含了——尽管如此,这里有一个Python脚本,用于将每个公共仓库下载到它们适当命名的目录层次结构中:
|
|
在get_repos()函数中,我们每次分页遍历所有可用的仓库数据,每页100个项目,直到没有剩余数据。这个脚本可以(而且可能应该)接受参数或配置文件以便移植,但让我们沉浸在硬编码事物的氛围中,即凭据。使用更新的projects_url和unauth_base_url值未认证运行上述代码看起来像这样: 搜索和克隆所有可用仓库(已编辑)
Gitleaks所有东西
接下来,我们将使用Gitleaks扫描所有内容。首先,让我们克隆项目,以便我们有gitleaks.toml文件,我们可以单独下载这个文件,但谁在乎呢。
|
|
首先,我们将为额外秘密添加一个额外规则。这个规则容易产生误报,但当它捕获否则会被遗漏的东西时,额外的噪音是值得的。将以下内容添加到你的/opt/gitleaks/config/gitleaks.toml文件中:
|
|
要对单个仓库运行Gitleaks,你可以使用如下语法:
|
|
但我们对大规模测试感兴趣,所以我们可以使用另一个一次性的Python脚本来做到这一点:
|
|
这个脚本将对每个仓库运行Gitleaks,并将生成的秘密写入JSON输出文件。这都很好,但我们可以做得更好一点(好得多的是将所有这些逻辑组合成一个单一的工具,或者分叉并将这个功能实现到一个现有的工具中)。在这里,我们可以看到Gitleaks正在做它的事情。 Gitleaks部分输出(已编辑)
合并所有东西
好吧,那么……现在,怎么办???我该怎么处理所有这些JSON文件?让我们写另一个程序,这次用Go编写,将所有JSON输出文件合并成一个CSV文件。
|
|
运行go程序:
|
|
再次,这些一次性脚本和程序中的每一个都可以(而且应该)集成到诸如Trufflehog、Gitleaks、Noseyparker之类的工具中,或者组合成一个独立的脚本或工具。我将把这留给你作为练习,像一个好邻居应该做的那样为开源做贡献。最初将每个步骤分解为单独的脚本是在没有凭据的情况下掠夺GitLab过程的最快原型方法。
分析所有东西
通过Excel或Libre Open Office将CSV文件导入为筛选表可以极大地帮助我们快速分析。 从CSV导入Excel数据 按描述或日期筛选的能力将对我们大有裨益。 Microsoft Excel导入的CSV文件带有列筛选器(已编辑)
如果你幸运地发现了一个启用的GitLab个人访问令牌,你可以用user_id和个人访问令牌更新第一个脚本,并再次运行脚本。
修复、缓解和预防
以下是你可以做的事情,以确保这种攻击不会发生在你的组织上:
修复
- 从源代码中删除所有敏感数据。
- 删除仓库历史中包含秘密的先前提交。
- 如果有太多违规提交,一旦敏感数据从源代码中删除,创建一个新的仓库并将新的清理后的代码提交到新仓库。
缓解
- 将所有GitLab项目设置为私有,并根据需要授予访问权限。
- 将GitLab项目设置中的“公开”视为开源。如果你不希望项目公开访问,请将项目设置为私有。
预防
- 使用诸如TruffleHog、GitGuardian等工具实施代码扫描CI/CD流水线。
- 使用诸如TruffleHog、GitGuardian等工具实施预提交钩子。
- 不要在公共或私有项目仓库中硬编码凭据或敏感信息。
- 教育开发人员和DevOps工程师有关软件开发相关的安全最佳实践。
结束语
在你的下一个内部网络渗透测试中,注意具有公开项目和API访问权限的GitLab实例!你可能会对你可能发现的东西感到惊讶😉我希望这篇博客文章激励你为开源做贡献并创建自己的工具。我没有为此编写开源GitHub项目的部分原因是为了引起对这个过程每个单独步骤逻辑的关注。分叉现有工具并发出拉取请求也是如此。我还发现了这个工具 https://github.com/punk-security/secret-magpie,旨在实现我们在本文中讨论的内容,但再次,据我快速查看源代码所知,在撰写本文时,它似乎不支持从未认证的上下文中执行此技术。
资源和参考
- https://github.com/gitleaks/gitleaks
- https://docs.gitlab.com/ee/user/public_access.html
- https://docs.gitlab.com/ee/api/projects.html
- https://github.com/projectdiscovery/nuclei
- https://github.com/projectdiscovery/nuclei-templates/blob/main/workflows/gitlab-workflow.yaml
- https://github.com/praetorian-inc/noseyparker
- https://github.com/punk-security/secret-magpie
- https://pre-commit.com/
- https://github.com/GitGuardian/ggshield-action
有关Trufflehog的更多信息,请参见: