简单地聊聊 GitHub 信息泄露监控

简单地聊聊 GitHub 信息泄露监控

编程那点事 随便写写 3974 字 / 8 分钟

去年 5 月份的时候,bilibili 源码泄露,B 站虽然一波 DMCA 下架了一堆仓库,但那也是无济于事。直到现在,在 GitHub 上搜索"bilibili.com",还是能搜出一大片当时泄露的源码。这反倒是给寻找新的泄露情报带来了干扰,B 站这可能也是因祸得福吧。 我在去年 12 月份的时候,在 bilibili 泄露的那份源码里,找到了两处还未被修复的敏感信息泄露,提交给了 BiliSRC,均评级为高危。其实但从这个漏洞来看,我只是在茫茫代码中找到了两串字符,这种简单的“搜索”操作完全称不上有啥技术含量,但是它带来的危害,往往都是致命的。

对于我来说,这种“搜索”,虽简单,但是却十分有成效。截止到目前,仅凭借着 GitHub 上的信息泄露,就已经找到了两家教育类企业的数据库泄露、GitLab 账号泄露,甚至还有国内某云计算厂商的某账号…… 随便一个就是高危。

是哪些人泄露了敏感信息?

由个人经验来看,很多的 GitHub 信息泄露都是企业的实习生或新入职的员工。他们往往会把自己里在公司负责的一个小项目给 push 到 GitHub 上,或者是将长久以来的技术总结文章发到 GitHub 上进行汇总管理,这些文章中难免包含很多公司的数据库配置,网络拓扑,服务器信息等——这种信息泄露在小公司尤为常见。 GitHub 于 2019 年 1 月开始允许个人账号免费创建私有仓库,在那之前,普通个人用户清一色的都是公开仓库,泄露的敏感信息量可想而知。

虽然有部分公司选择使用 GitLab 等来自建 Git 远程仓库,但是同样未正确设置仓库权限为私有,导致在/explorer中可以看到所有的公开仓库,同时可以通过查看公开的 Groups 来得知有哪些用户,之后可以尝试爆破猜测它们的密码…… 攻击面很广,这里不再赘述。可见自建 Git 仓库也并不是万全之计。

除了企业员工外,还有一群就是个人开发者,特别是——高校学生。很多计算机相关专业的学生,又或是几个学生组成的一个课程小组,平时喜欢“整活”自己写些小玩意儿,比如选课脚本,图书馆通知,课堂大作业项目等,他们往往未对代码进行脱敏就把源码 push 到 GitHub 上。写 Web 应用需要对接数据库,代码里会有 MySQL 的数据库账号配置;要发邮件通知,代码里就有个人学生邮箱账号密码;测试数据里可能还带有个人的常用密码等。 有的做得比较大的项目,可能会对接微信小程序、公众号,某教育 App 的第三方应用,甚至一些云厂商的服务,因此还会泄露这些服务的 AK 和 SK。

我曾在 GitHub 找到过某高校的一个学生账号,登录后可连接校园 VPN 并可白嫖全套该校学生优惠。

如何弥补?

GitHub 信息泄露,其实完全就是“人”的问题。就企业而言,员工没有良好的安全意识,对于 Git / GitHub 的了解不够,导致误 push 代码。因此还是那些老话,未雨绸缪加强对员工的安全培训但估计用处不大;亡羊补牢联系 GitHub 走 DMCA 撤下仓库。重点其实还是企业自己主动去监测自己的信息泄露情况,把希望和努力都放在员工自身上是不现实的。

对于我们高校学生而言也是一样,从自身做起,push 之前多检查下,配置该 ignore 的是否 ignore 了,代码里是否有测试时留下的敏感信息注释,这份代码是能给所有人看的吗?多问自己几个问题总是好的。 实在一不小心犯了错,也请一定一定学会怎样正确撤回之前自己错误的提交。在网上和现实中,已经看到过太多太多的删掉再 commit 一遍的案例了。最简单的办法不如直接删除整个 Repo 即使止损。

以上两点都是对“人”进行要求。但我认为在 GitHub 信息泄露如此严峻的形势下,我们应该主动点,主动去监控 GitHub 上是否有我们的信息被泄露。因此,一个自动化的扫描监控程序就很有必要了。

自动化扫描的思路

检测是否有信息泄露的过程其实很简单,无非是两步:

  1. 搜索代码
  2. 检查代码中是否有敏感信息 我就这两步展开来讲。

搜索代码

目前从 GitHub 上搜索代码主要有两种办法:

  • 使用 GitHub API 搜索
  • 模拟正常搜索请求爬取

使用 GitHub API 搜索

我们几乎不会通过第三方搜索引擎来进行搜索。所有的结果都来自于 GitHub,GitHub 的代码搜索对于我们来说就是个黑盒。它可能会对我们的搜索频率进行限制,可能对搜索结果进行过滤,这些我们都是不知道的。 比如你可以尝试搜索"alibaba-inc.com",返回的 Code 结果数竟然为零!但是去除两边的双引号,搜索alibaba-inc.com可以搜到 133K+ 条结果。目前不清楚阿里巴巴是否和 GitHub 有什么交易。

使用 GitHub API 进行搜索算是一种正经合法的路子。这里只讨论 GitHub v3 RESTful API,v4 GraphQL API 不在本文讨论范畴内。 目前开源的 GitHub 扫描器,如:GSIL,Hawkeye 都是使用 API 进行搜索。因为各大编程语言对于 GitHub 官方 API 有现成的 SDK 可以拿来用,因此调用 API 十分容易。并且返回的数据也十分详细,可以直接得到具体的 Repository 信息,源文件内容等。

