Domain fronting基本介绍

SoftNight 其他 2019年4月11日发布
Favorite收藏

导语:域前置技术已经出现有几年了,我一直都理解这个概念,但是从未真正理解它的工作原理。

域前置技术已经出现有几年了,我一直都理解这个概念,但是从未真正理解它的工作原理。直到最近,我跟Chris Truncer一起搞了个项目,他让我们设置域名前置,作为红队测试的一部分。也就是这时,我才不得不开始去认真琢磨和理解这个技术的内部共工作原理。幸运的是,Chris是一个非常不错的老师,它讲这个技术非常透彻,当我们一步一步去分析域前置的内部原理时,这个概念其实也非常简单。

在开始解释域名前置之前,我们先来回顾一下我们是如何获取网页的。

首先是网络请求

· 用户在浏览器里输入一个包含主机名的URL

· 操作系统在对主机名进行DNS查询

· 查到IP后,在两台主机之间建立TCP连接

现在有一个网络连接,应用程序启动并发送HTTP请求。在HTTP/1.0中,web服务器只能为每个IP地址提供一个web网站,因为它无法得知请求该网站的主机名。在HTTP/1.1中,引入了“host”头的概念,这让服务器能够基于提供主机名部署多个虚拟主机,也就是“命名虚拟主机”。服务器会根据已知的虚拟主机列表来检查所请求的主机名,然后选择正确的来提供服务。如果服务器不知道所请求的主机名,则使用默认站点来提供服务。

最基本的HTTP/1.1请求如下:

GET / HTTP/1.1
Host: digi.ninja

在浏览器发起的正常请求中,URL中的主机名应该与主机头中的主机名相匹配,但是也不一定是这样,因为没有任何措施来强制执行该链接。我们可以用curl来做一个演示,下面的这个请求将会与bing.com建立网络连接,但是通过主机头,最终会请求google这个网站。因为Bing并没有一个叫做google.com的虚拟主机,因此我们会得到一个报错:

$ curl -H "Host: google.com" bing.com
<h2>Our services aren't available right now</h2><p>We're working to restore all services as soon as possible. Please check back soon.</p>06XZVXAAAAAD6lfm8665lRL+M0r8EuYmDTFRTRURHRTA1MTMARWRnZQ==

我们再来尝试通过英国Google域名来请求澳大利亚Google网站:

$ curl -H "host: www.google.com.au" www.google.co.uk
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage"><head><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"><meta content="/images/branding/googleg/1x/googleg_standard_color_128dp.png" itemprop="image"><title>Google</title>...

这个请求成功了,因为UK Google服务器知道所有不同的虚拟主机,所以能够正确的转发请求并返回正确的内容。

现在我们已经了解了基础知识,我们来看看它是如何应用于域名前置的。

 

当我们在CDN(例如Amazon Cloudfront,Cloudflare,Microsoft Azure CDN或者是Google cloud CDN)上设置站点时,需要设置一个域名的CNAME记录来指向CDN服务器,并且有一个类似于“命令虚拟主机”需要在CDN web服务器上设置,这样它才能响应请求。该设置会提供一个“原始服务器”,会与入站的域进行配对,所以它才知道去哪里获取实际的内容并提供服务。

上面我们已经演示过,用来进行网络连接的主机名不一定要与所请求的网站相匹配,所以我们可以为部署在CDN上的一个站点使用主机名,但是在主机头中指向不同的站点。

那证书问题怎么办,使用不匹配的主机名和主机头不会出什么问题吗,不会造成证书警告或者泄露信息吗?当然不会。回到文章开头,设置的第一件事就是网络连接,这里就开始用到TLS了。一旦TCP连接成功建立,TLS就开始协商,并且全都是基于发起连接的主机名,主机头在应用层的流量中,并且在所有低层连接建立之前不会查看。我们可以继续使用Bing和Google的例子来演示,通过HTTPS来发起请求,同时使用curl来请求连接中的更多信息,如下:

