96SEO 2026-02-19 21:40 9
。

能够很容易的创建#xff0c;发送#xff0c;捕获#xff0c;分析和操作网络数据包#xff0c;包括TCP#xff0c;UDP#xff0c;ICMP等协议#xff0c;此外它还提…Scapy
是一款使用纯Python编写的跨平台网络数据包操控工具它能够处理和嗅探各种网络数据包。
能够很容易的创建发送捕获分析和操作网络数据包包括TCPUDPICMP等协议此外它还提供了许多有用的功能例如嗅探网络流量创建自定义协议和攻击网络的安全测试工具。
使用Scapy可以通过Python脚本编写自定义网络协议和攻击工具这使得网络安全测试变得更加高效和精确。
读者可自行安装Scapy第三方库其次该工具依赖于PCAP接口读者可自行安装npcap驱动工具包具体的安装细节此处就不再赘述。
scapy安装Npcap驱动https://npcap.com/dist/
网络端口扫描用于检测目标主机上开放的网络端口。
端口扫描可以帮助安全专业人员识别存在的网络漏洞以及识别网络上的服务和应用程序。
在进行端口扫描时扫描程序会发送特定的网络数据包尝试与目标主机的每个端口进行通信。
如果端口处于打开状态则扫描程序将能够成功建立连接。
否则扫描程序将收到一条错误消息表明目标主机上的该端口未开放。
常见的端口扫描技术包括TCP连接扫描、SYN扫描、UDP扫描和FIN扫描等。
其中TCP连接扫描是最常用的一种技术它通过建立TCP连接来识别开放的端口。
SYN扫描则利用TCP协议的三次握手过程来判断端口是否开放而UDP扫描则用于识别UDP端口是否开放。
FIN扫描则是利用TCP
在动手开发扫描软件之前我们还是要重点复习一下协议相关的内容这样才能真正理解不同端口扫描方式的原理首先是TCP协议TCPTransmission
Protocol传输控制协议是一种面向连接的、可靠的、基于字节流的传输层协议。
下图是TCP报文格式
Port占用2个字节表示发送端使用的端口号范围是0-65535。
Port占用2个字节表示接收端使用的端口号范围是0-65535。
Number占用4个字节表示数据段中第一个字节的序号。
TCP协议中采用序号对数据进行分段从而实现可靠传输。
Number占用4个字节表示期望收到的下一个字节的序号。
TCP协议中采用确认号对接收到的数据进行确认从而实现可靠传输。
Offset占用4个位表示TCP头部的长度。
由于TCP头部长度是可变的该字段用于指示数据段从哪里开始。
控制位Flags占用6个位共有6个标志位分别为URG、ACK、PSH、RST、SYN和FIN。
其中URG、ACK、PSH和RST标志的长度均为1位SYN和FIN标志的长度为1位。
Pointer占用2个字节表示该报文的紧急数据在数据段中的偏移量。
选项Options可变长度用于协商TCP参数如最大报文长度、时间戳等。
对于端口扫描来说我们需要重点关注控制位中所提到的6个标志位这些标志是我们实现扫描的关键如下是这些标志位的说明
URG紧急指针标志位当URG1时表明紧急指针字段有效。
它告诉系统中有紧急数据应当尽快传送这时不会按照原来的排队序列来传送而会将紧急数据插入到本报文段数据的最前面。
ACK当ACK1时我们的确认序列号ack才有效当ACK0时确认序号ack无效在TCP协议中规定所有建立连接的ACK必须全部置为1。
PSH当该标志位被设置时表示TCP数据包需要立即发送给接收方而无需等待缓冲区填满。
这个操作被称为推送操作即将缓冲区的数据立即推送给接收方。
RST当RST1时表明TCP连接出现严重错误此时必须释放连接之后重新连接该标志又叫重置位。
SYN同步序列号标志位tcp三次握手中第一次会将SYN1,ACK0此时表示这是一个连接请求报文段对方会将SYN1,ACK1表示同意连接连接完成之后将SYN0。
FIN在tcp四次挥手时第一次将FIN1表示此报文段的发送方数据已经发送完毕这是一个释放链接的标志。
接着我们来具体看一下在TCP/IP协议中TCP是如何采用三次握手四次挥手实现数据包的通信功能的如下是一个简单的通信流程图
第一次握手建立连接时客户端A发送SYN包(SYNj)到服务器B以及初始序号X保存在包头的序列号(Sequence
Number)字段里并进入SYN_SEND状态等待服务器B确认。
2第二次握手服务器B收到SYN包必须确认客户A的SYN(ACKj1)同时自己也发送一个SYN包(SYNk)即SYNACK包此时服务器B进入SYN_RECV状态。
第三次握手客户端A收到服务器B的SYNACK包向服务器B发送确认包ACK(ACKk1)此包发送完毕客户端A和服务器B进入ESTABLISHED状态完成三次握手。
至此服务端与客户端之间就可以传输数据了。
首先我们先来构建并实现一个ICMP数据包在之前的文章中笔者已经通过C语言实现了数据包的构建当然使用C语言构建数据包是一件非常繁琐的实现通过运用Scapy则可以使数据包的构建变得很容易ICMP数据包上层是IP头部所以在构造数据包时应先构造IP包头然后再构造ICMP包头如下我们先使用ls(IP)查询一下IP包头的结构定义然后再分别构造参数。
IP(dst192.168.1.1,ttl64,iduuid)
ip上述代码中我们已经构造了一个IP包头接着我们还需要构造一个ICMP包头该包头的构造可以使用ICMP()并传入两个参数如下则是构造好的一个ICMP包头。
0xfc1d接着我们需要将上述两个包头粘贴在一起通过使用/将来给你这进行拼接并在icmp_header后面增加我们所有发送的数据包字符串最终将构造好的数据包存储至packet变量内此时输入packet.summary()即可查看构造的数据包字符串。
Raw当我们构造好一个数据包后下一步则是需要将该数据包发送出去对于发送数据包Scapy中提供了多种发送函数如下则是不同的几种发包方式当我们呢最常用的还是sr1()该函数用于发送数据包并只接受回显数据。
send(pkt)发送三层数据包但不会受到返回的结果sr(pkt)发送三层数据包返回两个结果分别是接收到响应的数据包和未收到响应的数据包sr1(pkt)发送三层数据包仅仅返回接收到响应的数据包sendp(pkt)发送二层数据包srp(pkt)发送二层数据包并等待响应srp1(pkt)发送第二层数据包并返回响应的数据包
此处我们就以sr1()函数作为演示目标通过构造数据包并调用sr1()将该数据包发送出去并等待返回响应数据到respon变量内此时通过对该变量进行解析即可得到当前ICMP的状态。
sr1(packet,timeout3,verbose0)respon
192.168.1.101}上述流程就是一个简单的ICMP的探测过程我们可以将这段代码进行组合封装实现ICMP_Ping函数该函数只需要传入一个IP地址即可返回特定地址是否在线同时我们使用ipaddress.ip_network则可生成一整个C段中的地址信息并配合threading启用多线程则可实现一个简单的主机存活探测工具完整代码如下所示
ICMP_Ping(addr):RandomIDrandint(1,65534)packet
sr1(packet,timeout3,verbose0)if
{}.format(str(respon[IP].src)))if
__main__:logging.getLogger(scapy.runtime).setLevel(logging.ERROR)#net
ipaddress.ip_network(192.168.1.0/24)parser
argparse.ArgumentParser()parser.add_argument(-a,--addr,destaddr,help指定一个IP地址或范围)args
ipaddress.ip_network(str(args.addr))for
threading.Thread(targetICMP_Ping,args(str(item),))t.start()else:parser.print_help()读者可自行运行上述程序片段并传入main.py
192.168.9.0/24表示扫描整个C段并输出存活主机列表其中logging模块则用于指定只有错误提示才会输出其他的警告忽略。
扫描结果如下图所示
接着我们继续实现路由追踪功能跟踪路由原理是IP路由每经过一个路由节点TTL值会减一假设TTL值为0时数据包还没有到达目标主机那么该路由则会回复给目标主机一个数据包不可达由此我们就可以获取到目标主机的IP地址我们首先构造一个数据包并设置TTL值为1将该数据包发送出去即可看到回显主机的IP信息。
timeRandomIDrandint(1,65534)packet
sr1(packet,timeout3,verbose0)respon
|关于如何实现路由跟踪具体来说一开始发送一个TTL为1的数据包这样到达第一个路由器的时候就已经超时了第一个路由器就会返回一个ICMP通知该通知包含了对端的IP地址这样就能够记录下所经过的第一个路由器的地址。
接着将TTL值加1让其能够安全的通过第一个路由器而第二个路由器的的处理过程会自动丢包发通包超时通知这样记录下第二个路由器IP由此能够一直进行下去直到这个数据包到达目标主机由此打印出全部经过的路由器。
将上述跟踪过程自动化就可以完成数据包的跟踪其Python代码如下所示。
range(1,128):RandomIDrandint(1,65534)packet
sr1(packet,timeout3,verbose0)if
{}.format(str(respon[IP].src)))else:print([]
{}.format(str(respon[IP].src)))return
__main__:logging.getLogger(scapy.runtime).setLevel(logging.ERROR)parser
OptionParser()parser.add_option(-a,--addr,destaddr,help指定一个地址或范围)(options,args)
options.addr:TraceRouteTTL(str(options.addr))else:parser.print_help()读者可自行运行上述程序片段并传入main.py
104.193.88.77表示跟踪从本机到目标104.193.88.77主机所经过的路由器地址信息并将扫描结果输出如下图所示
扫描又叫做全连接扫描它是一种常用的端口扫描技术。
在这种扫描中扫描程序向目标主机发送TCP连接请求包SYN包如果目标主机回应了一个TCP连接确认包SYN-ACK包则说明该端口处于开放状态。
否则如果目标主机回应了一个TCP复位包RST包或者没有任何响应则说明该端口处于关闭状态。
这种扫描技术的优点是准确性高因为它可以在不建立实际连接的情况下确定目标主机的端口状态。
但是缺点是这种扫描技术很容易被目标主机的防火墙或入侵检测系统检测到。
全连接扫描需要客户端与服务器之间直接建立一次完整的握手该方式扫描速度慢效率低我们需要使用Scapy构造完整的全连接来实现一次探测在使用该工具包时读者应该注意工具包针对flags所代指的标识符RA/AR/SA含义这些标志是Scapy框架中各种数据包的简写此外针对数据包的定义有以下几种
实现全链接扫描我们封装并实现一个tcpScan()函数该函数接收两个参数一个扫描目标地址一个扫描端口列表通过对数据包的收发判断即可获取特定主机开放状态
代表发送SYN报文sendsr1(IP(dsttarget)/TCP(dportport,flagsS),timeout2,verbose0)if
__main__:logging.getLogger(scapy.runtime).setLevel(logging.ERROR)#
argparse.ArgumentParser()parser.add_argument(-H,--host,desthost,help输入一个被攻击主机IP地址)parser.add_argument(-p,--port,destport,help输入端口列表
args.port:tcpScan(args.host,eval(args.port))else:parser.print_help()运行上述代码片段并传入59.110.117.109地址以及端口80,8080,443,445程序将依次扫描这些端口并输出如下图所示
SYN扫描又称半开式扫描该过程不会和服务端建立完整的连接其原理是利用了TCP协议中的一个机制即在TCP三次握手过程中客户端发送SYN包到服务端服务端回应SYNACK包给客户端最后客户端回应ACK包给服务端。
如果服务端回应了SYNACK包说明该端口是开放的如果服务端回应了RST包说明该端口是关闭的。
Connect扫描那样建立完整的连接因此不会留下大量的日志可以有效地隐藏扫描行为。
缺点是在扫描过程中会产生大量的半连接容易被IDS/IPS等安全设备检测到而且可能会对目标主机造成负担。
SYN扫描不会和服务端建立完整的连接从而能够在一定程度上提高扫描器的效率该扫描方式在代码实现上和全连接扫描区别不大只是在结束到服务端响应数据包之后直接发送RST包结束连接上述代码只需要进行简单修改将send_1处改为R标志即可
代表发送SYN报文sendsr1(IP(dsttarget)/TCP(dportport,flagsS),timeout2,verbose0)if
__main__:logging.getLogger(scapy.runtime).setLevel(logging.ERROR)#
argparse.ArgumentParser()parser.add_argument(-H,--host,desthost,help输入一个被攻击主机IP地址)parser.add_argument(-p,--port,destport,help输入端口列表
args.port:tcpSynScan(args.host,eval(args.port))else:parser.print_help()同理我们分别传入被扫描主机IP地址以及需要扫描的端口号列表当扫描结束后即可输出如下图所示的结果
SYN扫描类似。
不同之处在于UDP协议是无连接的、无状态的因此无法像TCP一样建立连接并进行三次握手。
客户端向服务器发送带有端口号的UDP数据包如果服务器回复了UDP数据包则目标端口是开放的。
如果服务器返回了一个ICMP目标不可达的错误和代码3则意味着目标端口处于关闭状态。
如果服务器返回一个ICMP错误类型3且代码为123910或13的数据包则说明目标端口被服务器过滤了。
如果服务器没有任何相应客户端的UDP请求则可以断定目标端口可能是开放或被过滤的无法判断端口的最终状态。
无状态扫描可能会出现误报或漏报的情况。
由于UDP协议是无连接的、无状态的因此UDP端口不可达错误消息可能会被目标主机过滤掉或者由于网络延迟等原因无法到达扫描主机从而导致扫描结果不准确。
sr1(IP(dsttarget)/UDP(dportport),timeout5,verbose0)if
%(target,port))elif(udp_scan_resp.haslayer(UDP)):if(udp_scan_resp.getlayer(TCP).flags
%(target,port))elif(udp_scan_resp.haslayer(ICMP)):if(int(udp_scan_resp.getlayer(ICMP).type)3
int(udp_scan_resp.getlayer(ICMP).code)
__main__:logging.getLogger(scapy.runtime).setLevel(logging.ERROR)parser
argparse.ArgumentParser()parser.add_argument(-H,--host,desthost,help)parser.add_argument(-p,--port,destport,help)args
args.port:udpScan(args.host,eval(args.port))else:parser.print_help()运行上述代码并传入不同的参数即可看到如下图所示的扫描结果读者需要注意因为UDP的特殊性导致端口扫描无法更精确的判定
https://www.lyshark.com/post/1a03a021.html
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback