基于Python3的Scapy构造DNS报文

news2024/11/18 13:32:34

一:DNS协议

        DNS(Domain Name System)协议是计算机网络中的一种基础协议,它用于将域名(如www.baidu.com)转换为IP地址(如192.168.0.1),从而实现计算机之间的通信。

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

        上图中显示了 DNS 的报文格式。其中,事务 ID、标志、问题计数、回答资源记录数、权威名称服务器计数、附加资源记录数这 6 个字段是DNS的报文首部,共 12 个字节。
        整个 DNS 格式主要分为 3 部分内容,即基础结构部分、问题部分、资源记录部分。下面将详细地介绍每部分的内容及含义。

基础结构部分

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

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

  • 事务 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),一般是服务器由于设置的策略拒绝给出应答,如服务器不希望对某些请求者给出应答。

问题部分

问题部分指的是报文格式中查询问题区域(Queries)部分。该部分是用来显示 DNS 查询请求的问题,通常只有一个问题。该部分包含正在进行的查询信息,包含查询名(被查询主机名字)、查询类型、查询类。

问题部分格式如图所示。
 

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

  • 查询名:一般为要查询的域名,有时也会是 IP 地址,用于反向查询。
  • 查询类型:DNS 查询请求的资源类型。通常查询类型为 A 类型,表示由域名获取对应的 IP 地址。
  • 查询类:地址类型,通常为互联网地址,值为 1。

资源记录部分

资源记录部分是指 DNS 报文格式中的最后三个字段,包括回答问题区域字段、权威名称服务器区域字段、附加信息区域字段。这三个字段均采用一种称为资源记录的格式,格式如图所示。
 

资源记录格式中每个字段含义如下:

  • 域名:DNS 请求的域名。
  • 类型:资源记录的类型,与问题部分中的查询类型值是一样的。
  • 类:地址类型,与问题部分中的查询类值是一样的。
  • 生存时间:以秒为单位,表示资源记录的生命周期,一般用于当地址解析程序取出资源记录后决定保存及使用缓存数据的时间。它同时也可以表明该资源记录的稳定程度,稳定的信息会被分配一个很大的值。
  • 资源数据长度:资源数据的长度。
  • 资源数据:表示按查询段要求返回的相关资源记录的数据。

资源记录部分只有在 DNS 响应包中才会出现。下面通过 DNS 响应包来进一步了解资源记录部分的字段信息。

二:构造DNS报文

        scapy具有强大的报文构造能力和修改能力,我们一般定制化DNS报文都是修改DNS请求里的域名和响应里的IP地址。最方便的方法就是基于一个现有的DNS请求和响应报文去修改我们目标字段。

        我们可以先看看scapy解析dns的能力

 scapy解析请求和响应

