我正在尝试构建一个简单的Scapy脚本,该脚本手动管理3次握手,发出HTTP GET请求(通过发送单个数据包)到Web服务器并手动管理响应数据包(我需要手动发送ACK)响应的数据包)。
这是脚本的开头:
#!/usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
# Import scapy
from scapy.all import *
# beginning of 3-way-handshake
ip=IP(dst="www.website.org")
TCP_SYN=TCP(sport=1500, dport=80, flags="S", seq=100, options=[('NOP', None), ('MSS', 1448)])
TCP_SYNACK=sr1(ip/TCP_SYN)
my_ack = TCP_SYNACK.seq + 1
TCP_ACK=TCP(sport=1500, dport=80, flags="A", seq=101, ack=my_ack)
send(ip/TCP_ACK)
TCP_PUSH=TCP(sport=1500, dport=80, flags="PA", seq=102, ack=my_ack)
send(ip/TCP_PUSH)
# end of 3-way-handshake
# beginning of GET request
getString = 'GET / HTTP/1.1\r\n\r\n'
request = ip / TCP(dport=80, sport=1500, seq=103, ack=my_ack + 1, flags='A') / getString
# help needed from here...
上面的脚本完成了3次握手并准备了HTTP GET请求 然后,我将通过以下方式发送请求:
send(request)
现在,在发送之后,我应该获得/手动阅读回复 我的目的确实是通过手动发送响应的ACK数据包来读取响应(这是脚本的主要焦点)。
我该怎么做?
send(_)
函数是否合适,或者最好使用response = sr1(request)
之类的东西(但在这种情况下,我认为会自动发送ACK)?
答案 0 :(得分:2)
使用sr(),从收到的每个ans中读取数据(根据您是否使用转移,您需要随时解析内容长度或块长度chunking)然后发送ACK以响应ans列表中的 last 元素,然后重复直到满足结束标准(不要忘记包括全局超时,我使用8次传递而不获取任何回复,即2秒)。
确保sr是sr(req,multi = True,timeout = 0.25)或其附近。有时候,当你循环时会出现没有数据包出现的时期,这就是为什么HTTP拥有所有这些长度规格的原因。如果超时太高,那么您可能会发现服务器不耐烦等待ACK并开始重新发送。
请注意,当您使用传输分块时,您也可以尝试作弊并只读取0 \ r \ n \ r \ n但是如果它真的在数据流中...是的。不要依赖于TCP PSH,不过这很有吸引力,可能会用一些简单的用例来管理一些Wireshark会话。
显然,最终结果并非完全可行的用户代理,但它足够接近大多数用途。不要忘记发送Keep-Alive标头,RST异常,如果一切正常,请礼貌地关闭TCP会话。
请记住,RFC 2616并不长176页,只是为了咯咯笑。
答案 1 :(得分:0)
TCP_PUSH = TCP(运动= 1500,dport = 80,标志=" PA",seq = 102,ack = my_ack) 发送(IP / TCP_PUSH)
seq应该是101而不是102
答案 2 :(得分:-1)
你有没有尝试过:
responce = sr1(request)
print responce.show2
还尝试使用不同的嗅探器,如wireshark或tcpdump,因为netcat有一些错误。