Scapy:DNS数据包详解

DNS 分为查询请求和查询响应,请求和响应的报文结构基本相同。DNS 报文格式如图所示。

      630f30f2510d46dda2fe3a38d95598c9.png

上图中显示了 DNS 的报文格式。其中,事务 ID、标志、问题计数、回答资源记录数、权威名称服务器计数、附加资源记录数这 6 个字段是DNS的报文首部,共 12 个字节。

整个 DNS 格式主要分为 3 部分内容,即基础结构部分、问题部分、资源记录部分。下面将详细地介绍每部分的内容及含义。

基础结构部分

DNS 报文的基础结构部分指的是报文首部,如图所示。

 bf4c98f1f4b04aa4a3b7f9c047fe59b1.png

该部分中每个字段含义如下。

  • 事务 ID:DNS 报文的 ID 标识。对于请求报文和其对应的应答报文,该字段的值是相同的。通过它可以区分 DNS 应答报文是对哪个请求进行响应的。
  • 标志:DNS 报文中的标志字段。
  • 问题计数:DNS 查询请求的数目。
  • 回答资源记录数:DNS 响应的数目。
  • 权威名称服务器计数:权威名称服务器的数目。
  • 附加资源记录数:额外的记录数目(权威名称服务器对应 IP 地址的数目)。


基础结构部分中的标志字段又分为若干个字段,如图所示。

 cdbc3d14327e4218baa48a164214cb2d.png

         而在scapy中,通常一个DNS数据包,客户端发送DNSQR请求包,服务器发送DNSRR响应包。一个DNSQR包含有解析域名qname、解析类型qtype、解析类别qclass。一个DNSRR包含有解析域名rrname、类型type、解析类别类别rtype、TTL等等。

使用ls函数查看DNS包的结构如下:

length     : ShortField (Cond)                   = None            ('None')
id         : ShortField                          = 0               ('0')
qr         : BitField  (1 bit)                   = 0               ('0')
opcode     : BitEnumField                        = 0               ('0')
aa         : BitField  (1 bit)                   = 0               ('0')
tc         : BitField  (1 bit)                   = 0               ('0')
rd         : BitField  (1 bit)                   = 1               ('1')
ra         : BitField  (1 bit)                   = 0               ('0')
z          : BitField  (1 bit)                   = 0               ('0')
ad         : BitField  (1 bit)                   = 0               ('0')
cd         : BitField  (1 bit)                   = 0               ('0')
rcode      : BitEnumField                        = 0               ('0')
qdcount    : DNSRRCountField                     = 0               ('None')
ancount    : DNSRRCountField                     = 0               ('None')
nscount    : DNSRRCountField                     = 0               ('None')
arcount    : DNSRRCountField                     = 0               ('None')
qd         : DNSQRField                          = None            ('None')
an         : DNSRRField                          = None            ('None')
ns         : DNSRRField                          = None            ('None')
ar         : DNSRRField                          = None            ('None')
 

解析如下:

length:

        表示除length占用的部分外的整个DNS数据长度,占用两个字节。这个标志只在TCP请求数据包中存在。

id:

        DNS 报文的 ID 标识。对于请求报文和其对应的应答报文,该字段的值是相同的。通过它可以区分 DNS 应答报文是对哪个请求进行响应的。

qr:

        查询请求/响应的标志信息。查询请求时为 0;响应时为 1。

opcode:

        操作码。

        0 为普通的 DNS 请求(标准查询),1为 rDNS 请求(反向查询),2为服务器状态请求,3无意义,4为通知 (Notify),

5为更新 (Update),6到15保留。

aa:

        授权应答。该字段在响应报文中有效。值为 1 时,表示名称服务器是权威服务器;值为 0 时,表示不是权威服务器。

tc:

       表示是否被截断。0表示未截断。1 表示响应已超过 512 字节并已被截断,只返回前 512 个字节。

rd:

       期望递归。该字段能在查询中设置,并在响应中返回。为1时,告诉名称服务器必须处理这个查询,这种方式被称为一个递归查询。如果该位为 0,且被请求的名称服务器没有一个授权回答,它将返回一个能解答该查询的其他名称服务器列表。这种方式被称为迭代查询。

ra:

        可用递归。该字段只出现在响应报文中。当值为 1 时,表示服务器支持递归查询。

z:

        保留字段,在所有的请求和应答报文中,它的值必须为 0。

ad:

        0为应答服务器未验证了该查询相关的 DNSSEC 数字签名,1为应答服务器已经验证了该查询相关的 DNSSEC 数字签名。

