文章来源|MS08067 内网安全知识星球
本文作者:Spark(Ms08067 内网小组成员)
众所周知,谷歌云和亚马逊云于2018年宣布停止支持域前置技术。在去年8月的DEFCON28上安全研 究人员发布了一款名为“Noctilucent”(夜光)的开源工具。该工具使用TLS1.3协议从某种程度上 复活了域前置技术。这一新技术被安全研究人员称为“域隐藏”。
1、域前置
域前置是一种隐藏连接真实端点来规避审查的技术,其原理为在不同通信层使用不同的域名:在明文的DNS请求和TLS服务器名称中使用无害的域名来初始化连接,而实际要连接的被封锁域名仅在创建加密的HTTPS连接后发出,使其不以明文暴露给网络审查者。
为了彻底地理解域前置,需要先了解一些HTTP和HTTPS的基础知识。
1.0 SNI
- SNI(Server Name Indication)是一个TLS的扩展,用于允许多个网站托管在同一个服务器 上。
- 对于TLS1.3来说,这个扩展是加密的,也就是ESNI(Encrypted Server Name Indication)。
1.1 HTTP基础
- 在一次HTTP连接中,用户的第一个外部请求是向DNS请求目标web服务器的IP地址
- 这是一个未加密的数据包,发送到UDP协议的53端口
- DNS会返回一个包含目标web服务器IP地址的响应包
- 该响应包也是未加密的
- 用户得知了该域名所部署的服务器的IP地址后,会对其发送一个GET请求,并将域名作 为“Host”请求头
- 也是未加密的数据包,通过TCP协议发送至80端口
- 服务器返回HTML的内容作为响应
这样的传输过程显然是有问题的:
- 没有任何数据是加密的
- DNS和HTTP的请求包和响应包都是明文传输的形式
为了解决以上的问题,HTTPS诞生了。
1.2 HTTPS基础
- 最初的步骤与HTTP相同,用户向DNS请求目标web服务器的IP地址
- 也是一个未加密的UDP连接
- DNS会返回一个包含目标web服务器IP地址的响应包
- 该响应包也是未加密的(与HTTP相同)
接下来才是HTTPS的不同之处:
- 用户会发送一个ClientHello来开始一个TLS握手
- 目标web服务器使用接收到“server_name”(明文)来查询如何响应
- 服务器返回一个带有证书的响应包SeverHello来完成TLS握手
- 该证书为明文传输,但TLS1.3除外
- 握手后客户端和服务端便会使用同样的加密算法加密数据以及交换session key
HTTPS的认证过程比HTTP安全很多,但是整个DNS的过程以及证书交换的过程仍然是未加密的。这 一点导致域名和证书可能会在客户端和服务端的中间环节被泄露。
1.3 域前置原理
- 通过混淆HTTPS中的域名来规避审查
- 连接至一个被允许的服务器,但是将HTTP请求发送给真正的目标
- 最大的一个限制,真假域名必须来自在相同的域名供应商
- Google App Engine
- Amazon S3/CloudFront
- Microsoft Azure CDN
- Others
接下来说明域前置的原理:
- DNS查询如同之前一样
- 客户端向服务器的握手请求也与之前相同,但是在握手时,客户端连接至被前置的域名,而不是真正的域名
握手的响应过程与之前相同
- 客户端将包含了真实域名的“Host”请求头的HTTP请求发送至真实目的服务器上
- 只要目的服务器的域名也在该服务商上,CDN就会分发该请求
任何GAE上的网站都可以被用来前置一个未经审查的GAE域名
你可以将域前置看成一个信封里的明信片:
- 客户端在信封上写上CDN的域名,但是真正的域名被写在信封里的明信片上
- 网络防火墙或者审计设备好比快递员,他们会允许并发送这封信件,因为信封上的域名是被允许的
- 当CDN收到信封后,打开信封,并将明信片送给真正的域名
这种技术在所有主流的CDN上都是可行的,直到2018年4月,俄罗斯政府向各大供应商施压,试图阻 止全球知名的app——Telegram使用谷歌云和AWS来实现域前置。谷歌云、亚马逊云等大型云服务商先后禁止了该服务。虽然后来Telegram找到了其他的方法来躲避俄罗斯政府的审查,俄罗斯政府也取消了该禁令,但是各大云服务商再也没有恢复过域前置技术。
1.4 域前置的问题
- 主流云服务商已禁用该技术
- 前置的域名有局限性
必须由相同服务商提供的域名才可以被前置
- 必须在云服务商中有一个账号 不免费
带宽
CPU时间
复杂的注册方式
身份认证
手机号
信用卡
2.域隐藏
为了解决上述的问题,安全人员开发了域隐藏技术。域隐藏能实现域前置的隐藏真实域名的目的。它 比域前置更灵活,只需要把域名DNS记录托管在Cloudflare,而主机服务器可以托管在任何地方。
2.1 DNS over TLS/HTTPS
在探究TLS1.3的结构之前,需要使DNS传输更加安全
- 如果将域名直接写在DNS请求中,防火墙或者审计者很轻松地就可以拦截我们的请求
- 同时安全的DNS传输也是ESNI的基础
解决办法就是将DNS查询包装在TLS连接中。可以使用DNS over HTTPS(DoH)来实现这一目的。DoH可以绕过一些防火墙和审计设备,并且该技术正被广泛地使用。
2.2 TLS1.3 ESNI
解决了DNS查询的加密问题后,还可以使用DoH为域名获取一个服务器的ESNI公钥,并用该公钥加 密ClientHello包中的server_name。当server_name被加密后,防火墙或者审计设备便无法根据 server_name来阻断非法域名的请求。
- 客户端使用DNS over TLS/HTTPS来请求IP地址和ESNI公钥
带有ESNI的TLS1.3连接中必须拥有服务器的公钥,用以加密ClientHello中的server_name。获取该 公钥的方式是使用DNS查询TXT记录中的_esni记录。
- DNS通过DNS over TLS/HTTPS来返回IP地址和一个base64加密过的ESNI公钥,客户端可以使 用该公钥生成一个session key来加密server_name
- 各大云服务商会定时刷新该公钥,例如CloudFlare每小时会刷新公钥
- 之后客户端发送一个TLS ClientHello请求,其中的server_name已被加密
- Web服务器返回一个带有加密证书的ServerHello,这一点是TLS1.3与之前版本的不同之处
3.示例
项目地址:
https://github.com/SixGenInc/Noctilucent
将CS的代理设为本地的9999端口,使用夜光斗篷(Noctilucent Cloak,详见github)配合 shadowsocks,可以实现域隐藏。该示例中,利用www.bitdenfender.com作为被隐藏的域名。
开启夜光斗篷并以socks4模式运行本地的shadowsocks服务。
在受害主机中运行payload,主机上线。
防火墙中只有cloudflare.com的记录
也查询不到bitdenfender.com的任何记录。