原文地址:https://blog.christophetd.fr/bypassing-cloudflare-using-internet-wide-scan-data/
原文标题:CloudFlair: Bypassing Cloudflare using Internet-wide scan data
原文作者:Christophe Tafani-Dereeper
原文写于:2018/01/18
译者:驱蚊器喵#ΦωΦ
翻译水平有限,有不通顺的语句,请见谅。
Cloudflare 是一个在网站和网站用户之间的中间人服务, 保护网站免受各种攻击. 不幸的是, 这些网站常常配置不当, 让攻击者可以完全绕过 Cloudflare ,并发起 DDoS 攻击,或者利用基于 web 的漏洞发送本应被阻止的恶意漏洞利用代码. 本文将展示这个漏洞,并介绍自动检测工具 CloudFlair.
太阳被一片云遮住了视线. 照片来自 Pixabay.
Cloudflare 可以保护网站防御各种攻击. 他还可以作为 Web 应用防火墙 (WAF) 来阻止一些基于web的漏洞利用,比如 XSS 和 SQL 注入. It gained even more traction recently by announcing unmetered mitigation of DDoS attacks: Cloudflare 基本上表示他们会保护他们的客户免受任何规模的 DDoS 攻击,而不收取任何额外费用, 无论客户是在任何价位的套餐 (包含免费套餐).
在过去的几周, 我发现有几个使用了 Cloudflare 网站的配置有错误,可以让攻击者轻易绕过所有 Cloudflare 的保护. 这几家公司的网站上都有超过百万的用户在使用,是其市场的顶级领域公司之一.
一些有漏洞的网站会有公开的漏洞悬赏计划
需要明确的是, 这篇文章讨论的并不是 Cloudflare 服务本身的漏洞, 而是使用了Cloudflare的网站的管理员通常的错误配置.
注意: 就在发布这篇文章前的几分钟, 有个人提醒我注意一篇相似的文章 写于几个月前. 虽然如此,我还是会发布这篇文章,因为我相信他能提高我对这个主题的认识(并且我花了太多的时间写这篇文章).
背景: 使用 Cloudflare 保护网站
以下是不受Cloudflare保护时网站的通常请求流程。
- 用户向网站托管提供商的DNS服务器建立连接, 询问
example.com
网站IP地址 - DNS 服务器回应
example.com
的服务器的IP地址 (比如,93.184.216.34
) - 用户向web服务器发起 HTTP 请求
- web 服务器回应web网页数据
不受Cloudflare保护时网站的通常请求流程
由于任何人都可以直接访问托管example.com
的Web服务器,因此攻击者可能会通过对其进行DDoS攻击来破坏网站。 如果example.com
背后的基础设施不够强大,无法处理或阻止流量,那么该网站就可以完全被打到下线。
当公司 (或者个人) 决定使用 Cloudflare 来保护他们的网站
- 到他们的域名注册商, 将 DNS 服务器地址设置为 Cloudflare 的 (比如,
kim.ns.cloudflare.com
) ; - 设置 Cloudflare 账号来管理域名 (比如,
mycompany.com
).
现在, 当用户访问 mycompany.com
, 会发生以下的情况.
- 用户向 DNS 服务器
kim.ns.cloudflare.com
建立连接, 询问mycompany.com
网站的IP地址 - DNS 服务器返回Cloudflare中介服务器 IP 地址 (e.g.,
104.16.109.208
) - 用户向这台服务器发送 HTTP 请求
- Cloudflare 检查请求的合法性 (是否存在恶意请求内容,请求源IP地址,以及其他因素), 并决定放行或者阻断请求
- 如果 Cloudflare 选择让请求通过, 请求会被转发到负责
mycompany.com
网站的真实服务器 (比如,188.226.197.73
). 这台服务器通常被称为 源站服务器(origin server).
受Cloudflare保护时网站的通常请求流程
理论上, 攻击者无法直接访问源站服务器, 特别是不知道源站服务器的IP地址。然而, 这个保护依赖于源站服务器只能通过Cloudflare访问.
为了让这层保护生效, 攻击者必须无法直接连接源站服务器. 否则, 他只需要和源站服务器连接,而不需要通过 Cloudflare, 并且绕过所有的保护.
暴露的源站服务器
在Cloudflare后的源站服务器应该采取的正确行为是,只接受来自Cloudflare 的 IP 范围 的流量. 但是, 很多源站服务器接受了所有地址的流入流量. 我相信这是因为Cloudflare 的文档中没有强调这个问题. 我在文档中找到最相关的内容,是一个名为为Cloudflare所有用户推荐的第一步页面 :
Step 1:将 Cloudflare的 IP 地址放入白名单
一旦你 修改域名服务器到 Cloudflare, web 流量会被路由到 Cloudflare 的网络. 欧耶! 这就意味着你的网络服务器将收到Cloudflare的大量的经过代理后的流量 , 并且为了允许所有的流量访问它, 你将需要确保 Cloudflare 的 IP 们是在白名单中的,并且没有限制速率 . 这个页面包含了所有的 Cloudflare IP.
(我的强调部分)
你可以看到, 这里只告诉系统管理员,将Cloudflare 的 IP 地址白名单,但是没有明确指引需要阻止其他来源的传入流量. Cloudflare的博客中, 预防DDoS: 保护源站服务器 在我看来更加糟糕, 文中暗示,只需要让源站服务器的IP足够”秘密”即可.
Cloudflare 不能阻止知道你源站IP地址的攻击者直接向你发送流量. 只是因为你的源站服务器的IP地址不需要通过DNS,就已经连接到互联网. 如果你的IP地址不保密, 攻击者就能绕过 Cloudflare 的网络,直接攻击你的服务器.
(我的强调部分)
总而言之 – 只要没人能找到源站服务器的IP地址,那么它就是安全的.
Censys的互联网扫描数据
不幸的是, 在 2018 年, 依靠别人无法找到你的IP地址来保证安全,还能说有点乐观. 像 Shodan 或者 Censys 这样的项目会不停的扫描互联网中的主机,任何人都可以免费访问到这些数据.
举个随便的栗子, 他们只需要一秒钟就能检索出互联网上所有的 标题中包含Nicolas Cage
或者Rick Astley
HTTP 服务器 .
搜索的一个例子 (点击来放大)
Censys 非常适合查找暴露的源站服务器. 以下部分描述了使用Censys检测特定域名的公开源服务器的方法。
使用Censys查找某个域名的暴露的源站服务器
查找可公开访问的源站服务器的有效方法是,利用他们的 SSL 证书. 通过 Censys 证书搜索功能(Certificate search feature), 我们能搜索一个指定域名的有效 SSL 证书. Censys 从多个途径收集这些证书 (直接探测 443 端口, 以及证书透明项目(Certificate Transparency project)的日志信息).
举个例子, 查询请求 parsed.names: reddit.com and tags.raw: trusted
能用于查询颁发给reddit.com
的有效证书,或者是颁发给它的子域名. 这个 链接 会使用上述请求,直接跳转到 Censys 搜索.
查找颁发给reddit.com
的 SSL 证书,和它的子域名 (点击即可放大)
你可以看到,Censys 找到了 7 个单独的证书. 如果你单击某一个, 则可以选择查找在端口443上探测时,发现此证书的所有IPv4主机。
Finding IPv4 hosts using a specific SSL certificate (点击即可放大)
在这个 视图中,我们能看到,所有的 IPv4 主机使用的 SSL 证书的 SHA256 指纹信息是 36f7[…]815a0a.
这种简单的方式,来查找颁发了SSL证书到指定域名的 IPv4 主机,可以用于寻找源站服务器.
- 查找颁发给
mytarget.tld
域名的SSL 证书 - 找到所有使用了这些证书的 IPv4 主机
- 检查这些主机是否有可能是
mytarget.tld
的源站服务器
检查一个主机是否是(可能性)源站服务器
一旦我们有了一个潜在的源站服务器列表, 接下来的问题是: 我们如何评估那个主机就是特定Cloudflare保护域名后的源站服务器? 这里没有灵丹妙药(silver bullet),因为只有那家公司的系统管理员才会明确知道, 但是有一些启发式的方法可以提供帮助.
首先, 目标主机的IP地址不会在 Cloudflare IP 地址范围中, 否则, 我们找到的就是 Cloudflare 在源站和用户之间的中间人服务器. 然后, 目标主机的 HTML 回应应该类似于我们使用他的标准域名访问得到的回应 (比如, mytarget.tld
). 我之所以说类似,因为精确的相等在这里非常严谨, 当你在访问同一网页时,网页的每个部分都在发生变化 – CSRF tokens(令牌), 会话标识, 等等.
一旦我们找到一组符合这些标准的主机, 我们就可以基本相信我们找到了一组公开的源站服务器. 当然, 这些主机可能和 mytarget.tld
相似,但是实际上是开发环境或者是阶段性实例. 我们无法 100 % 信任, 但是可以直接浏览来帮助筛选, 并查看它是否能像访问mytarget.tld
的正式环境那样的行为: 能否注册账号? 能否登录你在mytarget.tld
创建的账号 , 反之亦然(vice versa)? 如果确定可以, 你就应该非常自信的确认你找到了一组不应公开的源站服务器.
请记住,通过在浏览器的地址栏中直接输入IP地址,来访问源站服务器,有时候不起作用, 因为运行的 web 服务器可能会验证一个 HTTP Host
请求头. 在这种情况下,你可以在Hosts
文件中添加一个静态映射,或者使用 curl
和Postman
这样的工具,在工具内可以设置指定的 Host
请求头.
使用 CloudFlair 自动处理
手动完成这个过程可能比较麻烦; 所以我写了个叫CloudFlair的工具来自动化完成 . 它会调用 Censys API 来搜索 SSL 证书和关联的 IPv4 主机. 一旦它使用之前描述的方式得到了潜在的源站主机列表, 它会挨个访问 ,并计算响应和原来域名返回响应的相似性. 它使用了一个结构相似的函数,这个函数被设计用于比较web网页 ( 这里描述的), 因为标准的字符串相似函数,比如 Levenshtein 距离对于计算常规web页面大小的运行太慢.
以下是一个示例的输出.
1 | $ python cloudflair.py myvulnerable.site |
获得了可能是源站服务器的IP地址列表后,你仍旧需要手工检查来确认这些结果.
修复措施
更新: 在 Cloudflare的CTO 在Twitter指出这个问题后, 未来最好的缓解措施可能是使用 Cloudflare Warp. 这个功能目前还在测试阶段, 但是可能成为扭转这个问题的重要功能. 我没有深入研究细节, 但是实质上,它允许你从专用网络(不可公开路由)打开一个通往 Cloudflare 的隧道, 确保只有 Cloudflare 能连接到你的源站服务器 (因为你的源站服务器没有暴露在公网中).
如果你的网站对于本文讨论的弱点有缺陷, 那么很可能没有简单的方法来解决. 一旦源站服务器的IP地址泄露了,游戏结束. Censys 使用的数据已经加上了版本管理, 并且任何人都可以在此下载 数据在任何时间的快照.而且, 现在服务器上的传入流量是不足以保护免受 DDoS 攻击的. 使用软件层面的iptables来丢弃流量,是不能保护攻击者发送的大流量数据包到服务器,这会消耗掉所有可用的带宽,让其不能被合法访问的用户访问.
以下两步措施是我推荐要做的.
- 第一步,应该是防止你的源站IP地址再次出现在 Censys 的扫描中, 并确保Cloudflare的应用层的安全功能无法被绕过 (比如 WAF 或者 HTTP 终点的速率限制).
- 第二步,应该是 (并且是唯一的方法) 防止攻击者对你发动 DDoS 攻击.
Step 1: 在传入流量启用防火墙或者开启 Authenticated Origin Pulls 功能
在你的源站服务器上配置,使之仅接受来自Cloudflare 的 IP 范围传入流量. 参考如下:
- https://danielmiessler.com/blog/whitelisting-cloudflare-iptables/
- https://support.cloudflare.com/hc/en-us/articles/200169166-How-do-I-whitelist-Cloudflare-s-IP-addresses-in-iptables-
注意: 在应用这些步骤之前, 请确保你了解 这将阻止你从SSH, RDP, FTP访问你的服务器, or 任何 基于非HTTP 的协议. 根据你的需要,这可能没问题. 但是, 如果你仍需要通过这些协议中的一种接入你的源站服务器, 那么你需要开启对应的端口.
另一种限制传入流量到 Cloudflare 的服务器的方法是,在账户上开启Authenticated Origin Pulls功能, 并对应的配置你的 web 服务器. 在与源站服务器通信的时候,这个功能可以让 Cloudflare 使用一个 TLS 客户端证书进行身份校验.
Step 2: 更换你的源站服务器IP地址
综上所述,一旦源站IP被泄露,游戏结束。最好的解决方案,如果可以的话,DDoS攻击也对你构成可信威胁的情况下,更换IP地址. 这要取决于你的服务器提供商, 可能很容易实现,也可能很难实现.
致谢
我想向下面的人们致以诚挚的谢意,感谢他们的多重建议和校对这篇文章!
- Julien Bachmann (Hacknowledge)
- Ludovic Barman
- Hadrien Milano
- Nicolas Reich
感谢你的阅读! 欢迎在下面评论或者给我发推 @christophetd 进行讨论和评论。