记一次 GitHub Pages 博客被攻击与修复

从来没有想过 GitHub Pages 上托管的静态博客也会被攻击……

4 月 13 日晚上,我收到来自 Google Search Console 的邮件,提醒我的域名 brando.dev 新增了所有者。我顺着邮件提供的链接点击进入 Dashboard,却并没有看到除我之外的人被添加到了管理员或所有者一栏中,于是我并没有放在心上。

Google Search Console警报的截图

实际上,如果我在 Google Search Consle 中 添加资源 > 网址前缀 并输入我的域名前缀的话,就能够看到被添加的新所有者(攻击者)。出于神秘的原因,哪怕我将我的域名通过 网域 资源类型添加进行管理和监控,我能收到其他人通过 网址前缀 添加所有者的警告,但是我在自己的 网域 管理面板却看不到相关记录。这两种资源类型某种程度上似乎被视作不同的资源(但如果这样,为什么还会通知到我 网域 资源的关联账号呢?没搞懂 Google 团队的逻辑)。

当时,我只是又去域名服务商确认了我的域名仍正常续费之后,就睡觉了。我没想到一觉醒来,我又收到了来自 Google Search Consle 的多条警报:

AMP 警报邮件
商家信息结构化数据问题警报邮件
产品摘要结构化数据问题警报邮件

我一打开我的博客主页,才发现大事不妙:

我的主页竟然被篡改成了一个博彩网站!

我气坏了,第一反应是域名那边出问题了,毕竟最早也是 Google Search Console 给我发的警报。我点开 Google Search Console 里提及的修复问题,但仍未找到新添加的所有者账号,也无法直接在 Console 上修复问题。看起来 Console 上只能去验证问题修复了没有。我登录了域名提供商,确认域名仍然有效续费,并且 DNS 记录也没有被操作过。

我又测试了几个之前的博文链接,发现都会转到 GitHub Pages 的 404 页面,这更让我感到奇怪,GitHub Pages 提示 Page Not Found,说明请求是确实给到了 GitHub Pages,难道是我的 repo 被更改了?

我打开了自己的博客所托管的 GitHub repo,检查了静态文件,没有问题。以防万一我又重新 hexo generate 了一遍静态页面到部署分支,再次打开播客主页,还是博彩网站……

我的脑中一下闪过一个想法。我在浏览器地址栏输入并访问 brandozhang.github.io,果然能打开我的博客主页,而且链接没有被修改为 brando.dev,我的预想得到了印证。

我想,攻击者大概是用以下方式来实施域名劫持的。

一个正常的 GitHub Pages 访问流程如下图所示。如果像我一样设置了 Custom Domain,那么访客会通过 DNS 查询得到我自定义域名 brando.dev 的 A 记录所指向的 IP 地址,也就是 GitHub Pages 服务器的 IP 地址。
当访客真的去请求这个地址时,GitHub Pages Server 会通过 HTTP 请求头中的 Host 字段,从 GitHub 的记录中找到对应的 repository 是哪个,并将其静态页面返回。

GitHub Pages Custom Domain 路由过程

GitHub Pages 的 Custom Domain 功能是 GitHub Pro User 特有的。之前我使用了 GitHub Student Program 所赠送的 GitHub Pro User 服务免费使用这一功能,并且得以从 private repository 托管 GitHub Pages (这也是一项付费功能)。由于前一段时间毕业,我的 GitHub Student Program 失效,我也忘记续费,这直接导致 GitHub Pages Custom Domain 和 Host GitHub Pages from private repository 的功能失效。

攻击者在自己的 GitHub repository 中,可以声称 brando.dev 是属于自己的,添加 CNAME 并且在 GitHub Pages 的设置中添加这一 Custom Domain 设置。当设置生效后,下次有访客访问 brando.dev 时,GitHub Pages Server 就会根据记录,路由到攻击者的 repository,并且呈现攻击者托管的网站内容。当然了,攻击者要想使用 Custom Domain 的功能,应该也需要 GitHub Pro User。GitHub Pro User 的订阅量得到提升,它是最终赢家。

为了解决这个问题,我给 GitHub 充了钱来重新使用 Custom Domain 的功能……
然后我根据 这篇文档 在 GitHub 上重新验证了我对域名的归属权。按照 GitHub 的说法,一旦我 verify 了这个 custom domain,除非我后面撤销,不然不能有第二个人进行 verify。
需要注意的是,verify custom domain 之后大概 7 小时才会生效(虽然上面的文档说要 7 天),再此之后才能重新在 repository 中设置 custom domain 并将域名的路由纠正回来。


记一次 GitHub Pages 博客被攻击与修复
https://brando.dev/zh-hans/2024/05/03/记一次-GitHub-Pages-博客被攻击与修复/
作者
Brando ZHANG
发布于
2024年5月3日
许可协议