近日,国外安全研究人员 Gabor 发表了两篇关于如何利用基于 NTP (Network Time Protocol)的验证算法缺陷绕过 WordPress 登陆验证的文章,这两篇文章分别介绍了 基于 NTP 的验证算法缺陷 以及 如何利用该缺陷绕过 WordPress 登陆验证 并给出了 POC 和相关工具。以下内容是对这两篇文章的汇总介绍。 ;)
关于 NTP 相关的知识,可以在 这里 进行了解。
现在以 WordPress 的一款插件 Google Authenticator 为例来说明一般的 token 生成程序生成一次性密码(TOTP)的实现细节。
如下图所示,程序会使用一个密钥种子与当前服务器的时间戳进行 TOTP 算法后得出一个 6 位纯数字的 Token,该 Token 每 30 秒更换一次,其实这就是我们常见的 “动态口令”。
在这个动态口令生成过程中所存在的问题就在于每次使用相同的密钥种子和时间戳的组合总会生成一个相同的动态口令。而密钥种子是个不变量同时在攻击中不可控,因此只要控制了时间戳那么即可生成任意时间戳所对应的动态口令。
图 1 :基于 NTP 的 TOTP 算法
从目前来看有很多使用 NTP 的网络都没有对 NTP 传输过程进行加密验证。因此,攻击者就可以修改 NTP 传输的数据进行中间人攻击,给 NTP 客户端提供一个伪造的时间戳。 Gabor 在文章中提到了几个早先对 NTP 进行安全研究的文章资料和工具。
结合以上工具以及多种中间人攻击技术就可以通过 NTP 控制远程服务器的时钟。
在 Unix 中设置时间的 ntpd 服务不会接受一个伪造的虚假时间戳,所以无法进行时间戳的伪造攻击。不过,可以结合 CVE-2015-5300 漏洞进行攻击。
另外一种设置时间的方法是 ntpdate 。这种设置方式非常简单,也是 Ubuntu Wiki 中推荐的方式。因此,在很多地方都使用了这种方式进行时间设置。你可以参考 官方手册 和 这篇博文 进行设置。
设置的方式极其简单,在 corntab 中运行 ntpdate <hostname>
即可。但是值得注意的是 ntpdate 会接受任何来自于 NTP 服务的数据流! 。
几个有名的开源项目,如 Yocto Project , OpenWRT , Startups ,还有 托管在 GitHub 上的无数配置脚本,以及 5 万多 Docker 用户 ,甚至包括 VPS 提供商 都使用了 ntpdate 进行时间同步设置。
早在 2002年 就有人提出使用 corntab 运行 ntpdate 不是一个好主意。
通过上述描述,让我们来总结一下攻击 NTP 的现有条件:
WordPress 中的插件 Google Authenticator 可以对 WordPress 后台登录开启双重验证。如下图所示:
图 2 :Google Authenticator 插件对 WordPress 后台登录开启双重验证
由于可以利用中间人攻击设置服务器的时间一直为指定的时间,因此,可以使用暴力破解的手段对动态口令进行破解。大约最多需要一百万次的破解尝试。
搭建如下网络环境:
整个网络非常简单,三台 Ubuntu 虚拟机需要处于同一个子网中。如下图所示:
图 3 :搭建攻击网络环境
为了模拟中间人攻击以 篡改 NTP 传输数据 ,我们首先需要修改 WordPress 服务器的 /etc/hosts
文件,如下图所示:
图 4 :修改 /etc/hosts 文件
其次,我们假设管理员使用计划任务每隔一分钟同步一次时间(事实上很多人都是这么做的),如下图所示:
图 5 :管理员每隔一分钟同步一次时间
然后,我们使用预先设置的时间作为参数执行 Delorean ,同时 WordPress 服务器依旧会每隔一分钟同步一次时间。
图 6 :使用预先设置的时间作为参数执行 Delorean
现在,我们在另外一台虚拟机中,也就是攻击者的机器中运行 WPBiff。设置 WordPress 后台登录用户名和密码,以及与上图相同的时间戳作为运行参数。如下图所示:
图 7 :运行 WPBiff 开始攻击
在 WPBiff 运行了 39 分钟后,成功的爆破出了 6 位纯数字动态口令,同时 dump 出了有效的登陆 WordPress 后台的 session cookies。如下图所示:
图 8 :成功爆破出了动态口令
由于插件不允许动态口令的重用,所以可以使用 dump 出来的 session cookies 直接登录 WordPress 后台。 在额外的三次测试中,又分别花费了 51分钟,57分钟,83分钟 爆破出了动态口令。
图 9 :成功登陆 WordPress 后台