###[ DNS ]### 
  id        = 49586
  qr        = 1
  opcode    = QUERY
  aa        = 0
  tc        = 0
  rd        = 1
  ra        = 1
  z         = 0
  ad        = 0
  cd        = 0
  rcode     = ok
  qdcount   = 1
  ancount   = 23
  nscount   = 2
  arcount   = 0
  \qd        \
   |###[ DNS Question Record ]### 
   |  qname     = 'upload-z1.qbox.me.'
   |  qtype     = A
   |  qclass    = IN
  \an        \
   |###[ DNS Resource Record ]### 
   |  rrname    = 'upload-z1.qbox.me.'
   |  type      = CNAME
   |  rclass    = IN
   |  ttl       = 516
   |  rdlen     = None
   |  rdata     = 'upload-z1.clouddn.com.'
   |###[ DNS Resource Record ]### 
   |  rrname    = 'upload-z1.clouddn.com.'
   |  type      = CNAME
   |  rclass    = IN
   |  ttl       = 80
   |  rdlen     = None
   |  rdata     = 'upload-z1-oss.clouddn.com.'
   |###[ DNS Resource Record ]### 
   |  rrname    = 'upload-z1-oss.clouddn.com.'
   |  type      = CNAME
   |  rclass    = IN
   |  ttl       = 54
   |  rdlen     = None
   |  rdata     = 'bc-gate-up.qiniu.com.'
   |###[ DNS Resource Record ]### 
   |  rrname    = 'bc-gate-up.qiniu.com.'
   |  type      = A
   |  rclass    = IN
   |  ttl       = 104
   |  rdlen     = None
   |  rdata     = 111.31.48.121
   |###[ DNS Resource Record ]### 
   |  rrname    = 'bc-gate-up.qiniu.com.'
   |  type      = A
   |  rclass    = IN
   |  ttl       = 104
   |  rdlen     = None
   |  rdata     = 111.31.48.33
   |###[ DNS Resource Record ]### 
   |  rrname    = 'bc-gate-up.qiniu.com.'
   |  type      = A
   |  rclass    = IN
   |  ttl       = 104
   |  rdlen     = None
   |  rdata     = 111.13.229.82
   |###[ DNS Resource Record ]### 
   |  rrname    = 'bc-gate-up.qiniu.com.'
   |  type      = A
   |  rclass    = IN
   |  ttl       = 104
   |  rdlen     = None
   |  rdata     = 111.13.229.81
   |###[ DNS Resource Record ]### 
   |  rrname    = 'bc-gate-up.qiniu.com.'
   |  type      = A
   |  rclass    = IN
   |  ttl       = 104
   |  rdlen     = None
   |  rdata     = 111.13.229.68
   |###[ DNS Resource Record ]### 
   |  rrname    = 'bc-gate-up.qiniu.com.'
   |  type      = A
   |  rclass    = IN
   |  ttl       = 104
   |  rdlen     = None
   |  rdata     = 111.13.229.74
   |###[ DNS Resource Record ]### 
   |  rrname    = 'bc-gate-up.qiniu.com.'
   |  type      = A
   |  rclass    = IN
   |  ttl       = 104
   |  rdlen     = None
   |  rdata     = 111.31.48.20
   |###[ DNS Resource Record ]### 
   |  rrname    = 'bc-gate-up.qiniu.com.'
   |  type      = A
   |  rclass    = IN
   |  ttl       = 104
   |  rdlen     = None
   |  rdata     = 111.13.229.73
   |###[ DNS Resource Record ]### 
   |  rrname    = 'bc-gate-up.qiniu.com.'
   |  type      = A
   |  rclass    = IN
   |  ttl       = 104
   |  rdlen     = None
   |  rdata     = 111.31.48.19
   |###[ DNS Resource Record ]### 
   |  rrname    = 'bc-gate-up.qiniu.com.'
   |  type      = A
   |  rclass    = IN
   |  ttl       = 104
   |  rdlen     = None
   |  rdata     = 111.31.48.122
   |###[ DNS Resource Record ]### 
   |  rrname    = 'bc-gate-up.qiniu.com.'
   |  type      = A
   |  rclass    = IN
   |  ttl       = 104
   |  rdlen     = None
   |  rdata     = 111.31.48.23
   |###[ DNS Resource Record ]### 
   |  rrname    = 'bc-gate-up.qiniu.com.'
   |  type      = A
   |  rclass    = IN
   |  ttl       = 104
   |  rdlen     = None
   |  rdata     = 111.31.48.21
   |###[ DNS Resource Record ]### 
   |  rrname    = 'bc-gate-up.qiniu.com.'
   |  type      = A
   |  rclass    = IN
   |  ttl       = 104
   |  rdlen     = None
   |  rdata     = 111.13.229.78
   |###[ DNS Resource Record ]### 
   |  rrname    = 'bc-gate-up.qiniu.com.'
   |  type      = A
   |  rclass    = IN
   |  ttl       = 104
   |  rdlen     = None
   |  rdata     = 111.31.48.123
   |###[ DNS Resource Record ]### 
   |  rrname    = 'bc-gate-up.qiniu.com.'
   |  type      = A
   |  rclass    = IN
   |  ttl       = 104
   |  rdlen     = None
   |  rdata     = 111.31.48.18
   |###[ DNS Resource Record ]### 
   |  rrname    = 'bc-gate-up.qiniu.com.'
   |  type      = A
   |  rclass    = IN
   |  ttl       = 104
   |  rdlen     = None
   |  rdata     = 111.31.48.22
   |###[ DNS Resource Record ]### 
   |  rrname    = 'bc-gate-up.qiniu.com.'
   |  type      = A
   |  rclass    = IN
   |  ttl       = 104
   |  rdlen     = None
   |  rdata     = 111.13.229.75
   |###[ DNS Resource Record ]### 
   |  rrname    = 'bc-gate-up.qiniu.com.'
   |  type      = A
   |  rclass    = IN
   |  ttl       = 104
   |  rdlen     = None
   |  rdata     = 111.13.229.80
   |###[ DNS Resource Record ]### 
   |  rrname    = 'bc-gate-up.qiniu.com.'
   |  type      = A
   |  rclass    = IN
   |  ttl       = 104
   |  rdlen     = None
   |  rdata     = 111.31.48.25
   |###[ DNS Resource Record ]### 
   |  rrname    = 'bc-gate-up.qiniu.com.'
   |  type      = A
   |  rclass    = IN
   |  ttl       = 104
   |  rdlen     = None
   |  rdata     = 111.31.48.24
  \ns        \
   |###[ DNS Resource Record ]### 
   |  rrname    = 'qiniu.com.'
   |  type      = NS
   |  rclass    = IN
   |  ttl       = 78188
   |  rdlen     = None
   |  rdata     = 'ns3.dnsv5.com.'
   |###[ DNS Resource Record ]### 
   |  rrname    = 'qiniu.com.'
   |  type      = NS
   |  rclass    = IN
   |  ttl       = 78188
   |  rdlen     = None
   |  rdata     = 'ns4.dnsv5.com.'
  ar        = None

