scapy在已建立的连接上发送tcp数据包

时间:2018-01-13 19:25:07

标签: c tcp network-programming scapy

我有以下内容:

服务器端:TCP python服务器(不是scapy) 客户端:Scapy建立连接并发送TCP数据包

我试图在3路握手后通过scapy在已建立的连接上发送TCP数据包

我能够构建3路握手和服务器端(另一方面-python TCP服务器 - 不是scapy-创建TCP套接字,bind,listen,accpet,recv())显示新连接到来并且accept()返回创建的FD

我试图在3次握手成功后从scapy发送数据包但是在非scapy端的recv()无法获取数据包

scapy side:

#!/usr/bin/env python
from scapy.all import *
import time

# VARIABLES
src = sys.argv[1]
dst = sys.argv[2]
sport = random.randint(1024,65535)
dport = int(sys.argv[3])

# SYN
ip=IP(src=src,dst=dst)
SYN=TCP(sport=sport,dport=dport,flags='S',seq=1000)
SYNACK=sr1(ip/SYN)

# ACK
ACK=TCP(sport=sport, dport=dport, flags='A', seq=SYNACK.ack, ack=SYNACK.seq + 1)
send(ip/ACK)

time.sleep(15)

ip = IP(src=src, dst=dst)
tcp = ip / TCP(sport=sport, dport=dport, flags="PA", seq=123, ack=1) / "scapy packet 123"
tcp.show2()

send(tcp)

不是scapy方:

#!/usr/bin/python

import socket
from scapy.all import *

ip = sys.argv[1]
port = sys.argv[2]

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((ip, int(port)))
s.listen(1)

while True :
    conn, addr = s.accept()
    print 'Connection address:', addr
    data = conn.recv(1024) # Stuck here .....

tcpdump输出显示:

tcpdump: listening on ens1f1, link-type EN10MB (Ethernet), capture size 65535 bytes
18:09:35.820865 IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto TCP (6), length 40)
    11.4.3.31.63184 > 11.4.3.30.strexec-d: Flags [S], cksum 0x6543 (correct), seq 1000, win 8192,                                                                        length 0
18:09:35.821017 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 44)
    11.4.3.30.strexec-d > 11.4.3.31.63184: Flags [S.], cksum 0x748d (correct), seq 3017593595, ac                                                                       k 1001, win 29200, options [mss 1460], length 0
18:09:35.930593 IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto TCP (6), length 40)
    11.4.3.31.63184 > 11.4.3.30.strexec-d: Flags [.], cksum 0xde5a (correct), seq 1, ack 1, win 8                                                                       192, length 0
18:09:51.057904 IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto TCP (6), length 56)
    11.4.3.31.63184 > 11.4.3.30.strexec-d: Flags [P.], cksum 0x8eef (correct), seq 4294966419:429                                                                       4966435, ack 1277373702, win 8192, length 16
18:09:51.057996 IP (tos 0x0, ttl 64, id 1194, offset 0, flags [DF], proto TCP (6), length 40)
    11.4.3.30.strexec-d > 11.4.3.31.63184: Flags [.], cksum 0x8c4a (correct), seq 1, ack 1, win 2                                                                       9200, length 0

我的问题为什么接收方没有收到发送的数据包?

注意:我的目标是在已建立的连接上使用错误的校验和发送TCP数据包,并且不通过scapy tcp服务器接收它 提前致谢!!

1 个答案:

答案 0 :(得分:1)

您的序列号必须准确跟踪您发送的有效负载字节。设置了SYN或FIN标志的数据包是一个例外,它被视为具有长度为1的有效负载。换句话说,您可以使用您喜欢的任何初始序列号,但它必须逐字节增加你发送的有效载荷(SYN或SYN + ACK [或FIN]为+1)。

因此,如果您在SYN数据包中以序列号1000开头,那么带有有效负载的下一个数据包(称为此pktA)的序列号应为1001.那么您的下一个数据包(pktB)应该具有序列号1001 + pktA.payload_size,等等。

同样,您不能简单地将TCP标头中的确认编号字段设置为1(正如您对“scapy数据包123”所做的那样)。每当您在标头中提供ACK标志时,您需要通过将标头中的确认编号设置为来自另一方的最后一个有效负载的最后接收的序列号来确认另一方的有效负载。在这种情况下,您已经发送了一个带有该确认号的裸ACK数据包,因此您不需要包含ACK标志,但通常包含它并且如果您要包含该标志,则确认序列号应该正确设置。

请参阅此链接以获得良好的概述: http://packetlife.net/blog/2010/jun/7/understanding-tcp-sequence-acknowledgment-numbers/