2

我正在尝试构建一个简单的 Scapy 脚本,该脚本手动管理 3 次握手,向 Web 服务器发出 HTTP GET 请求(通过发送单个数据包)并手动管理响应数据包(我需要手动发送 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 是自动发送的)?

4

3 回答 3

2

使用 sr(),从收到的每个 ans 中读取数据(您需要随时解析 Content-Length 或块长度,具体取决于您是否使用传输分块),然后发送 ACK 作为响应到 ans 列表中的最后一个元素,然后重复直到满足结束条件(不要忘记包括全局超时,我使用 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 页,只是为了搞笑。

于 2013-06-18T21:26:07.343 回答
0

TCP_PUSH=TCP(sport=1500, dport=80, flags="PA", seq=102, ack=my_ack) 发送(ip/TCP_PUSH)

seq 应该是 101 而不是 102

于 2014-05-19T06:59:49.120 回答
-1

你试过了吗:

responce = sr1(request)
print responce.show2

还可以尝试使用不同的嗅探器,例如 wireshark 或 tcpdump,因为 netcat 有一些错误。

于 2013-06-16T20:37:40.807 回答