设为首页收藏本站language 语言切换
查看: 2256|回复: 0
收起左侧

现任明教教主Scapy模拟整个TCP连接过程

[复制链接]
发表于 2016-3-15 12:56:14 | 显示全部楼层 |阅读模式
现任明教教主Scapy模拟整个TCP连接过程
安全CCNA学习交流2群 451768824
拓扑
Linux上的特殊处理
客户端linux需要做如下配置来防止发送不必要的reset:
firewall-cmd --direct --add-rule ipv4 filter OUTPUT 1 -p tcp --tcp-flags RST RST -s 202.100.1.139 -j DROP

socket回显服务器
#!/usr/bin/python3.4
# -*- coding=utf-8 -*-
myHost = '202.100.1.138'
myPort = 6668

if len(sys.argv) == 3:
    myHost, myPort = sys.argv[1:]

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 logging
import re
logging.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)

#响应的数据包产生数组([0]为响应,[1]为未响应)
result_synack_list = result_raw_synack[0].res

#第一层[0]位第一组数据包
#第二层[0]表示发送的包,[1]表示收到的包
#第三层[0]为IP信息,[1]为TCP信息,[2]为TCP数据
tcpfields_synack = result_synack_list[0][1][1].fields
#由于SYN算一个字节,所以客户到服务器序列号(sc_sn)需要增加1
sc_sn = tcpfields_synack['seq'] + 1
cs_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)

#响应的数据包产生数组([0]为响应,[1]为未响应)
result_msg_list = result_raw_msg[0].res
#提取服务器响应包的IP信息,生成字典(注意是提取的第二组数据,第一组仅仅是ACK)
msgback_ip_fields = result_msg_list[1][1][0].fields
#提取服务器响应包的TCP信息,生成字典(注意是提取的第二组数据,第一组仅仅是ACK)
msgback_tcp_fields = result_msg_list[1][1][1].fields
#提取服务器响应包的TCP数据信息,生成字典(注意是提取的第二组数据,第一组仅仅是ACK)
msgback_data_fields = result_msg_list[1][1][2].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_len
cs_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)需要增加1
sc_sn = result_raw_fin[1].fields['seq'] + 1
cs_sn = result_raw_fin[1].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)

整个过程抓包
现任明教教主
2016.03.12
乾颐堂客服热线:400-618-8070
乾颐堂官网:www.qytang.com
乾颐堂网络实验室 我们为您想的更多

您需要登录后才可以回帖 登录 | 论坛注册

本版积分规则

QQ|Archiver|手机版|小黑屋|sitemap|鸿鹄论坛 ( 京ICP备14027439号 )  

GMT+8, 2025-3-1 20:31 , Processed in 0.072597 second(s), 25 queries , Redis On.  

  Powered by Discuz!

  © 2001-2025 HH010.COM

快速回复 返回顶部 返回列表