网络劫持攻击(一)——详解dns解析与劫持

628 阅读8分钟

前言

最近在工作时处理了一些关于HTTP/HTTPS请求中DNS被劫持问题。本文将简要梳理其中的内容,包括dns域名解析原理, dns劫持以及应对方案。并与网络劫持中的另一大类劫持——http劫持进行比对。

1. DNS解析

1.1 什么是DNS

DNS(Domain Name System 域名解析系统) ,将给定的域名解析为具体的IP地址。 在互联网上每个机器都是使用IP地址进行通信的, 由于IP地址是一串数字,不方便记忆,因此人们希望使用一串便于记忆的字符串代替IP, 这串字符就是IP对应的名字,简称域名。而使用域名访问的时候,需要借助dns(域名解析系统),将域名解析为具体的IP, 我们就可以跟这个IP通信。举例, 当我们访问谷歌时,在网页是以google.com域名搜索, 其实我们是跟93.46.8.90通信(比如dns将google.com解析为93.46.8.90), 显然记住google.com比93.46.8.90方便。

1.2 DNS工作原理

图1-1

上图演示了访问一个URL时DNS解析的全过程。注意,该图中忽略了查找本地DNS应用缓存、以及查找本地host文件的步骤。在DNS解析时的任意一步,只要找到对应域名记录,则服务器就会向主机返回结果并停止往下访问。图中的步骤如下所述(与上图中稍微不同,如下步骤中包含了本地查找):

  1. 判断一下DNS应用缓存是否有域名download.beta.example.com的IP,如果有直接返回。(对于浏览器来说可以开启禁用缓存, 那么将直接跳过这一步)

  2. 获取本地hosts文件,判断是否有域名download.beta.example.com的记录,如果有直接返回。(windows hosts文件默认保存在:C:\Windows\System32\Drivers\etc\hosts, 在linux上hosts文件位于/etc/hosts)。

  3. 将域名发送到本地DNS服务器,如果本地DNS缓存有域名download.beta.example.com的记录,直接返回。对应上图步骤1.

  4. 将域名download.beta.example.com发送到根服务器(Root Server),Root Server维护顶级域名服务器(eg, .com, .cn, .org等 全球13个)。Root Server识别到该顶级域名为com后,会将com域名服务器地址IP返回给请求者,声明其不知道域名地址,但是com域名服务器知道,你可以去找它。对应图中步骤2, 3

  5. 本地DNS服务器将域名download.beta.example.com发送到com域名服务器,com域名服务器它不知道该域名地址,但是它知道example.com域名服务器地址,于是返回将example.com地址返回并告诉请求者,你可以去哪里找它。对应图中步骤4,5

  6. 将域名download.beta.example.com发送到example.com域名服务器, example.com服务器它不知道该域名地址,但是它知道beta.example.com域名服务器地址,于是返回将beta.example.com地址返回并告诉请求者,你可以去哪里找它。对应图中步骤 6,7

  7. 将域名download.beta.example.com发送到beta.example.com域名服务器, beta.example.com服务器如果知道该域名地址,将返回download.beta.example.com地址并且将结果缓存到本地dns中, 如果不知道, 那么将中止继续递归访问。对应图中步骤8,9

  8. 将解析结果返回给用户, 整个dns解析结束。对应图中步骤10.

1.3 HTTP请求

为方便接下来对于DNS劫持的讲解,需要简单说一下HTTP请求的过程。

  1. 首先针对http请求URL中的host发起域名解析。
  2. 将域名解析后得到的IP地址,在互联网上发起http请求。
  3. http服务器响应请求后将http请求结果返回给用户。

2. dns劫持

DNS劫持也称域名劫持。 即当我们向DNS发起域名解析的请求,结果这个请求被劫持(攻击者截获了我们向DNS服务器发送的包),劫持之后攻击者可能不响应我们的请求,更多的是返回给我们错误的IP地址,将我们导向其他服务器,从而可以窃取我们的信息,甚至盗用我们的财务。当我们浏览网页时,如果DNS被劫持,可能访问到意想不到的网页。如下图所示。

