在中国的 Gitee 扫描 725 万个仓库发现 26400 条活跃凭证
这篇客座文章由独立安全研究员本·齐默尔曼撰写,并与 MongoDB 的 Kingfisher 团队合作开发。本专注于公共源托管平台的大规模凭证曝光研究。简而言之:我扫描了 Gitee(中国最大的本土 Git 托管平台)上的 7,256,531 个公共仓库,使用了 TruffleHog 和 Kingfisher,发现了 26,400 条独特的经过验证的活跃凭证。发现包括一个主要企业 AI 平台的活跃组织管理员凭证和数千个活跃的云服务提供商访问密钥。什么是 Gitee?Gitee 于 2013 年由 OSChina 启动,被中国工业和信息化部选为国家开放源代码托管平台。相较于 GitHub 和 GitLab,其公共 API 的功能受到严重限制:没有分页项目端点,网站上的代码搜索功能似乎多年前已经退役。2021 年对 Gitee 上凭证曝光进行研究的尝试得出结论,其 API 限制太大,无法扩展研究。与任何大型 Git 平台一样,它是凭证曝光的一个吸引目标:它是基于 Git 的,因此深埋在提交历史中的秘密将持续存在。它托管数百万个公共仓库,具有活跃的提交量。它没有公共等同于平台供应商的秘密扫描合作伙伴关系,这在 GitHub 上已经成为标准。枚举数百万个 Gitee 仓库 Gitee 的公共 API 功能有限,因此枚举数百万个仓库需要结合多个来源:唯一一个以规模返回有用数据的官方 REST 端点,平台的探索信息流,网站本身的每个用户的仓库和星标者页面,以及支持网站搜索 UI 的 Gitee 内部 Elasticsearch 小部件。引导用户名语料库 返回有用数据的唯一官方 REST 端点是 GET /api/v5/search/users?q= 。我用三个字符前缀查询( aaa , aab , ..., zzz )进行请求,并将结果与从公共探索信息流中提取的用户名结合( /explore/all?order=starred|popular|updated )。然后,我通过每个用户的关注列表和热门仓库的星标者扩展该集合。这生成了一个包含 1,704,759 个用户名的种子语料库。抓取前端每个用户页面 拥有用户名语料库后,两个每个用户页面生成了仓库:gitee.com/{user}/projects(用户自己的仓库)和 gitee.com/{user}/stared_projects(用户已星标的仓库)。/projects 的第一页返回完整的 HTML;后续页面是 AJAX 分页的( X-Requested-With: XMLHttpRequest )。在用户名引导期间使用的星标者列表页面以相同方式分页,此外还需要从第 1 页 HTML 中提取 CSRF 令牌。查询现场搜索小部件 平台的很大一部分位于社交图之外。为了访问它,我使用了同一内部 Elasticsearch 端点,支持 Gitee 的现场搜索 UI:so.gitee.com/v1/search/widget/wong1slagnlmzwvsu5ya 。它接受查询 ID,一个 q 参数,以及通过 from + size 进行分页:无格式代码片段。每个查询每页最多返回 20 个结果,总共硬性限制为 200 个结果( from + size <= MAX_RESULTS ),无论实际存在多少匹配项。对于特定用户名,这通常是可以接受的;对于常见用户名和针对小部件的三元前缀查询,上限会悄然截断结果。用桶拆分逃避 200 结果上限 小部件的响应包括按语言( 编程语言 )和许可证( 许可证 )进行分组的 Elasticsearch 聚合。对于每个用户名抓取,当查询被限制时,我按响应已经返回的语言桶将其拆分:无格式代码片段。对于针对小部件的三元前缀查询(用于显示与我发现的任何用户无关的仓库),我将其扩展为围绕查询树的 BFS:被限制的节点首先按语言拆分,然后按许可证,再按更深的前缀,直到每个分支适应 200 个结果。去重所有来源中的仓库 ID 后,生成了一组 7,256,531 个独特公共 Gitee 仓库的工作集。连接扫描管道 下一个挑战是克隆和扫描 725 万个仓库。为了在单个 Python 脚本中完成此任务,我使用了 Modal,一个专为 AI 工作负载而流行的无服务器计算平台,但同样适合大多数并行作业。我对每个仓库并发运行 TruffleHog 和 Kingfisher,以增加覆盖范围。每个表面都验证了另一个错过的凭证,因此同时运行两个可以捕获更多曝光的凭证而非单独一个。图 1. 双扫描器管道架构。
阅读全文 →本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