$ curl -v -H "Host: google.com" https://bing.com
* Rebuilt URL to: https://bing.com/
*   Trying 13.107.21.200...
* TCP_NODELAY set
* Connected to bing.com (13.107.21.200) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
  * TLSv1.2 (OUT), TLS handshake, Client hello (1):
  * TLSv1.2 (IN), TLS handshake, Server hello (2):
  * TLSv1.2 (IN), TLS handshake, Certificate (11):
  * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
  * TLSv1.2 (IN), TLS handshake, Server finished (14):
  * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
  * TLSv1.2 (OUT), TLS change cipher, Client hello (1):
  * TLSv1.2 (OUT), TLS handshake, Finished (20):
  * TLSv1.2 (IN), TLS handshake, Finished (20):
  * SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
  * ALPN, server accepted to use h2
  * Server certificate:
  *  subject: CN=www.bing.com
  *  start date: Jul 20 17:47:08 2017 GMT
  *  expire date: Jul 10 17:47:08 2019 GMT
  *  subjectAltName: host "bing.com" matched cert's "bing.com"
  *  issuer: C=US; ST=Washington; L=Redmond; O=Microsoft Corporation; OU=Microsoft IT; CN=Microsoft IT TLS CA 5
  *  SSL certificate verify ok.
  * Using HTTP2, server supports multi-use
  * Connection state changed (HTTP/2 confirmed)
  * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
  * Using Stream ID: 1 (easy handle 0x559a18d7f900)
  > GET / HTTP/2
  > Host: google.com
  > User-Agent: curl/7.58.0
  > Accept: */*
  >
  * Connection state changed (MAX_CONCURRENT_STREAMS updated)!
  < HTTP/2 400
  < x-msedge-ref: 0OPdbXAAAAACPvltTXmg8T6Ynwb1og0T8TE9OMDRFREdFMDQyMABFZGdl
  < date: Thu, 07 Feb 2019 09:15:35 GMT
  <
  * Connection #0 to host bing.com left intact
  <h2>Our services aren't available right now</h2><p>We're working to restore all services as soon as possible. Please check back soon.</p>0OPdbXAAAAACPvltTXmg8T6Ynwb1og0T8TE9OMDRFREdFMDQyMABFZGdl

请求之后,会有很多的输出结果,但最重要的两行如下:

subject: CN=www.bing.com
subjectAltName: host "bing.com" matched cert's "bing.com"

这表明正在使用Bing的证书协商TLS连接,没有警告,因为证书有效,并且在HTTP请求中发送主机头之前也没有涉及到Google。

我跟Chris遇到的情况是这样的,我们使用前置技术来获取某公司基于HTTPS的CC通信,该公司使用了web过滤器来判断主机头,这个主机头是用来发起请求的。他们没有进行SSL剥离,这一点十分重要,因为这样可以让他们了解HTTP流量并且让他们也可以根据主机头来进行判断。我们选择了一家托管在Cloudfront的公司,该公司名声还不错,我们希望可以通过他们的过滤器。我们在Cloudfront上设置好我们的C2站点,将它的源指向我们的真实服务器。自定义的beacon软件使用正常的主机名来进行网络连接,在主机头中使用恶意的主机名。对于公司的过滤器来说,我们是在与一个正常的,值得信任的网站通信,但是CDN看到并响应了C2站点的请求,这些请求将所有流量直接转发到我们的服务器中。

在这个例子中,我们讲到了如何隐藏C2流量,不过这个技术也可以用来绕过审核过滤器和其他类似的情况。绕过审核的方法跟上面的例子相同,除了有一点,就是要查看的站点,前置了一个可信任站点和自定应浏览器插件,或者是本地网络代理,是否替换了主机头为正确的值。

如果你管理着一个域名并且通过CDN提供服务,你可能会想,我应该怎么做来防止我的好名声被滥用?依我看,啥也做不了。因为HTTP工作方式本身是存在漏洞的,网络连接和应用程序流量之间断开连接也是存在问题的。当你将你的站点托管在与其他站点共享的平台时,一旦建立了网络连接,所有其他站点都是可以访问的。甚至没有任何日志,你可以用来进行检查,因为当CDN见到主机头时,所有的流量就都转发到恶意的站点去了,所有的日志也同样在它的账户中。你唯一能做的是查看DNS日志并且尝试统计网站流量和请求,如果你看到有很多请求,但是却没有多少流量,那么这肯定不正常。

如果你想自己设置云端前置域名,你可以参考我的一篇文章Cloudfront域名前置–有效案例

相关文章:

Cloudfront域名前置

Cloudflare域名前置

本文翻译自:https://digi.ninja/blog/domain_fronting.php如若转载,请注明原文地址: https://www.4hou.com/others/16770.html
点赞 0
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论