碳基体

奋斗在产品安全第一线的安全妹子

十二、TCP/IP协议分析-DNS协议

一、DNS报文结构

DNS报文采用大端字节序,由DNS报头与DNS正文组成。

 

DNS报头定长12个字节,由

transaction ID 2个字节 

 + flags 2个字节

+questions 2个字节 查询段中的条目数

+answers RRs 2个字节 应答段中的资源记录数

+authority RRs 2个字节 授权段中的资源记录数

+additional RRs 2个字节  附加段中的资源记录数

组成。


其中flags对应的术语:

QR query/response 1位 0表示query 1表示response

OPCODE 4位   值为0表示标准查询,值为1表示逆向查询,值为2表示查询服务器状态,值为3保留,值为4表示通知,值为5表示更新报文,值6~15的留为新增操作用

AA 是否要求授权,在响应中有效

TC 是否截断

RD 是否期望递归

RA 是否递归可用

Z 保留位

RCODE 响应码4位:值0表示没有错误;1表示格式错误;2表示服务器故障;3表示名字错误,仅对来自权威服务器的响应有意义,表示查询中引用的域名不存在;4表示没有实现;5表示拒绝;6-15保留将来使用

bin(int('8180',base=16))‘0b1000000110000000' 


   



DNS正文包括

Question查询段、Answer应答段、Authority授权段、Additional附加段。

例如:对smtp.aol.com进行域名查询

    

Question查询段包括

qname 变长,以\0x00结尾

+ qtype 2个字节

+ qclass 2个字节 

  

  qtype常见的类型 

0x0010 (16)  表示TXT,e.x. cujo.movie.edu. IN TXT “Location: machine room dog house"

0x000f (15) 表示MX,  e.x. ora.com IN MX 0 ora.ora.com.

                                                        IN MX 10 ruby.ora.com

                                                        IN MX 10 opal.ora.com

0x001d (29)表示LOC location information,

0x000c (12) 表示PTR domain name pointer,e.x. 1.249.249.192.in-addr.arpa. IN PTR wormhole.movie.edu.

0x000d (13)表示 HINFO host information, e.x. grizzly.movie.edu. IN HINFO VAX-11/780 UNIX

0x0001  (1) 表示A (host address) e.x. localhost.movie.edu. IN A 127.0.0.1

0x001c  (28)表示AAAA (IPv6 address)

0x0005 (5) 表示CNAME ,e.x. wh.movie.edu. IN CNAME wormhole.movie.edu.

0x00ff (255) 表示 *(A request for all records the server/cache has available),

0x002 (2) 表示NS(authoritative name server),e.x. movie.edu. IN NS terminator.movie.edu

0x0021 (33)表示SRV(server selection)) 

0x0006 (6) 表示SOA 



Answer应答段、Authority授权段、Additional附加段包括: 

name 2个字节 域名重复出现的时候采用消息压缩。头2位都是11,用于与标识区区别,后14位表示偏移量

+ type  2个字节 

+ class  2个字节 

+ time to live 4个字节 

+ data length 2个字节 ,前2位必须是00,后面6位用于计算长度

+ data 变长

  

  

DNS数据格式

1. 2个字节整型

2. 4个字节整型

3. 域名

  

4.字符串

  


二、示例 

1. txt类型 可任意填写,可为空。一般做一些验证记录时会使用此项,如:做SPF(反垃圾邮件)记录

name 2个字节 域名重复出现的时候采用消息压缩。头2位都是11,用于与标识区区别,后14位表示偏移量

以0xc00c  为例:

bin(int('c00c',base=16)) ---> '0b1100000000001100'

int('00000000001100',base=2) --->12   ,头2位都是11,表示域名采用消息压缩,偏移量为12

+ type 2个字节  0x0010 10表示TXT类型

+ class 2个字节  0x0001

+ time to live 4个字节 0x0000010e

+ data length 2个字节  0x0010

+ data 变长 = (txt length 1个字节 0x0f + txt content组成)

  

2. MX类型 建立电子邮箱服务,将指向邮件服务器地址,需要设置MX记录。建立邮箱时,一般会根据邮箱服务商提供的MX记录填写此记录

 

name 2个字节 域名重复出现的时候采用消息压缩。头2位都是11,用于与标识区区别,后14位表示偏移量

以0xc00c  为例:

bin(int('c00c',base=16)) ---> '0b1100000000001100'

int('00000000001100',base=2) --->12   ,头2位都是11,表示域名采用消息压缩,偏移量为12

+ type 2个字节  0x000f 15表示MX类型

+ class 2个字节  0x0001

+ time to live 4个字节 0x00000228

+ data length 2个字节  0x000a

