现任明教教主Scapy模拟整个TCP连接过程
现任明教教主Scapy模拟整个TCP连接过程安全CCNA学习交流2群 451768824拓扑http://www.qytang.com/upload/images/2016-03-15/6359364137087274343259408.pngLinux上的特殊处理客户端linux需要做如下配置来防止发送不必要的reset:firewall-cmd --direct --add-rule ipv4 filter OUTPUT 1 -p tcp --tcp-flags RST RST -s 202.100.1.139 -j DROPsocket回显服务器#!/usr/bin/python3.4# -*- coding=utf-8 -*-http://www.qytang.com/upload/images/2016-03-15/6359364204560876105829488.pngmyHost = '202.100.1.138'myPort = 6668
if len(sys.argv) == 3: myHost, myPort = sys.argv
numPortSocks = 2
mainsocks, readsocks, writesocks = [], [], []for i in range(numPortSocks): portsock = socket(AF_INET, SOCK_STREAM) portsock.bind((myHost, myPort)) portsock.listen(5) mainsocks.append(portsock) readsocks.append(portsock) myPort += 1
print('select-server loop starting')while True: readables, writeables, exceptions = select(readsocks, writesocks, []) for sockobj in readables: if sockobj in mainsocks: newsock, address = sockobj.accept()
scapy实现整个TCP连接#!/usr/bin/python3.4# -*- coding=utf-8 -*-
import loggingimport relogging.getLogger("scapy.runtime").setLevel(logging.ERROR)from scapy.all import *
#设置目的端口号dstport = 6668#随机产生源端口sportid = random.randint(1024, 2000)#随机产生目的端口seqid = random.randint(20000, 30000)
#产生SYN包(FLAG = 2 为SYN)result_raw_synack = sr(IP(dst='202.100.1.138')/TCP(dport=dstport,sport=sportid,flags=2,seq=seqid), verbose = False)
#响应的数据包产生数组(为响应,为未响应)result_synack_list = result_raw_synack.res
#第一层位第一组数据包#第二层表示发送的包,表示收到的包#第三层为IP信息,为TCP信息,为TCP数据tcpfields_synack = result_synack_list.fields #由于SYN算一个字节,所以客户到服务器序列号(sc_sn)需要增加1sc_sn = tcpfields_synack['seq'] + 1cs_sn = tcpfields_synack['ack']
#发送ACK(flag = 16),完成三次握手!send(IP(dst='202.100.1.138')/TCP(dport=dstport,sport=sportid,flags=16,seq=cs_sn,ack=sc_sn), verbose = False) #发送数据(b"Welcome to qytang"),flag为24(ACK = 16,PUSH = 8)#注意‘multi=1’,服务器会先给一个ACK确认,然后发送回显数据。#如果客户没有及时确认,还会有多次重传!result_raw_msg = sr(IP(dst='202.100.1.138')/TCP(dport=dstport,sport=sportid,flags=24,seq=cs_sn,ack=sc_sn)/b"Welcome to qytang", verbose = False, multi=1, timeout=1)
#响应的数据包产生数组(为响应,为未响应)result_msg_list = result_raw_msg.res #提取服务器响应包的IP信息,生成字典(注意是提取的第二组数据,第一组仅仅是ACK)msgback_ip_fields = result_msg_list.fields#提取服务器响应包的TCP信息,生成字典(注意是提取的第二组数据,第一组仅仅是ACK)msgback_tcp_fields = result_msg_list.fields#提取服务器响应包的TCP数据信息,生成字典(注意是提取的第二组数据,第一组仅仅是ACK)msgback_data_fields = result_msg_list.fields
#如果回显数据中有‘Echo’字段就打印回显内容if re.search(b'Echo', msgback_data_fields['load']): print(msgback_data_fields['load']) #技术数据长度,ip总长度 - ip头部长度(['ihl']*4) - tcp头部长度(['dataofs']*4)data_len = msgback_ip_fields['len'] - msgback_ip_fields['ihl']*4 - msgback_tcp_fields['dataofs']*4 #客户到服务器端的序列号为,服务器回显中的‘seq’加上传输的数据长度!sc_sn = msgback_tcp_fields['seq'] + data_lencs_sn = msgback_tcp_fields['ack']
#发送ACK对服务器的回显进行确认,flag = 16(ACK)send(IP(dst='202.100.1.138')/TCP(dport=dstport,sport=sportid,flags=16,seq=cs_sn,ack=sc_sn), verbose = False) #客户端主动发送FIN(1) + ACK(16),进行连接终结。result_raw_fin = sr1(IP(dst='202.100.1.138')/TCP(dport=dstport,sport=sportid,flags=17,seq=cs_sn,ack=sc_sn), verbose = False)
#由于FIN算一个字节,所以客户到服务器序列号(sc_sn)需要增加1sc_sn = result_raw_fin.fields['seq'] + 1cs_sn = result_raw_fin.fields['ack'] #发送最后一个ACK(16),结束整个TCP连接!!!send(IP(dst='202.100.1.138')/TCP(dport=dstport,sport=sportid,flags=16,seq=cs_sn,ack=sc_sn), verbose = False)
整个过程抓包http://www.qytang.com/upload/images/2016-03-15/6359364284559799026334987.png现任明教教主2016.03.12乾颐堂客服热线:400-618-8070乾颐堂官网:www.qytang.com乾颐堂网络实验室 我们为您想的更多
页:
[1]