[Finished in 2.3s]

 可以看到scapy具备完整的DNS解析能力,那我们的目标就是利用scapy的解析能力去修改我们的目标字段,另外修改目标字段后报文的各种校验和也需要重新计算。

        下面给出完整的构造DNS报文的代码

def dnsPcapProc(self):
        savefile = 'dns_'+ datetime.now().strftime("%H%M%S") + '.pcap'
        srcpcap = rdpcap(self.dnsPcapFilePath)
        srcpcap[1][DNS].show2()
        oriDomainLen = len(srcpcap[0][DNS].fields['qd'].fields['qname'])
        diff = len(self.dnsDomainInputEntry)+1 - oriDomainLen

        oriIPLen = srcpcap[0][IP].len
        oriUDPLen = srcpcap[0][UDP].len
        srcpcap[0][IP].len = oriIPLen + diff
        srcpcap[0][UDP].len = oriUDPLen + diff
        
        srcpcap[0][DNS].fields['qd'].fields['qname'] = self.dnsDomainInputEntry.encode("utf-8")
        
        try:
            del srcpcap[0][IP].len
            del srcpcap[0][IP].chksum
        except:
            srcpcap[0][DNS].fields['qd'].fields['qtype'] = 28
            del srcpcap[0][IPv6].plen
            del srcpcap[0][IPv6].chksum
            flg =6
        
        del srcpcap[0][UDP].len
        del srcpcap[0][UDP].chksum

        
        srcpcap[0][IP].len = oriIPLen + diff
        srcpcap[0][UDP].len = oriUDPLen + diff

        ip_list = list()

        ip_list.append(self.dnsIPInputEntry)

        srcpcap[1][UDP].payload.ancount = len(ip_list)
        srcpcap[1][UDP].payload.qd.qname =  self.dnsDomainInputEntry.encode("utf-8")
        dns_anser_as_ord = []
        for ip in ip_list:
            ipstr,flg = self.ipstr_trans2_hexlist(ip)
            if flg == 4:
                dns_anser_as_ord += [0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x1c, 0x20, 0x00, 0x04]
            else:
                dns_anser_as_ord += [0xc0, 0x0c, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x00, 0x1c, 0x20, 0x00, 0x10]
            dns_anser_as_ord += ipstr

        hexByteOri = "".join(["%02x" % c for c in dns_anser_as_ord]).encode("utf-8")
        hexByte = binascii.a2b_hex(hexByteOri)

        srcpcap[1][UDP].payload.an = hexByte
        try:
            del srcpcap[1][IP].len
            del srcpcap[1][IP].chksum
        except:
            del srcpcap[1][IPv6].plen
            del srcpcap[1][IPv6].chksum

        del srcpcap[1][UDP].len
        del srcpcap[1][UDP].chksum
        #srcpcap[0].show2()
        #wrpcap(savefile, srcpcap)
        pktdump = PcapWriter(savefile, append=True, sync=True)
        ether_layer = srcpcap[0]['Ether']
        newpcap = Ether(src=ether_layer.src, dst=ether_layer.dst) / srcpcap[0].getlayer('IP')
        newpcap2 = Ether(src=ether_layer.dst, dst=ether_layer.src) / srcpcap[1].getlayer('IP')
        pktdump.write(newpcap)
        pktdump.write(newpcap2)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1118299.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Unity地编细节】为什么Unity笔刷在地形上面刷不出来