+ data 变长 = (preference优先级 2个字节 0x0028

 + mail exchange组成 0x 05 73 6d 74 70 34 c0 0c --> smtp4.google.com

      

3. A类型

  

name 2个字节 域名重复出现的时候采用消息压缩。头2位都是11,用于与标识区区别,后14位表示偏移量

以0xc02a  为例:

bin(int('c02a',base=16)) ---> '0b1100000000101010'

int('00000000101010',base=2) --->42   ,头2位都是11,表示域名采用消息压缩,偏移量为42

+ type 2个字节  0x0001 1表示A类型

+ class 2个字节  0x0001

+ time to live 4个字节 0x00000258

+ data length 2个字节  0x0004

+ data 变长 = (ip地址 0x d8ef251a

int('d8ef251a',base=16) ----> 3639551258

socket.inet_ntoa(struct.pack('!L',3639551258)) ---> 216.239.37.26

 )

  4. PTR类型 PTR记录是A记录的逆向记录,又称做IP反查记录或指针记录,负责将IP反向解析为域名 

name 2个字节 域名重复出现的时候采用消息压缩。头2位都是11,用于与标识区区别,后14位表示偏移量

以0xc00c  为例:

bin(int('c00c',base=16)) ---> '0b1100000000001100'

int('00000000001100',base=2) --->12   ,头2位都是11,表示域名采用消息压缩,偏移量为12

+ type 2个字节  0x000c 12表示PTR类型

+ class 2个字节  0x0001

+ time to live 4个字节 0x00015125

+ data length 2个字节  0x0020

+ data 变长 

  5. AAAA类型  将主机名(或域名)指向一个IPv6地址(例如:ff03:0:0:0:0:0:0:c1),需要添加AAAA记录 

name 2个字节 域名重复出现的时候采用消息压缩。头2位都是11,用于与标识区区别,后14位表示偏移量 

以0xc00c  为例:

bin(int('c00c',base=16)) ---> '0b1100000000001100'

int('00000000001100',base=2) --->12   ,头2位都是11,表示域名采用消息压缩,偏移量为12

+ type 2个字节  0x001c 28表示PTR类型

+ class 2个字节  0x0001

+ time to live 4个字节 0x00015180

+ data length 2个字节  0x0010

+ data 变长 

 

6. CNAME类型 如果将域名指向一个域名,实现与被指向域名相同的访问效果,需要增加CNAME记录。这个域名一般是主机服务商提供的一个域名

  name 2个字节 域名重复出现的时候采用消息压缩。头2位都是11,用于与标识区区别,后14位表示偏移量 

以0xc00c  为例:

bin(int('c00c',base=16)) ---> '0b1100000000001100'

int('00000000001100',base=2) --->12   ,头2位都是11,表示域名采用消息压缩,偏移量为12

+ type 2个字节  0x0005 5表示CNAME类型

+ class 2个字节  0x0001

+ time to live 4个字节 0x00000279

+ data length 2个字节  0x0008

+ data 变长 ( 0x 03 77 77 77 01 6c c0 10 --- www.l.google.com)

  7.NS类型  域名解析服务器记录,如果要将子域名指定某个域名服务器来解析,需要设置NS记录 

  

  name 2个字节 域名重复出现的时候采用消息压缩。头2位都是11,用于与标识区区别,后14位表示偏移量

以0xc00c  为例:

bin(int('c00c',base=16)) ---> '0b1100000000001100'

int('00000000001100',base=2) --->12   ,头2位都是11,表示域名采用消息压缩,偏移量为12

+ type 2个字节  0x0002 2表示NS类型

+ class 2个字节  0x0001

+ time to live 4个字节 0x0000000e

+ data length 2个字节  0x000e

+ data 变长 ( 0x 06 6e 73 2d 65 78 74 04 6e 72 74 31 c0 0c --- ns-ext.nrt1.isc.org)

  

  8.SOA 类型 SOA叫做起始授权机构记录,NS用于标识多台域名解析服务器,SOA记录用于在众多NS记录中那一台是主服务器 

  name 0x00

+ type 2个字节  0x0006 6表示SOA类型

+ class 2个字节  0x0001

+ time to live 4个字节 0x00000005

+ data length 2个字节  0x0040

+ data 变长 (Primary Name Server

 + Responsible authority's mailbox

+ serial number 4个字节

+ refresh interval 4个字节

+ retry Interval 4个字节

+ expire limit 4个字节

+ minimum ttl 4个字节)

  9. SRV 类型:添加服务记录服务器服务记录时会添加此项,SRV记录了哪台计算机提供了哪个服务。格式为:服务的名字.协议的类型(例如:_example-server._tcp) 

   name 0xc00c

+ type 2个字节  0x0021 33表示SRV类型

+ class 2个字节  0x0001

+ time to live 4个字节 0x00000258

+ data length 2个字节  0x001a

+ data 变长 (Priority 2个字节

 + weight 2个字节

+ Port 2个字节

+ target)

 

来源:碳基体