前言
最近遇到一个棘手的线上问题:其它市有用户反馈说某 APP 内的网页打开跳转到了不相关的恶意网站。在对服务器、主机配置、前端代码进行排查后尚未发现问题。但有个关键线索在于具有鲜明的区域特征——反馈区域较集中,仅在特定地市区域发生。除该地市外无其它地市反馈,遂将怀疑的目光投向了网络传输链路,推测这很可能是一次针对性的 DNS 劫持或 DNS 污染事件。
DNS的劫持&污染
DNS(Domain Name System),常被誉为互联网的“电话簿”,负责将我们容易记忆的域名(如 www.baidu.com
)翻译成机器能够识别的IP地址(如 1.1.1.1
)。然而,由于历史原因,传统的 DNS 查询过程几乎是“裸奔”的——它以明文方式在网络中传输,这就给路径上的运营商、ISP、路由器等中间节点留下了“可乘之机”。历史上也有相关的 DNS 劫持的案例说明如:Use of Rogue DNS Servers on Rise。
下面一表总结两者细致的区别:
特征 | DNS劫持(DNS Hijacking) | DNS污染(DNS Spoofing) |
---|---|---|
核心目的 | 牟利和欺诈 主要目的是将用户流量重定向到恶意网站(如钓鱼网站)、广告页面或安装恶意软件,以窃取信息或获取经济利益。 | 审查和封锁 主要目的是阻止用户访问特定网站或服务,使其无法访问或访问到一个无效的IP地址。 |
实施者 | 黑客、网络犯罪分子,有时甚至是ISP(为了广告) 实施者可以是个人或团体,目标可以是单个用户、一个路由器下的所有用户,或者某个 ISP 的所有用户。 | 大型网络运营商、G*W 等 通常是规模巨大、有组织的行为,由处于网络骨干位置的实体实施。 |
技术手段 | 篡改用户设置 / 控制 DNS 服务器 1. 本地篡改:通过恶意软件修改用户电脑的 hosts 文件或网络设置中的 DNS 服务器地址。 2. 路由器攻击:入侵用户的路由器,修改其 DHCP 配置,使所有连接到此路由器的设备都使用恶意的 DNS 服务器。 3. ISP层面劫持:ISP 修改自己的 DNS 服务器,将无法解析的域名(NXDOMAIN)或特定域名指向自己的广告服务器。 | “抢答”式攻击 / 中间人攻击 在用户向正确的 DNS 服务器查询时,攻击者监听查询请求。一旦发现是目标域名,它会伪造一个假的 DNS 响应,并利用网络延迟,抢在真正的 DNS 响应到达之前发送给用户。用户的 DNS 缓存会“中毒”,记下这个假地址。 |
影响范围 | 针对性、局部性 影响范围可大可小。小到一台被病毒感染的电脑,大到一个被黑客控制的公共 Wi-Fi,或者某个行为不当的 ISP 的所有客户。 | 大范围、区域性 通常影响一个国家或一个大型网络内的所有用户,具有广泛的地理特征。 |
结果表现 | 访问A网站,却打开了B网站(钓鱼、广告页) 用户尝试访问网站 A ,结果被重定向到一个看起来一模一样的假冒网站 B ,旨在窃取密码。 或者输入一个不存在的网址,会跳转到 ISP 的广告搜索页而不是标准的错误页。 | 网站无法访问或连接重置 用户尝试访问网站 A ,结果是连接超时、连接被重置,或者解析到一个完全不相关的、无法访问的 IP 地址。 |
尽管两者在动机和手段上有所不同,但可谓殊途同归:它们都通过操纵 DNS 解析过程,最终导致用户设备获取到错误的 IP 地址。对于用户而言,直观感受都是访问异常,难以区分其背后的根本原因。
演示
话不多说,那就使用相应的 APP 简单操作劫持一下吧,将目标 APP 访问网站时的域名请求劫持到预设的假网站。
1、搭建“山寨”服务器:
简单在自己的服务器上启用一个 Nginx Web 服务,并将其配置为“万能跳转机”,无论收到何种请求,都强制 301 重定向到自定义网站:
server {
# 监听80、443端口
listen 80 default_server;
listen 443 ssl default_server;
listen [::]:80 default_server;
listen [::]:443 ssl default_server;
http2 on;
# 通配符,匹配所有其他未匹配的主机名
server_name _;
#index index.html;
#root /usr/local/nginx/html;
# SSL证书
ssl_certificate /www/certs/xxx/fullchain.pem;
ssl_certificate_key /www/certs/xxx/privkey.pem;
# 任意请求过来皆将使用 301 重定向到百度
return 301 http://www.baidu.com;
# 日志记录,自定义是否留
access_log /www/wwwlogs/default-access.log;
error_log /www/wwwlogs/default-error.log;
}
2、模拟 DNS 劫持:
在一台已获取 Root 权限的 Android 设备上,直接修改 hosts 文件。hosts 文件拥有最高的DNS解析优先级,通过添加一条映射规则,我们将目标 APP 的业务域名强行指向我们搭建的“山寨”服务器 IP:
[root@mi-15:/data/ssh/root]# cat /system/etc/hosts
127.0.0.1 localhost
::1 ip6-localhost
# 增添一条域和IP的映射,将该域定向到目标IP
124.xxx.xxx.7 test.example.com.cn
[root@mi-15:/data/ssh/root]#
3、上在完成上述配置后,重新打开 APP 并访问相关功能。果不其然,页面直接跳转到了自定义的网站:
实验成功的关键在于,虽然目标 APP 的网络请求使用了 HTTPS 协议,但它并未严格执行证书校验。
当我们的“山寨”服务器返回一个与域名不匹配的无效 SSL 证书时,APP 的网络库选择了“信任”这个错误证书并继续进行 TLS 握手,最终成功与恶意服务器建立了连接从而导向自定义的网站。
防范
在 APP 上,主要有如下防范方式:
1、全局强制使用 HTTPS 协议:通过加密信道,即便 DNS 被劫持,攻击者也因无法提供合法的服务器证书而导致 TLS 握手失败,从而中断连接。
2、SSL/TLS 证书锁定(Certificate Pinning / Public Key Pinning):APP 内置服务器的公钥指纹,只认该“指纹”,任何伪造的证书都无法通过校验,从根本上杜绝了信任非法证书的可能。
3、使用 HTTPDNS 或 DoH :传统 DNS 基于 UDP 协议,其查询过程是为明文,极易遭受监听和篡改。HTTPDNS 和 DoH 技术将 DNS 查询封装在 HTTPS 请求中,让中间人无法窃听或篡改查询内容,确保 APP 从源头就能获取到正确的 IP 地址。
4、IP 地址直连:在 APP 中预置一份或多份服务器的 IP 地址列表。当所有 DNS 解析方式都失效时,可尝试直连 IP,确保核心功能的可用性。但这需要配合动态更新机制,以应对服务器 IP 变更。