指纹识别之dns

https://ephen.me/2017/dns-tcp/
https://c.biancheng.net/view/6457.html
https://www.jianshu.com/p/b483300378af
https://www.cnblogs.com/549294286/p/5172448.html

wireshark数据包分析

Packet Details Pane(数据包详细信息), 在数据包列表中选择指定数据包,在数据包详细信息中会显示数据包的所有详细信息内容。数据包详细信息面板是最重要的,用来查看协议中的每一个字段。各行信息分别为
(1)Frame: 物理层的数据帧概况
(2)Ethernet II: 数据链路层以太网帧头部信息
(3)Internet Protocol Version 4: 互联网层IP包头部信息
(4)User Datagram Protocol: 传输层的数据段头部信息,此处是UDP
(5)Domain Name System : 应用层的信息,此处是DNS协议

请求包
在这里插入图片描述
响应包
在这里插入图片描述

DNS数据包格式

在这里插入图片描述
事务 ID、标志、问题计数、回答资源记录数、权威名称服务器计数、附加资源记录数这 6 个字段是DNS的报文首部,共 12 个字节。

整个 DNS 格式主要分为 3 部分内容,即基础结构部分、问题部分、资源记录部分。

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

标志字段又分为若干个字段
在这里插入图片描述
标志字段中每个字段的含义如下:
QR(Response):查询请求/响应的标志信息。查询请求时,值为 0;响应时,值为 1。
Opcode:操作码。其中,0 表示标准查询;1 表示反向查询;2 表示服务器状态请求。
AA(Authoritative):授权应答,该字段在响应报文中有效。值为 1 时,表示名称服务器是权威服务器;值为 0 时,表示不是权威服务器。
TC(Truncated):表示是否被截断。值为 1 时,表示响应已超过 512 字节并已被截断,只返回前 512 个字节。
RD(Recursion Desired):期望递归。该字段能在一个查询中设置,并在响应中返回。该标志告诉名称服务器必须处理这个查询,这种方式被称为一个递归查询。如果该位为 0,且被请求的名称服务器没有一个授权回答,它将返回一个能解答该查询的其他名称服务器列表。这种方式被称为迭代查询。
RA(Recursion Available):可用递归。该字段只出现在响应报文中。当值为 1 时,表示服务器支持递归查询。
Z:保留字段,在所有的请求和应答报文中,它的值必须为 0。
rcode(Reply code):返回码字段,表示响应的差错状态。当值为 0 时,表示没有错误;当值为 1 时,表示报文格式错误(Format error),服务器不能理解请求的报文;当值为 2 时,表示域名服务器失败(Server failure),因为服务器的原因导致没办法处理这个请求;当值为 3 时,表示名字错误(Name Error),只有对授权域名解析服务器有意义,指出解析的域名不存在;当值为 4 时,表示查询类型不支持(Not Implemented),即域名服务器不支持查询类型;当值为 5 时,表示拒绝(Refused),一般是服务器由于设置的策略拒绝给出应答,如服务器不希望对某些请求者给出应答。

在这里插入图片描述
在请求中 Questions 的值不可能为 0;Answer RRs,Authority RRs,Additional RRs 的值都为 0,因为在请求中还没有响应的查询结果信息。这些信息在响应包中会有相应的值。

在这里插入图片描述
Answer RRs,Authority RRs,Additional RRs 都有了相应的值(不一定全为 0)

问题部分
问题部分指的是报文格式中查询问题区域(Queries)部分。该部分是用来显示 DNS 查询请求的问题,通常只有一个问题。该部分包含正在进行的查询信息,包含查询名(被查询主机名字)、查询类型、查询类。
在这里插入图片描述
查询名:一般为要查询的域名,有时也会是 IP 地址,用于反向查询。
查询类型:DNS 查询请求的资源类型。通常查询类型为 A 类型,表示由域名获取对应的 IP 地址。
查询类:地址类型,通常为互联网地址,值为 1。

https://www.jianshu.com/p/b483300378af
DNS资源记录:A记录/AAAA记录、CNAME、MX、NS、TXT、SPF

【domain】 IN A 【IP地址】
【domain】 IN AAAA 【IP地址】
【別名】 IN CNAME 【原名】

jd.com,jd360.com,jingdong.com虽然是不同名字的域名,但是可以指向同一个原名jd.com。可以让企业的对外展示更加灵活。

【domain】 IN MX 【优先度】 【邮件服务器】

邮件路由记录

【domain】 IN NS 【DNS服务器】

指定域名解析服务器

【domain】 IN TXT 【任意字符串】

一般指某个主机名或域名的说明,或者联系方式,或者标注提醒等等。

【domain】 IN TXT 【送信侧邮件服务器确认规则】

SPF记录是TXT记录的一个运用。后面的备注需要按照指定的格式才能有效。

基于TCP的域名解析

https://ephen.me/2017/dns-tcp/

