加载中…
个人资料
现任明教教主-乾颐堂
现任明教教主-乾颐堂
  • 博客等级:
  • 博客积分:0
  • 博客访问:6,224
  • 关注人气:2,075
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

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

(2016-03-14 08:43:29)
标签:

杂谈

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

http://s13/mw690/001w5tqHzy6ZC1TtmFebc&690

=====================拓扑=======================

http://s4/mw690/001w5tqHzy706fP0v3J33&690

=================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 -*-

 

import sys, time

from select import select

from socket import *

def now(): return time.ctime(time.time())

 

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()

print('Connect:', address, id(newsock))

readsocks.append(newsock)

else:

data = sockobj.recv(1024)

print('\tgot', data, 'on', id(sockobj))

if not data:

sockobj.close()

readsocks.remove(sockobj)

else:

reply = 'Echo=>%s at %s' % (data, now())

sockobj.send(reply.encode())

================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)

===================整个过程抓包=======================

http://s4/middle/001w5tqHzy706fIYvILd3&690

---------现任明教教主

                                                     2016.03.12

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有