👨‍💻个人主页:元宇宙-秩沅 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 秩沅 原创 😶‍🌫️收录于专栏:unity细节和bug 😶‍🌫️优质专栏 ⭐【…

【编解码】解码字符串中的 UNICODE 字符

前言 由于前后端交互中编码的问题,出现了这样的一串字符: {"share_names":["\u4e2d\u6587\u8def\u5f84"]}出现了unicode编码作为字符串内容的情况,直接用json解析的话会报错,所以在json解析前需要先进行转码…

Linux | 深入浅出冯诺依曼

前言 但凡是科班出生的小伙伴多多稍稍应该都听过冯诺依曼体系吧,这似乎已成为入门计算机的必备知识了,本章就带着大家一起去理解冯诺依曼体系; 一、体系构成 冯诺依曼体系主张计算机由五大部件组成,如下所示; 输入设备…

进程(0)——计算机的中的软硬件【Linux】

进程(0)——计算机的中的软硬件【Linux】 一.硬件:1.1 冯诺依曼结构:1.2 存储金字塔1.2.1输入设备和存储器:1.2.2输出设备和存储器: 二.软件:2.1 操作系统2.1.1 如何理解管理: 博主自…

【Asp.net】Asp.net core中IIS配置注意事项

1、应用地址池设为无托管代码 一、提示:关于IIS上运行ASP.NET Core 站点的“HTTP 500.19”错误 安装dotnet-hosting-3.1.2-win.exe ASP.NET Core 3.1 Runtime (v3.1.2)下载地址: https://download.visualstudio.microsoft.com/download/pr/dd119832-dc4…

visual studio Qt 开发环境中手动添加 Q_OBJECT 导致编译时出错的问题

问题简述 创建项目的时候,已经添加了类文件,前期认为不需要信号槽,就没有添加宏Q_OBJECT,后面项目需要,又加入了宏Q_OBJECT,但是发现只是添加了一个宏Q_OBJECT,除此之外没有改动其它的代码,原本…

AWS Lambda 操作 RDS 示例

