TCP/IP 与 scapy 的连接
TCP/IP connection with scapy
我正在尝试使用 scapy
实现一个类似 netcat 的小实用程序(我可以在其中对 IP 数据包进行低级修改),但我无法启动正确的连接。
我试图创建一个连接到远程主机并发送一些字符串的简单测试程序:
#!/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
将数据发送到远程,并且它确实工作得很好)。
当运行 a tcpdump
在接收器上时,我可以看到以下输出:
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
所以:我做错了什么`
您的内核在收到来自您的 TCP 伙伴的 SYN/ACK 时正在关闭连接。
如果你在 linux 下,你可以使用 IP table 来通知内核你不希望这种行为。如果这样做,请注意安全问题。
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))
我正在尝试使用 scapy
实现一个类似 netcat 的小实用程序(我可以在其中对 IP 数据包进行低级修改),但我无法启动正确的连接。
我试图创建一个连接到远程主机并发送一些字符串的简单测试程序:
#!/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
将数据发送到远程,并且它确实工作得很好)。
当运行 a tcpdump
在接收器上时,我可以看到以下输出:
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
所以:我做错了什么`
您的内核在收到来自您的 TCP 伙伴的 SYN/ACK 时正在关闭连接。 如果你在 linux 下,你可以使用 IP table 来通知内核你不希望这种行为。如果这样做,请注意安全问题。
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))