libnet使用举例(7)
作者:小四 (scz@nsfocus.com)
主页:http://www.nsfocus.com
日期:2000-08-15
这次以构造DNS报文为例继续介绍libnet库编程。
./linuxkiller -o 44 -y 53 -s 192.168.10.1
ping bbs.tsinghua.edu.cn后抓取如下报文:
[ udp ] 192.168.10.1 [ 1476 ] -> 192.168.0.2 [ 53 ]
udpHeadLen = 8 udpDataLen = 37
byteArray [ 37 bytes ] ---->
00000000 42 83 01 00 00 01 00 00-00 00 00 00 03 62 62 73 B?..........bbs
00000010 08 74 73 69 6E 67 68 75-61 03 65 64 75 02 63 6E .tsinghua.edu.cn
00000020 00 00 01 00 01 .....
42 83 id 标识符
01 00 param 参数 正向解析请求报文,允许递归解析
00 01 qtcount 问题数
00 00 ancount 回答数
00 00 aucount 管理机构数
00 00 adcount 其他信息数
03 62 62 73 bbs 长度域为03
08 74 73 69 6E 67 68 75 61 tsinghua 长度域为08
03 65 64 75 edu 长度域为03
02 63 6E cn 长度域为02
00 长度域为0,表示结束
00 01
00 01
这是一个相当标准的DNS查询报文,不理解的话可以翻看RFC。构造一些边界情形的
DNS报文,如果DNS SERVER没有处理边界情形,结果未知。
./linuxkiller -o 44 -x 53 -s 192.168.0.2
ping bbs.tsinghua.edu.cn后抓取如下报文:
[ udp ] 192.168.0.2 [ 53 ] -> 192.168.10.1 [ 1476 ]
udpHeadLen = 8 udpDataLen = 165
byteArray [ 165 bytes ] ---->
00000000 30 8F 81 80 00 01 00 02-00 02 00 02 03 62 62 73 0弫€.........bbs
00000010 08 74 73 69 6E 67 68 75-61 03 65 64 75 02 63 6E .tsinghua.edu.cn
00000020 00 00 01 00 01 C0 0C 00-05 00 01 00 01 50 DC 00 .....?......P?
00000030 19 03 62 62 73 03 6E 65-74 08 74 73 69 6E 67 68 ..bbs.net.tsingh
00000040 75 61 03 45 44 55 02 43-4E 00 C0 31 00 01 00 01 ua.EDU.CN.?....
00000050 00 00 14 71 00 04 CA 70-3A C8 C0 35 00 02 00 01 ...q..蕄:壤5....
00000060 00 01 50 DD 00 06 03 6F-61 72 C0 35 C0 35 00 02 ..P?..oar??..
00000070 00 01 00 01 50 DD 00 0D-04 6D 6F 6F 6E 05 62 6A ....P?..moon.bj
00000080 6E 65 74 C0 42 C0 66 00-01 00 01 00 01 50 DD 00 net繠纅......P?
00000090 04 CA 70 3A CE C0 78 00-01 00 01 00 01 50 DD 00 .蕄:卫x......P?
000000A0 04 CA 70 04 41 .蕄.A
由于是两次查询,所以DNS应答报文的标识符和前面那个DNS查询报文的标识符并不一
致,如果是配对的两个报文,该标识符保持一致。回答分组有可能使用压缩格式,而
请求分组永远不会采用压缩格式。
30 8F 标识符
81 80 参数 正向解析响应报文,递归解析获得
00 01 问题数
00 02 回答数
00 02
00 02
03 62 62 73 bbs <-- 指针 = 12 (从数据区头部开始计算)
08 74 73 69 6E 67 68 75 61
03 65 64 75
02 63 6E
00
00 01
00 01
C0 0C 指针 = 12 (从数据区头部开始计算)
00 05 type = CNAME
00 01 class
00 01 50 DC 寿命
00 19 len = 25
03 62 62 73 bbs <-- 指针 = 49 (从数据区头部开始计算)
03 6E 65 74 net <-- 指针 = 53 (从数据区头部开始计算)
08 74 73 69 6E 67 68 75 61 tsinghua
03 45 44 55 EDU <-- 指针 = 66 (从数据区头部开始计算)
02 43 4E CN
00 结束
C0 31 指针 = 49 (从数据区头部开始计算)
00 01 type = A
00 01 class
00 00 14 71 寿命
00 04 len = 4
CA 70 3A C8 202.112.58.200
C0 35 指针 = 53 (从数据区头部开始计算)
00 02 type = NS
00 01 class
00 01 50 DD 寿命
00 06 len = 6
03 6F 61 72 oar <-- 指针 = 102 (从数据区头部开始计算)
C0 35 指针 = 53 (从数据区头部开始计算)
C0 35 指针 = 53 (从数据区头部开始计算)
00 02 type = NS
00 01 class
00 01 50 DD 寿命
00 0D len = 13
04 6D 6F 6F 6E moon <-- 指针 = 120 (从数据区头部开始计算)
05 62 6A 6E 65 74 bjnet
C0 42 指针 = 66
C0 66 指针 = 102
00 01 type = A
00 01 class
00 01 50 DD 寿命
00 04 len = 4
CA 70 3A CE 202.112.58.206
C0 78 指针 = 120
00 01 type = A
00 01 class
00 01 50 DD 寿命
00 04 len = 4
CA 70 04 41 202.112.4.65
上面这些报文分析去年在华中站Security版贴过,当时也没有人讨论它,这次再分析
一次,主要是为后面的DoS程序做准备。建议用NetXray抓来回的DNS报文,看看解析
后的直观显示,加强理解。
写linuxkiller的时候发现过许多关于DNS报文的问题。某次由于命令上指定过滤规则
失误,对非UDP 53端口的报文调用了doUdpDns()函数进行解析,结果进入了无限循环。
我的解析函数假设指针后面绝对不会再跟指针,对此没有进一步查看RFC,不知道RFC
是否有这个要求。解析函数的具体实现依赖于所接受的都是正常DNS报文,而非刻意
构造的攻击性报文。很多sniffer软件在解析DNS回答分组的时候没有处理边界情形,
前几个月BugTraq来了好几个关于这个问题的报告,包括tcpdump、L0pht的antisniff
等等都在解析DNS回答分组的时候存在问题。
还存在另外的问题。即使抛开指针,按照非压缩格式构造一个巨大的DNS回答分组而
不违背RFC是很简单的事情。我没有抓取攻击BIND 8的Exploit Code所发送出去的回
答分组,想来是利用了这点。今天才意识到DNS非压缩格式居然依赖于长度域为00标
识结束,这就和strcpy等字符串函数存在的问题类似了。
<待续>
作者:小四 (scz@nsfocus.com)
主页:http://www.nsfocus.com
日期:2000-08-15
这次以构造DNS报文为例继续介绍libnet库编程。
./linuxkiller -o 44 -y 53 -s 192.168.10.1
ping bbs.tsinghua.edu.cn后抓取如下报文:
[ udp ] 192.168.10.1 [ 1476 ] -> 192.168.0.2 [ 53 ]
udpHeadLen = 8 udpDataLen = 37
byteArray [ 37 bytes ] ---->
00000000 42 83 01 00 00 01 00 00-00 00 00 00 03 62 62 73 B?..........bbs
00000010 08 74 73 69 6E 67 68 75-61 03 65 64 75 02 63 6E .tsinghua.edu.cn
00000020 00 00 01 00 01 .....
42 83 id 标识符
01 00 param 参数 正向解析请求报文,允许递归解析
00 01 qtcount 问题数
00 00 ancount 回答数
00 00 aucount 管理机构数
00 00 adcount 其他信息数
03 62 62 73 bbs 长度域为03
08 74 73 69 6E 67 68 75 61 tsinghua 长度域为08
03 65 64 75 edu 长度域为03
02 63 6E cn 长度域为02
00 长度域为0,表示结束
00 01
00 01
这是一个相当标准的DNS查询报文,不理解的话可以翻看RFC。构造一些边界情形的
DNS报文,如果DNS SERVER没有处理边界情形,结果未知。
./linuxkiller -o 44 -x 53 -s 192.168.0.2
ping bbs.tsinghua.edu.cn后抓取如下报文:
[ udp ] 192.168.0.2 [ 53 ] -> 192.168.10.1 [ 1476 ]
udpHeadLen = 8 udpDataLen = 165
byteArray [ 165 bytes ] ---->
00000000 30 8F 81 80 00 01 00 02-00 02 00 02 03 62 62 73 0弫€.........bbs
00000010 08 74 73 69 6E 67 68 75-61 03 65 64 75 02 63 6E .tsinghua.edu.cn
00000020 00 00 01 00 01 C0 0C 00-05 00 01 00 01 50 DC 00 .....?......P?
00000030 19 03 62 62 73 03 6E 65-74 08 74 73 69 6E 67 68 ..bbs.net.tsingh
00000040 75 61 03 45 44 55 02 43-4E 00 C0 31 00 01 00 01 ua.EDU.CN.?....
00000050 00 00 14 71 00 04 CA 70-3A C8 C0 35 00 02 00 01 ...q..蕄:壤5....
00000060 00 01 50 DD 00 06 03 6F-61 72 C0 35 C0 35 00 02 ..P?..oar??..
00000070 00 01 00 01 50 DD 00 0D-04 6D 6F 6F 6E 05 62 6A ....P?..moon.bj
00000080 6E 65 74 C0 42 C0 66 00-01 00 01 00 01 50 DD 00 net繠纅......P?
00000090 04 CA 70 3A CE C0 78 00-01 00 01 00 01 50 DD 00 .蕄:卫x......P?
000000A0 04 CA 70 04 41 .蕄.A
由于是两次查询,所以DNS应答报文的标识符和前面那个DNS查询报文的标识符并不一
致,如果是配对的两个报文,该标识符保持一致。回答分组有可能使用压缩格式,而
请求分组永远不会采用压缩格式。
30 8F 标识符
81 80 参数 正向解析响应报文,递归解析获得
00 01 问题数
00 02 回答数
00 02
00 02
03 62 62 73 bbs <-- 指针 = 12 (从数据区头部开始计算)
08 74 73 69 6E 67 68 75 61
03 65 64 75
02 63 6E
00
00 01
00 01
C0 0C 指针 = 12 (从数据区头部开始计算)
00 05 type = CNAME
00 01 class
00 01 50 DC 寿命
00 19 len = 25
03 62 62 73 bbs <-- 指针 = 49 (从数据区头部开始计算)
03 6E 65 74 net <-- 指针 = 53 (从数据区头部开始计算)
08 74 73 69 6E 67 68 75 61 tsinghua
03 45 44 55 EDU <-- 指针 = 66 (从数据区头部开始计算)
02 43 4E CN
00 结束
C0 31 指针 = 49 (从数据区头部开始计算)
00 01 type = A
00 01 class
00 00 14 71 寿命
00 04 len = 4
CA 70 3A C8 202.112.58.200
C0 35 指针 = 53 (从数据区头部开始计算)
00 02 type = NS
00 01 class
00 01 50 DD 寿命
00 06 len = 6
03 6F 61 72 oar <-- 指针 = 102 (从数据区头部开始计算)
C0 35 指针 = 53 (从数据区头部开始计算)
C0 35 指针 = 53 (从数据区头部开始计算)
00 02 type = NS
00 01 class
00 01 50 DD 寿命
00 0D len = 13
04 6D 6F 6F 6E moon <-- 指针 = 120 (从数据区头部开始计算)
05 62 6A 6E 65 74 bjnet
C0 42 指针 = 66
C0 66 指针 = 102
00 01 type = A
00 01 class
00 01 50 DD 寿命
00 04 len = 4
CA 70 3A CE 202.112.58.206
C0 78 指针 = 120
00 01 type = A
00 01 class
00 01 50 DD 寿命
00 04 len = 4
CA 70 04 41 202.112.4.65
上面这些报文分析去年在华中站Security版贴过,当时也没有人讨论它,这次再分析
一次,主要是为后面的DoS程序做准备。建议用NetXray抓来回的DNS报文,看看解析
后的直观显示,加强理解。
写linuxkiller的时候发现过许多关于DNS报文的问题。某次由于命令上指定过滤规则
失误,对非UDP 53端口的报文调用了doUdpDns()函数进行解析,结果进入了无限循环。
我的解析函数假设指针后面绝对不会再跟指针,对此没有进一步查看RFC,不知道RFC
是否有这个要求。解析函数的具体实现依赖于所接受的都是正常DNS报文,而非刻意
构造的攻击性报文。很多sniffer软件在解析DNS回答分组的时候没有处理边界情形,
前几个月BugTraq来了好几个关于这个问题的报告,包括tcpdump、L0pht的antisniff
等等都在解析DNS回答分组的时候存在问题。
还存在另外的问题。即使抛开指针,按照非压缩格式构造一个巨大的DNS回答分组而
不违背RFC是很简单的事情。我没有抓取攻击BIND 8的Exploit Code所发送出去的回
答分组,想来是利用了这点。今天才意识到DNS非压缩格式居然依赖于长度域为00标
识结束,这就和strcpy等字符串函数存在的问题类似了。
<待续>