实现目标 创建一个 Lambda 接收调用时传入的数据, 写入 RDS 数据库 Post 表存储文章信息. 表结构如下: idtitlecontentcreate_date1我是标题我是正文内容2023-10-21 15:20:00 AWS 资源准备 RDS 控制台创建 MySQL 实例, 不允许 Public access (后面 Lambda 需要通过 VPC 访问…

【Qt进阶之自定义控件】使用QListWidget实现自定义Item效果

目的 Q:如何在Qt库的基础上,实现自定义控件呢? A:根据官方文档回答,就是继承需实现的控件,然后实现自定义功能。 以下是实现QListWidget控件的自定义item。 先看下最终效果是如何: listItem 主…

基于YOLO实现的口罩佩戴检测 - python opemcv 深度学习 计算机竞赛

文章目录 0 前言1 课题介绍2 算法原理2.1 算法简介2.2 网络架构 3 关键代码4 数据集4.1 安装4.2 打开4.3 选择yolo标注格式4.4 打标签4.5 保存 5 训练6 实现效果6.1 pyqt实现简单GUI6.3 视频识别效果6.4 摄像头实时识别 7 最后 0 前言 🔥 优质竞赛项目系列&#xf…

正则表达式,日期选择器时间限制,报错原因

目录 一、正则表达式 1、表达式含义 2、书写表达式 二、时间限制 1、原始日期选择器改造 2、禁止选择未来时间 3、从...到...两个日期选择器的时间限制 三、Uncaught (in promise) Error报错 一、正则表达式 1、表达式含义 (1)/^([a-zA-Z0-9_.…

2.1.1BFS中的Flood Fill和最短路模型

1.池塘计数 农夫约翰有一片 N ∗ M N∗M N∗M 的矩形土地。 最近,由于降雨的原因,部分土地被水淹没了。 现在用一个字符矩阵来表示他的土地。 每个单元格内,如果包含雨水,则用”W”表示,如果不含雨水,…

Unity 文字显示动画(2)

针对第一版的优化,自动适配文字大小,TextMeshPro可以拓展各种语言。第一版字母类语言效果更好。 using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.UI;public partial class TextBeat…

CSS 三栏布局

左右两列定宽&#xff0c;中间自适应 浮动margin <style>.container {width: 500px;height: 200px;line-height: 200px;}.left {width: 100px;height: 100%;float: left;background: orange;text-align: center;}.right {width: 100px;height: 100%;float: right;back…

大模型必备算力:CPUGPU天梯图(2023年最新版)

在当今计算机世界&#xff0c;CPU、GPU和显卡的性能成为了衡量计算机性能的重要指标。今天深入了解CPU、GPU和显卡天梯图。 首先&#xff0c;CPU作为计算机的大脑&#xff0c;负责处理各种任务。它的性能主要由核心数、主频和缓存大小决定。其中&#xff0c;核心数和主频决定了…

学会使用Pandas进行数据清洗

大家好&#xff0c;如果你对数据科学感兴趣&#xff0c;那么数据清洗可能对你来说是一个熟悉的术语&#xff0c;本文将向你介绍使用Pandas进行数据清洗的过程。我们的数据通常来自多个资源&#xff0c;而且并不干净&#xff0c;它可能包含缺失值、重复值、错误或不需要的格式等…

二分查找,求方程多解

1.暴力遍历&#xff1a; 解为两位小数&#xff0c;故0.001的范围肯定可以包含&#xff08;零点存在&#xff09; 2.均分为区间长度为1的小区间&#xff08;由于两解&#xff0c;距离不小于1&#xff09;&#xff0c;一个区间最多一个解 1.防止两边端点都为解 2&…

JOSEF约瑟 JY82-III JY82-1P JY82J电压等级380V 检漏继电器 面板安装

系列型号&#xff1a; JY82A检漏继电器 JY82B检漏继电器 JY82-380/660检漏继电器 JY82-IV检漏继电器 JY82-2P检漏继电器 JY82-2/3检漏继电器 JJKY检漏继电器 JD型检漏继电器 JY82-IV;JY82J JY82-II;JY82-III JY82-1P;JY82-2PA;JY82-2PB 一、产品概述 检漏继电器 J…

GitHub和Gitee的区别以及具体使用

文章目录 GitHub和GiteeGitHub和Gitee区别GitHub的使用Gitee的使用 GitHub和Gitee GitHub和Gitee区别 速度不同&#xff1a;GitHub位于美国&#xff0c;而Gitee位于中国。这意味着在中国使用Gitee可能会有更快的访问速度和更好的稳定性。如果我们希望体验Git飞一般的速度&…

基本指令(1):操作系统/Xshell,文件,路径

一、操作系统 操作系统是一款进行软硬件资源管理的工具&#xff0c;对上提供良好、稳定的运行服务。 二、文件 1. 文件 文件内容 文件属性 2. 所有的文件操作&#xff1a; 对文件的内容进行操作 对文件的属性进行操作 三、路径 3.1 路径的概念 路径的本质是&#xff…

Transformers基本组件(一)快速入门Pipeline、Tokenizer、Model

Transformers基本组件&#xff08;一&#xff09;快速入门Pipeline、Tokenizer、Model Hugging Face出品的Transformers工具包可以说是自然语言处理领域中当下最常用的包之一&#xff0c;实现了大量的主流预训练模型架构&#xff0c;并提供了对应的与训练好的模型文件。 借助…