ps:dns劫持其实并不是真的“黑掉”了我们的想访问的目标网站,而是冒名顶替、招摇撞骗罢了。

图2-1

因此,dns解析被劫持,我们如何判断以及处理。

  1. 当我们发起域名解析请求时,在本地hosts文件以及本地缓存没有找到对应的记录,我们就需要向外网发起域名解析请求,如果这时候被劫持,假如劫持之后没有返回解析IP给我们,那我们域名解析的接口会调用失败,这时候我们可以尝试调用几次,如果都失败,我们可以停下来分析,是否域名写错等等(如果有多个域名,程序可以自动切换其他域名解析尝试)

  2. 如果劫持之后返回无效的IP, 那么会导致我们无法连接上,最终在程序可以通过连接超时发现问题。(如果有多个域名,程序可以自动切换其他域名解析尝试)

  3. 如果劫持之后返回可以连接的IP,当我们成功连接此IP并且发送http请求,对方也响应此请求。那么我们应当如何辨别此响应是来自被劫持之后的服务器,而不是我们自己的服务器呢? (类似上图,用户访问建设银行服务器,由于被劫持,访问到了假的建设银行服务器,此时我们辨别此服务器真假呢? ) 比如我们可以让http头部携带多一个字段,用于鉴定此响应是否来自我们目标服务器。 对于每一个http请求的资源, 目标服务器拥有对应资源的唯一标识。并且服务器在响应客户端的请求时候,都会带上这个标识。 由于其他服务器没有我们请求资源的标志字段,因此,我们就可以通过判断http响应请求是否正确包含此字段,从而可以鉴别此服务器的真伪。

谁会劫持我们 ?

(1)运营商: 运营商主要是为了盈利,对我们访问的网页插入一些广告,让人烦厌的广告。

(2)gwf: 中国防火墙(Great Firewall of China),主要是劫持我们访问国外的网页。dns服务器解析出口要经过政府管辖的服务器(主要在北京,广州,上海),如果发现是解析国外的dns,那么会返回给我们无效的IP地址,让我们无法访问。

(3)其他第三方(主要是黑客)

3. http劫持

http劫持主要是http内容的劫持,如下图所示,即篡改了http请求响应的状态码,http头部信息,或者消息内容。

图3-1

http请求是在dns域名解析之后,拿到具体的IP,再发起http请求。

  1. 如果此http请求被劫持,劫持之后没有给我们应答,那么我们同样可以通过请求超时发现问题。
  2. 如果此http请求被劫持之后,虚假的服务器响应应答,那么我们也可以通过判断响应是否携带资源请求的唯一标识,来判断服务器的真伪。
  3. 如果http请求得到了目标服务器的真实响应,但是这个响应在返回过程被劫持了,而且被篡改信息,程序基本就没法判断响应信息是否被修改过了(因为http头部资源唯一标识没有被修改), 这样基本无解了。 为了避免这种情况,尽量使用https代替http。 如上图情况所描述。

借用知乎回答里很形象的比喻

  • DNS劫持的现象:你输入的网址是www.google.com,出来的是百度的页面。

  • HTTP劫持的现象:你输入的网址是www.google.com,出来的是谷歌的页面,但右下角弹出:偶系渣渣辉的广告。

4. DNS劫持的不完善的解决方案:HTTPDNS

传统使用dns服务器解析域名,即将要解析的域名向运营商的dns服务器发起解析的请求(本质发送udp报文)。 httpdns是基于http协议的域名解析服务, 我们使用的是腾讯提供的httpdns服务,即将要解析的域名以http协议发送到腾讯服务器,腾讯再使用权威的dns服务器查询域名,然后将查询结果返回。如下图所示,从而使我们绕过了本地dns解析造成的域名劫持问题。如下图所示。

图4-1

但是这个方法仅仅相当于用一个新的dns服务器替换了本地DNS服务器,实际有点换汤不换药的感觉。如果大家有更好的方案,欢迎在评论区里交流