但 GitHub 对 RESTful 搜索 API 的请求频率存在限制,即登录用户每分钟 30 次请求。解决方法一般是多开几个账号生成多个 Access Token 即可实现更多的请求。 同时在今年五月份举行的 GitHub Satellite 中,可以看出 GitHub 接下来准备在安全方向发力。目前 GitHub 已经推出了Dependabot alerts来监测前端项目的依赖组件安全,同时对项目的安全报警发布,甚至是 CVE 申请都给予了支持。下一步是将代码分析引擎 CodeQL 整合进 GitHub 生态中,可以检测项目的代码是否存在威胁以及是否泄露敏感信息。 综上所述,目前能感觉到 GitHub 为了推自家的 CodeQL,开始对 GitHub API,特别是搜索 API 进行了一些限制。可能日后搜索 API 会有更多的限制。

模拟正常搜索请求爬取

另一种方法就比较简单粗暴,直接模拟正常用户操作,爬取搜索代码的结果页后解析 DOM。 git-hound 使用的就是这种模拟登录 + 搜索的方法。因为这毕竟这不是正道,所以建议使用小号进行操作,防止被 GitHub 风控甚至封号。 模拟登录 GitHub 的操作不难,拿到页面的 CSRF Token 后正常发请求即可。需要注意的是,成功登录前可能会有一步向邮箱发送验证码或是因为账号开启了 2FA 二次验证要输入验证码,因此发送登录请求后还要根据响应来判断是否需要二次验证。 具体的代码可以参考 git-hound 的实现,我个人认为是十分完备的了。

搜索的关键词

我们可以活用 GitHub 的高级搜索条件,比如使用pushed:>2019-01-01 created:>2019-01-01 等过滤器过滤掉一些很老的代码。language:java 来筛选特定语言的代码,排除搜索结果中静态文件的干扰。 还可以搜索很多常与敏感信息出现的关键词,比如:"jdbc:mysql://" "mysqli_connect("等数据库连接语句,往往就能有很多公网数据库的账号密码。还有敏感的文件名:filename:.env filename:bash_history filename:_rsa filename:jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml 等。

对于企业而言,可以搜索企业的内网、外网域名,企业邮箱,版权声明(一般会写在代码首部注释),常用包名等。思路其实可以放的很广。

检查代码中是否有敏感信息

**何为敏感信息?我们所希望看到的“敏感信息”又是什么?**首先要弄清楚这个问题。

对于企业而言,任何关于自己公司的代码,哪怕是一个前端的项目代码,一小段服务器的请求日志等危害不大的信息,也是他们想要找到的。因为这关系到企业的名誉,虽然这些东西造成不了实际的安全威胁,但是可能暴露企业在某些方面的短板,那必然是要一网打尽统统处理掉的。因此在搜索上是广撒网,直接搜企业相关特征,在代码匹配上可以选择错杀一千不放过一个。这种场景下对准确度没有那么高的要求,更多的是广度。

对于那些想搞些免费 OSS,或者肉鸡之类的人,就不需要再关心数据的来源了,直接搜索敏感代码片段即可。比如"aliyun.com" "AccessKey"等。效果显著,但因为众所周知地原因不深入讨论。

而对于挖 SRC 的白帽子而言,肯定是要针对大厂的信息泄露,比如服务器、数据库、内网 VPN、员工邮箱的登录口令信息。因此在搜索时,要注意关键词的选择,比如你只搜索alibaba-inc.com这个域名,可能会搜到一堆带 alibaba-inc.com 的 NPM 镜像站链接的package.json。可以选择加上"secret" "password" 等词,同时筛选文件类型为Java。 搜索返回的结果,主要是用正则匹配指定格式和长度的 Key,匹配上文提到的敏感代码片段等。因此对于一个自动化扫描器,需要能够不断接受添加新的正则匹配规则,并对之前的扫描任务进行记录并重新扫描。更进一步,对常见的代码文件,需要能够简单地用正则做下分词(是真的简单的),提取出其中的注释,字符串等内容,反馈给人工快速查阅审计。

进一步呢?

有时候,人们也会将一些包含敏感信息的 PDF、Word、Excel 文件传到 GitHub 上,很常见的就是企业内部文档。而这些文件是无法直接通过 API 预览分析其内容的, 这部分可以选择将文件下载到本地,借助第三方库读取其内容。甚至在当今 Serverless 成为主流的时代,随手写个处理 PDF 的云函数扔阿里云上也不失为一种好的选择。

而对于泄露的密码,很有可能是个人的常用密码或企业内部的通用密码。可以使用这些密码在同一单位的其他服务的口令鉴权上进行“撞库”。一个真实的例子:个人项目的代码里泄露了开发者本地 MySQL 数据库的密码,经尝试为该开发者 GitHub 密码 + 常用邮箱密码。

最后聊一下展望

在 GSIL 的作者这篇文章中,他提到单靠提交 GitHub 信息泄露,每月单漏洞收入超过¥10k+。这是三年前的数据,现在状况应该已经有所改观。但去年年底发布的介绍 git-hound 的文章,又提出了 GitHub CI 日志中的敏感信息泄露这一新的思路。随着 GitHub Actions 大规模被各大开源项目使用,由此导致的安全威胁肯定也会有很多。

自己也曾开坑写过好几次 GitHub 信息泄露监控,但最后都是因为一些事情而不了了之。最近的一次是因为太急于求成,一上来后端还没写完就开始写前端,搞得两边忙来忙去进展很慢,动力也慢慢被消磨殆尽。 因此也希望用本文总结一下 GitHub 信息泄露的几个点,为自己接下来在暑假又双叒叕再次写 GitHub 信息泄露理清思路。今年暑假已经计划好了写两个真正有用,今后自己也会使用的安全相关的项目,希望自己能坚持下去,最终让项目形成一个像 Cardinal 一样的“编写->收到反馈->升级”的良性循环。