DNS 是同时占用 UDP 和 TCP 的 53 端口传输数据的,这种单个应用协议同时使用两种传输协议的情况,在 TCP/IP 栈中也算是个异类。
当我们在使用 tcpdump 、 WireShark 等抓包工具分析时,会发现几乎所有的 DNS 应用都是在使用 UDP 传输。
DNS在什么情况下才会用到 TCP 呢?

由于UDP是按照数据包来传输的,整个包最大只能 512 字节。一般正常情况下,用来 DNS 查询是绰绰有余的。但当解析配置过于复杂,或者记录值过长(如: TXT 、 RRSIG 记录)使得 UDP 无法承载的情况下,就有必要转换 TCP 查询。

由于基于 TCP 的域名解析非常少见,大多数域名厂商是不支持的, CloudXNS 也不例外。然而同域名同主机同线路的同类型解析将会封装到一个 UDP 包传输,如果内容过多(超过 512 字节),该数据包可能会承载不下。

这也是为什么 CloudXNS 中即使 A 、 TXT 、 MX 等类型记录尽管不与自身互斥,我们仍然会对同域名下同一主机同一线路限制解析记录条数的原因。

指纹识别代码

来自fingerprintx


package dns

import (
	"bytes"
	"crypto/rand"
	"net"
	"time"

	"github.com/praetorian-inc/fingerprintx/pkg/plugins"
	utils "github.com/praetorian-inc/fingerprintx/pkg/plugins/pluginutils"
)

const DNS = "dns"

type UDPPlugin struct{}
type TCPPlugin struct{}

func init() {
	plugins.RegisterPlugin(&UDPPlugin{})
	plugins.RegisterPlugin(&TCPPlugin{})
}

func CheckDNS(conn net.Conn, timeout time.Duration) (bool, error) {
	for attempts := 0; attempts < 3; attempts++ {
		transactionID := make([]byte, 2)
		_, err := rand.Read(transactionID)
		if err != nil {
			return false, &utils.RandomizeError{Message: "Transaction ID"}
		}

		InitialConnectionPackage := append(transactionID, []byte{ //nolint:gocritic
			// Transaction ID
			0x01, 0x00, // Flags: 0x0100 Standard query
			0x00, 0x01, // Questions: 1
			0x00, 0x00, // Answer RRs: 0
			0x00, 0x00, // Authority RRs: 0
			0x00, 0x00, // Additional RRs: 0
			0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x04, 0x62, 0x69, 0x6e, 0x64, 0x00, // Name: version.bind
			0x00, 0x10, // Type: TXT (Text strings) (16)
			0x00, 0x03, // Class: CH (0x0003)
		}...)

		if conn.RemoteAddr().Network() == "tcp" {
			InitialConnectionPackage = append([]byte{0x00, 0x1e}, InitialConnectionPackage...)
		}

		response, err := utils.SendRecv(conn, InitialConnectionPackage, timeout)
		if err != nil {
			return false, err
		}

		if len(response) == 0 {
			return false, nil
		}

		if conn.RemoteAddr().Network() == "udp" {
			if !bytes.Equal(transactionID[0:1], response[0:1]) {
				return false, nil
			}
		}

		if conn.RemoteAddr().Network() == "tcp" {
			if !bytes.Equal(transactionID[0:1], response[2:3]) {
				return false, nil
			}
		}
	}

	return true, nil
}

func (p *UDPPlugin) Run(conn net.Conn, timeout time.Duration, target plugins.Target) (*plugins.Service, error) {
	isDNS, err := CheckDNS(conn, timeout)
	if err != nil {
		return nil, err
	}

	if isDNS {
		payload := plugins.ServiceDNS{}
		return plugins.CreateServiceFrom(target, payload, false, "", plugins.UDP), nil
	}

	return nil, nil
}

func (p *UDPPlugin) PortPriority(i uint16) bool {
	return i == 53
}

func (p UDPPlugin) Name() string {
	return DNS
}

func (p *UDPPlugin) Type() plugins.Protocol {
	return plugins.UDP
}

func (p TCPPlugin) Run(conn net.Conn, timeout time.Duration, target plugins.Target) (*plugins.Service, error) {
	isDNS, err := CheckDNS(conn, timeout)
	if err != nil {
		return nil, err
	}

	if isDNS {
		payload := plugins.ServiceDNS{}

		return plugins.CreateServiceFrom(target, payload, false, "", plugins.TCP), nil
	}

	return nil, nil
}

func (p TCPPlugin) PortPriority(i uint16) bool {
	return i == 53
}

func (p TCPPlugin) Name() string {
	return DNS
}

func (p *TCPPlugin) Priority() int {
	return 50
}

func (p *UDPPlugin) Priority() int {
	return 50
}

func (p TCPPlugin) Type() plugins.Protocol {
	return plugins.TCP
}

构造的请求包类似
向某个DNS服务器发送下面的请求即可获得版本信息
dig @115.124.17.156 version.bind chaos txt

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开心星人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值