如何创建 HTTP GET 请求 Scapy?
How to create HTTP GET request Scapy?
我需要创建 HTTP GET 请求并保存数据响应。
我试着用这个:
syn = IP(dst=URL) / TCP(dport=80, flags='S')
syn_ack = sr1(syn)
getStr = 'GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n'
request = IP(dst='www.google.com') / TCP(dport=80, sport=syn_ack[TCP].dport,
seq=syn_ack[TCP].ack, ack=syn_ack[TCP].seq + 1, flags='A') / getStr
reply = sr1(request)
print reply.show()
但是当我打印 reply
时,我没有看到任何数据响应。
另外,我check in的时候'Wireshark'得到了SYN,SYN/ACK但是没有得到ACK。
图片:
编辑:
我现在尝试这样做:
# Import scapy
from scapy.all import *
# Print info header
print "[*] ACK-GET example -- Thijs 'Thice' Bosschert, 06-06-2011"
# Prepare GET statement
get='GET / HTTP/1.0\n\n'
# Set up target IP
ip=IP(dst="www.google.com")
# Generate random source port number
port=RandNum(1024,65535)
# Create SYN packet
SYN=ip/TCP(sport=port, dport=80, flags="S", seq=42)
# Send SYN and receive SYN,ACK
print "\n[*] Sending SYN packet"
SYNACK=sr1(SYN)
# Create ACK with GET request
ACK=ip/TCP(sport=SYNACK.dport, dport=80, flags="A", seq=SYNACK.ack, ack=SYNACK.seq + 1) / get
# SEND our ACK-GET request
print "\n[*] Sending ACK-GET packet"
reply,error=sr(ACK)
# print reply from server
print "\n[*] Reply from server:"
print reply.show()
print '\n[*] Done!'
但它打印我作为服务器的回复;
0000 IP / TCP 192.168.44.130:23181 > 216.58.208.164:http A / Raw ==>
IP / TCP 216.58.208.164:http > 192.168.44.130:23181 A / Padding None
我需要基于行的文本数据:text/html.
您正在发送一个 RST 段以响应 SYN-ACK,因为您的内核不知道您通过 Scapy 发送的 SYN(参见 here)。这可以通过 iptable 规则解决:
iptables -A OUTPUT -p tcp --tcp-flags RST RST -s <your ip> -j DROP
因为您要结束与该 RST 段的连接,当您发送 HTTP 请求时,端点也会使用 RST 进行应答,因为连接未建立,因此您在 RST 段上使用 show()
没有数据,所以你看不到任何东西。
您正在发送 SYN 并正确接收 SYN_ACK。此时,您应该根据收到的 SYN_ACK 生成并发送一个 ACK,然后最后发送 HTTP GET 请求。看来您对 TCP 3 次握手机制有些困惑。简而言之,您不应该 'get' 一个 ACK,您应该自己生成并发送它。
按照上面的建议在 iptables 中设置规则后,您可以执行以下操作:
from scapy.all import *
seq = 12345
sport = 1040
dport = 80
ip_packet = IP(dst='192.168.56.107')
syn_packet = TCP(sport=sport, dport=dport, flags='S', seq=seq)
packet = ip_packet/syn_packet
synack_response = sr1(packet)
next_seq = seq + 1
my_ack = synack_response.seq + 1
ack_packet = TCP(sport=sport, dport=dport, flags='A', seq=next_seq, ack=my_ack)
send(ip_packet/ack_packet)
payload_packet = TCP(sport=sport, dport=dport, flags='A', seq=next_seq, ack=my_ack)
payload = "GET / HTTP/1.0\r\nHOST: 192.168.56.107\r\n\r\n"
reply, error = sr(ip_packet/payload_packet/payload, multi=1, timeout=1)
for r in reply:
r[0].show2()
r[1].show2()
希望这对您有所帮助。基本上,您返回的第一个响应并不真正包含 HTTP 响应数据。我针对 INETSIM 模拟 HTTP 服务器测试了脚本,在那种情况下(至少)服务器响应的第一个数据包(在 3 次 TCP 握手之后)是一系列 NULL (0x00) 字节。因此,在我的案例中,使用 multi 以某种方式完成了这些事情。
我需要创建 HTTP GET 请求并保存数据响应。 我试着用这个:
syn = IP(dst=URL) / TCP(dport=80, flags='S')
syn_ack = sr1(syn)
getStr = 'GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n'
request = IP(dst='www.google.com') / TCP(dport=80, sport=syn_ack[TCP].dport,
seq=syn_ack[TCP].ack, ack=syn_ack[TCP].seq + 1, flags='A') / getStr
reply = sr1(request)
print reply.show()
但是当我打印 reply
时,我没有看到任何数据响应。
另外,我check in的时候'Wireshark'得到了SYN,SYN/ACK但是没有得到ACK。
图片:
编辑:
我现在尝试这样做:
# Import scapy
from scapy.all import *
# Print info header
print "[*] ACK-GET example -- Thijs 'Thice' Bosschert, 06-06-2011"
# Prepare GET statement
get='GET / HTTP/1.0\n\n'
# Set up target IP
ip=IP(dst="www.google.com")
# Generate random source port number
port=RandNum(1024,65535)
# Create SYN packet
SYN=ip/TCP(sport=port, dport=80, flags="S", seq=42)
# Send SYN and receive SYN,ACK
print "\n[*] Sending SYN packet"
SYNACK=sr1(SYN)
# Create ACK with GET request
ACK=ip/TCP(sport=SYNACK.dport, dport=80, flags="A", seq=SYNACK.ack, ack=SYNACK.seq + 1) / get
# SEND our ACK-GET request
print "\n[*] Sending ACK-GET packet"
reply,error=sr(ACK)
# print reply from server
print "\n[*] Reply from server:"
print reply.show()
print '\n[*] Done!'
但它打印我作为服务器的回复;
0000 IP / TCP 192.168.44.130:23181 > 216.58.208.164:http A / Raw ==> IP / TCP 216.58.208.164:http > 192.168.44.130:23181 A / Padding None
我需要基于行的文本数据:text/html.
您正在发送一个 RST 段以响应 SYN-ACK,因为您的内核不知道您通过 Scapy 发送的 SYN(参见 here)。这可以通过 iptable 规则解决:
iptables -A OUTPUT -p tcp --tcp-flags RST RST -s <your ip> -j DROP
因为您要结束与该 RST 段的连接,当您发送 HTTP 请求时,端点也会使用 RST 进行应答,因为连接未建立,因此您在 RST 段上使用 show()
没有数据,所以你看不到任何东西。
您正在发送 SYN 并正确接收 SYN_ACK。此时,您应该根据收到的 SYN_ACK 生成并发送一个 ACK,然后最后发送 HTTP GET 请求。看来您对 TCP 3 次握手机制有些困惑。简而言之,您不应该 'get' 一个 ACK,您应该自己生成并发送它。
按照上面的建议在 iptables 中设置规则后,您可以执行以下操作:
from scapy.all import *
seq = 12345
sport = 1040
dport = 80
ip_packet = IP(dst='192.168.56.107')
syn_packet = TCP(sport=sport, dport=dport, flags='S', seq=seq)
packet = ip_packet/syn_packet
synack_response = sr1(packet)
next_seq = seq + 1
my_ack = synack_response.seq + 1
ack_packet = TCP(sport=sport, dport=dport, flags='A', seq=next_seq, ack=my_ack)
send(ip_packet/ack_packet)
payload_packet = TCP(sport=sport, dport=dport, flags='A', seq=next_seq, ack=my_ack)
payload = "GET / HTTP/1.0\r\nHOST: 192.168.56.107\r\n\r\n"
reply, error = sr(ip_packet/payload_packet/payload, multi=1, timeout=1)
for r in reply:
r[0].show2()
r[1].show2()
希望这对您有所帮助。基本上,您返回的第一个响应并不真正包含 HTTP 响应数据。我针对 INETSIM 模拟 HTTP 服务器测试了脚本,在那种情况下(至少)服务器响应的第一个数据包(在 3 次 TCP 握手之后)是一系列 NULL (0x00) 字节。因此,在我的案例中,使用 multi 以某种方式完成了这些事情。