前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >工控网络基础入门篇之IPTables的m32模块

工控网络基础入门篇之IPTables的m32模块

作者头像
剑指工控
发布2021-11-09 10:52:40
5950
发布2021-11-09 10:52:40
举报
文章被收录于专栏:剑指工控

我们在前面提到了 GFW 对 DNS 劫持和污染的根源是在向境外 DNS 发起解析请求时,抢先返回虚假的 IP 信息给解析器。根据观察分析,GFW 伪造的虚假信息格式是非常固定的,甚至可以说是非常便于识别和拦截的。我们只要利用 iptables 的过滤规则,就可以很轻松的丢弃这些污染信息。

我们在前面也说了,境外 DNS 的正确信息不是不会返回,只是被 GFW 的虚假信息抢先占了位置导致不被解析器接受而已,而防火墙是一个在解析器之前的关卡,只要在这里丢弃了污染信息,那么境外 DNS 返回的正确信息就可以作为第一个到达的信息顺利被解析器接受了。

工欲善其事,必先利其器,我们要想过滤 GFW 的劫持信息,就要先了解这个数据的格式。在网络数据抓取上,业界公认的神器莫过于WireShark了,启动 wireshare 之后选择网卡,在过滤项中写 port 53,表示我们只查看数据信息中包含 53 端口的信息。为什么是 53 端口? 因为 DNS 服务器的查询端口是 53,然后我们通过 Dig 命令,指定使用 8.8.8.8 去查询 twitter.com 的 A 记录。可以看到如下的查询和返回信息:

虚假信息和正确信息混杂

可以看到,GFW 凭借自己的位置优势 (离我们近) 抢先返回了两个虚假的 IP 地址给我们,但后面 Google DNS 的正确信息也返回了,只是没有被解析器接受,我们要干掉的就是前面两条错误信息。观察多次之后我们发现这种信息的格式是完全一样的,区别仅仅是 IP 地址会在一个数组范围内变化: 可以看到 GFW 伪造的这个虚假信息非常粗糙,一般 DNS 都会返回一些 Additional 信息,例如告诉你这个域名的

污染信息实例

权威名称服务器地址之类的。GFW 的目的就是污染,只要把错误 IP 传达给你就完了,所以他整个消息包在虚假 IP 之后就没了,还真是精打细算节约流量呢。

我目前搜集和统计到的 GFW 用于 DNS 劫持的污染 IP 有 48 个,如下表所示:

118.5.49.6

128.121.126.139

159.106.121.75

169.132.13.103

188.5.4.96

189.163.17.5

192.67.198.6

197.4.4.12

202.106.1.2

202.181.7.85

203.161.230.171

203.98.7.65

207.12.88.98

208.56.31.43

209.145.54.50

209.220.30.174

209.36.73.33

209.85.229.138

211.94.66.147

213.169.251.35

216.221.188.182

216.234.179.13

23.89.5.60

243.185.187.39

249.129.46.48

253.157.14.165

37.61.54.158

4.36.66.178

46.82.174.68

49.2.123.56

54.76.135.1

59.24.3.173

64.33.88.161

64.33.99.47

64.66.163.251

65.104.202.252

65.160.219.113

66.45.252.237

72.14.205.104

72.14.205.99

74.125.127.102

74.125.155.102

74.125.39.102

74.125.39.113

77.4.7.92

78.16.49.15

8.7.198.45

93.46.8.89

转换成 16 进制就是:

042442 B2

0807 C62D

1759053 C

253 D369E

2 E52AE44

31027 B38

364 C8701

3 B1803AD

402158 A1

4021632 F

4042 A3FB

4168 CAFC

41 A0DB71

422 DFCED

480 ECD63

480 ECD68

4 A7D2766

4 A7D2771

4 A7D7F66

4 A7D9B66

4 D04075C

4 E10310F

5 D2E0859

76053106

80797 E8B

9 F6A794B

A9840D67

BC050460

BDA31105

C043C606

C504040C

CA6A0102

CAB50755

CB620741

CBA1E6AB

CF0C5862

D0381F2B

D1244921

D155E58A

D1913632

D1DC1EAE

D35E4293

D5A9FB23

D8DDBCB6

D8EAB30D

F3B9BB27

F9812E30

FD9D0EA5

为什么这里要把 IP 地址转换成 16 进制呢? 因为你知道整个计算机是基于 2 进制的,从上面的抓包你也可以看到实际的 IP 地址都是 16 进制的,我们过滤这些地址要用的 iptables 的 u32 模块也只认识 16 进制的数字。

u32 模块是 iptables 的一个扩展包,他允许你从一个 IP 数据包中抓取 4 个字节 (32 比特) 的数据,然后对这个 4 个字节的数据进行数值分析,在符合条件之后交给 iptables 进行各种处理。而 IP 地址刚好就是 4 个字节,那么我们只需要在 DNS 返回信息的 IP 包中提取出 IP 地址信息,然后和上面的这个列表对比,如果发现匹配就丢弃这个数据就可以了。

