Python 如何创建HTTP GET请求Scapy?
我需要创建HTTP GET请求并保存数据响应。 我试着用这个:Python 如何创建HTTP GET请求Scapy?,python,http,get,scapy,Python,Http,Get,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,
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
时,我看不到任何数据响应。
此外,当我签入“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(请参阅)。这可以通过iptable规则解决:
iptables-A输出-p tcp-tcp标志RST-s-j DROP
因为您要结束与该RST段的连接,所以当您发送HTTP请求时,端点也会用RST应答,因为连接未建立,所以您在没有数据的RST段上使用
show()
,这就是为什么您看不到任何内容。您正在发送SYN并正确接收SYN_ACK。此时,您应该根据接收到的SYN_ACK生成并发送ACK,然后最终传输HTTP GET请求。您似乎对TCP 3路握手机制有些困惑。简而言之,您不应该“获取”ACK,您应该自己生成并发送此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握手之后)是一系列空(0x00)字节。因此,在我的例子中,使用multi不知何故完成了这项工作。reply.show()已经自动打印了,不需要打印statement@YotamSalmon但是我只需要将数据保存在html文件中。B我知道您需要,但是reply变量是一个对象,而不是字符串。您必须从对象获取响应负载。我不记得现在是怎么做的,但让我检查一下,如果我找到了解决方案,我会尽快发布答案。这是网络中的Magshimim项目的问题吗?@Yotammarmon是的,我尝试了很长时间,但没有成功。很抱歉。我尽了很大的努力,却找不到解决办法。顺便说一句,我建议你看看这个网站:ell.stackexchange.com所以你可以修改我的代码,我试过了,但它对我也不起作用。@YairB。首先,您是否实施了前面提到的解决RST问题的方法?首先,确保操作系统不会自动发送RST。然后尝试生成一个ACK以响应SYN_ACK。如果这不起作用,请在此时上传一个新的wireshark捕获,然后我们可以从那里开始。@wookie919他已经在其
请求
段中确认SYN-ACK,但是,您是对的,最好在实际请求之前发送一个没有数据的ACK,因为这是一种更快的确认段的方法(并在本例中建立连接)。现在我更新问题..看我尝试做什么以及它打印了我什么。