cd:

        0为服务器已经进行了相关 DNSSEC 数字签名的验证,1为服务器并未进行相关 DNSSEC 数字签名的验证。

rcode:

        返回码字段,表示响应的差错状态。

        0为正常

        1 为表示报文格式错误(Format error),服务器不能理解请求的报文。

        2 为表示域名服务器失败(Server failure),因为服务器的原因导致没办法处理这个请求。

        3为名称错误(Name Error),只有对授权域名解析服务器有意义,指出解析的域名不存在。

        4为查询类型不支持(Not Implemented),即域名服务器不支持查询类型。

        5为拒绝(Refused),一般是服务器由于设置的策略拒绝给出应答,如服务器不希望对某些请求者给出应答。

        6为域名出现了但是他不该出现。

        7为集合 RR 存在但是他不该存在。

        8为集合 RR 不存在但是他应该存在

        9为服务器并不是这个区域的权威服务器

        10为该名称并不包含在区域中

        11到15,保留

        16为错误的 OPT 版本或者 TSIG 签名无效

        17为无法识别的密钥

        18为签名不在时间范围内

        19为错误的 TKEY 模式

        20为重复的密钥名称

        21为该算法不支持

        22为错误的截断

        23到3840保留

        3841到4095私人使用

        4096到65534保留

qdcount:

        DNS 查询请求的数目。

ancount:

        DNS 查询请求的数目。

nscount:

        权威名称服务器的数目。

arcount:

        额外的记录数目(权威名称服务器对应 IP 地址的数目)。

qd:

        DNS解析部分,应传入DNSQR类

an:

        是DNS解析的回应部分,为DNSRR类。

ns:

        权威名称服务器区域。

ar:

       附加信息区域。

DNS解析类型

1.A记录解析

        记录类型选择“A”,记录值填写空间商提供的主机IP地址,MX优先级不需要设置,TTL设置默认的3600即可。

2.CNAME记录解析

        CNAME类型解析设置的方法和A记录类型基本是一样的,其中将记录类型修改为“CNAME”,并且记录值填写服务器主机地址即可。

3.MX记录解析

        MX记录解析是做邮箱解析使用的。记录类型选择MX,线路类型选择通用或者同时添加三条线路类型为电信、网通、教育网的记录,记录值填写邮局商提供的服务器IP地址或别名地址,TTL设置默认的3600即可,MX优先级填写邮局提供商要求的数据,或是默认10,有多条MX记录的时候,优先级要设置不一样的数据。

        这些解析类型即DNSQR.qtype、DNSRR.type的内容

DNSQR类解析

该类包含有以下内容

qname:

        查询名,一般为要查询的域名,有时也会是 IP 地址,用于反向查询。比如说www.sina.com。它由一个或者多个标示符序列组成。每个标示符已首字节数的计数值来说明该标示符长度,每个名字以0结束。计数字节数必须是0~63之间。该字段无需填充字节。
qtype:

        DNS 查询请求的资源类型。通常查询类型为 A 类型,表示由域名获取对应的 IP 地址。详见上文。
qclass:

        地址类型,通常为互联网地址,值为 1。

DNSRR类解析

该类包含有以下内容

rranme:

       域名,指DNS 请求的域名。即发送的DNSQR类中的qname。

type:

       资源记录的类型,与问题部分中的查询类型值是一样的。即发送的DNSQR类中的qtype。

rclass:

        地址类型,与问题部分中的查询类值是一样的。

ttl:

        生存时间,以秒为单位,表示资源记录的生命周期,一般用于当地址解析程序取出资源记录后决定保存及使用缓存数据的时间。它同时也可以表明该资源记录的稳定程度,稳定的信息会被分配一个很大的值。

rdlen:

        资源数据的长度。

rdata:

        指DNS记录中与类型相关的数据部分,表示按查询段要求返回的相关资源记录的数据。 比如对于DNS的A记录中的IPv4地址或者MX记录中的主机名及其优先级。

参考资料:

python scapy dns 包字段解析 - 御用闲人 - 博客园

用scapy模拟DNS放大攻击 - Capricorn.python - 博客园

Python 使用Scapy操作DNS流量 - lyshark - 博客园

DNS中的“无效Rdata”

DNS报文格式解析(非常详细)

DNS 标志位简要解析 - imlonghao

猜你喜欢

转载自blog.csdn.net/m0_71713477/article/details/128688373