首页 > 解决方案 > 与 scapy 的 TCP/IP 连接

问题描述

我正在尝试使用scapy(我可以对 IP 数据包进行低级修改)来实现一个类似 netcat 的小实用程序,但我无法启动正确的连接。

我试图创建一个连接到远程主机并发送一些字符串的简单测试程序:

#!/usr/bin/env python3
import random
import sys
from scapy.all import *

dst = sys.argv[1]
sport = random.randint(1024, 65535)
dport = int(sys.argv[2])
data = 'hello\r\n'

ip = IP(dst=dst, frag=0)
SYN = TCP(sport=sport, dport=dport, flags='S', seq=1000)
SYNACK = sr1(ip/SYN)
ACK = TCP(sport=sport, dport=dport, flags='A', seq=SYNACK.ack, ack=SYNACK.seq + 1)
INITACK = sr1(ip/ACK)
PUSHACK = TCP(sport=sport, dport=dport, flags='PA', seq=INITACK.ack, ack=INITACK.seq + 1)
RESPONSE = sr1(ip/PUSHACK/Raw(load=data))

在接收方我有一个nc -l -p 6666跑步。

当我调用脚本时,我在发件人上得到以下输出:

$ sudo ./test.py REMOTE 6666
Begin emission:
Finished sending 1 packets.
.......*
Received 8 packets, got 1 answers, remaining 0 packets
Begin emission:
Finished sending 1 packets.
*
Received 1 packets, got 1 answers, remaining 0 packets
Begin emission:
Finished sending 1 packets.
*
Received 1 packets, got 1 answers, remaining 0 packets

但是接收的 netcat 从不输出任何数据(我确实检查了是否可以使用 将数据发送到远程echo foo | nc REMOTE 6666,它确实工作得很好)。

在接收器上运行 atcpdump时,我可以看到以下输出:

23:31:58.205257 IP SENDER.4902 > RECEIVER.6666: Flags [S], seq 1000, win 8192, options [mss 536], length 0
23:31:58.205279 IP RECEIVER.6666 > SENDER.4902: Flags [S.], seq 1928493439, ack 1001, win 29200, options [mss 1460], length 0
23:31:58.344181 IP SENDER.4902 > RECEIVER.6666: Flags [R], seq 1001, win 0, length 0
23:31:58.396581 IP SENDER.4902 > RECEIVER.6666: Flags [.], ack 1, win 8192, length 0
23:31:58.396593 IP RECEIVER.6666 > SENDER.4902: Flags [R], seq 1928493440, win 0, length 0
23:31:58.459286 IP SENDER.4902 > RECEIVER.6666: Flags [P.], seq 4294966296:4294966303, ack 2, win 8192, length 7
23:31:58.459296 IP RECEIVER.6666 > SENDER.4902: Flags [R], seq 1928493441, win 0, length 0

所以:我做错了什么`

标签: pythonlinuxnetworkingtcpscapy

解决方案


当你的内核从你的 TCP 伙伴收到一个 SYN/ACK 时,它正在关闭连接。如果你在 linux 下,你可以使用 IP 表来通知内核你不希望这种行为。如果您这样做,请注意安全问题。

iptable 命令如下:

iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP
iptables -L

您的代码也需要稍作改动。


#!/usr/bin/env python3
import random
import sys
from scapy.all import *

dst = sys.argv[1]
sport = random.randint(1024, 65535)
dport = int(sys.argv[2])
data = 'hello\r\n'

ip = IP(dst=dst, frag=0)
SYN = TCP(sport=sport, dport=dport, flags='S', seq=1000)
SYNACK = sr1(ip/SYN)
ACK = TCP(sport=sport, dport=dport, flags='A', seq=SYNACK.ack, ack=SYNACK.seq + 1)
send(ip/ACK)
# at this point, you and your partner are on established state.


# you can then start to send things
cur_seq=SYNACK.ack
cur_ack=SYNACK.seq + 1


PUSHACK = TCP(sport=sport, dport=dport, flags='PA', seq=cur_seq, ack=cur_ack)
cur_seq += len(data)
RESPONSE = sr1(ip/PUSHACK/Raw(load=data))



推荐阅读