我们用到的完整命令如下:

命令有 5 条是因为 u32 模块一次最多允许我们匹配 10 个数据,具体格式的分析我们只需要看一条就够了,以第一条为例详细说明:

1. iptables -t mangle -I PREROUTING,这些和上一节是一样的,不重复了

2. -p udp,表示只分析 UDP 协议的数据,因为 DNS 查询默认都是 UDP 协议的

3. –sport 53,表示源端口是 53 的数据,因为 DNS 服务器返回的数据都是从它的 53 端口返回的

4. -m u32 –u32,这里表示使用 u32 模块,这是个标准命令格式

在开始后面的 u32 模块分析前,我们先补充介绍一下 DNS 响应包的数据组成。首先这是一个 IP 包,就有 IP 报头,另外这是 UDP 协议的,就有 UDP 报头,后面的 UDP 数据就是 DNS 服务器的响应数据了,所以格式是这样的:

[ IP_Header ]::[ UDP_Header ]::[ UDP_Data == DNS_Response ]

u32 模块部分的匹配代码是这样的:

0&0 x0F000000 =0 x05000000 && 22&0 xFFFF@16 =0 x4A7D7F66

• 0

第一个 0 表示从第 0 个字节开始抓 4 个字节,计算机世界一直都是从 0 开始数的。

• &0x0F000000

“&” 表示把前面抓到的 4 个字节和 “&” 后面的掩码进行 “与” 操作,这个就算是文科生也应该在计算机基础课上学过,不解释了。0x0F000000 就是这个掩码了,这表示其他位全部置 0,只保留第 0 字节的低 4 位。

• =0x05000000

“=0x05000000” 表示判断前面进行完与操作的数是不是等于 0x05000000. 如果你知道 IP 包的数据格式,就知道第 0 个字节的低 4 位表示的是 IP 报头的长度,一般来说都是 20 字节但也有特例。这里我们要确定这个报头没有什么特殊格式,长度确实是 20,为什么要判断这个长度后面会解释。

• 22&0xFFFF

这个表示从第 22 个字节开始取 4 个字节 (22∼25),和掩码 0xFFFF(0x0000FFFF) 与操作,也就是取 24,25

字节的内容,得到一个数 X。你抓包分析看一下就会发现,24,25 字节对应的数字是 UDP_Header 里表示 UDP 包的长度,也就是 UDP_Header+UDP_Data 的总长度。

• @

这个 @ 的作用非常大,一定要理解。@ 表示从 IP 包的最开始往后跳跃 X 个字节,具体跳跃多少呢? 就是 @ 前面的数值了。我们说了 @ 前面的一个与操作得到了 UDP 包的长度,也就是说这里我们要从 0 开始往后跳过 UDP 包的长度。整个 IP 包的长度是 IP 头长度 (20)+UDP 包的长度 (X),现在我们从 0 开始跳过了 UDP 包的长度 (X),就位于了整个 IP 包的最末再往前倒退 20 个字节的位置。

• 16

我们前面的抓包已经看到了,虚假的 IP 信息刚好位于整个 IP 包的最后 4 个字节,我们现在已经处在最末 -20 个字节的位置了,那么从这个位置开始数,抓第 16 个字节开始的 4 个字节就行了,也就是 16∼19 字节,为什么不是 17∼20? 我们是从第 0 个字节开始算的,别忘了这点。

后面的 -j DROP 就很好理解了,直接丢弃。在我们的防火墙中应用以上规则,GFW 的对境外 DNS 查询的劫持信息就被过滤掉了,剩下的就是正确的解析信息了。

但是要记住! 只有对境外 DNS 查询的污染包是 GFW 发出的,也只有这个情况下这个数据格式才是和我们的命令匹配的。虽然这可以解决大部分问题了,但有的时候我们还是需要境内 DNS+ 境外 DNS 组合的方式,因为境内 DNS 的速度比较快,而且他们对一些大网站的节点解析都比较适合我们。

但是我们在使用这些境内 DNS 面对的问题不是 GFW 的劫持,而是他们给出的原始数据就是被污染(被劫持后污染) 的。这样的结果是,他们给出的 DNS 响应包会因为服务器配置的格式不同而千差万别,而且基本确定的是 IP 都不是在最末的 4 字节上,因为正常的响应包末尾一般都是 Additional RRs 数据。我们想要使用境内 DNS 获得高速的解析又不想被污染,就要对境内 DNS 的响应数据也做过滤,那么这种 IP 位置不固定的响应包要如何过滤呢? 这里我们就要用到更强大的 string 模块了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-08-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 剑指工控 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档