如何获取http响应的长度python scapy

How to get the length of http response python scapy

所以我正在编写一个 python scapy 脚本,它将首先完成一次 3 次握手,发送一个 http get,然后关闭连接。

这是目前的代码:

!/usr/bin/env python

from scapy.all import *

getStr = 'GET / HTTP/1.0\r\nHost: www.google.com\r\n\r\n'

#Send SYN
syn = IP(src="31.31.31.10",dst='31.31.31.17') /         TCP(dport=80,sport=RandShort(),flags='S')
syn_ack = sr1(syn)`

#Send GET w/ ACK of server's SA
get1 = (IP(src="31.31.31.10",dst="31.31.31.17")/TCP(dport=80, sport=syn_ack[TCP].dport,seq=syn_ack[TCP].ack, ack=syn_ack[TCP].seq + 1, flags='PA')/getStr)
send (get1)

pkts = sniff(count=1,filter="host 31.31.31.17 and port 80",prn=lambda x:x.summary())
print pkts.sprintf("%TCP.len%") #Will this work? I am getting an issue here

AttributeError: 'list' object has no attribute 'sprintf'

基本上我只是想从PA中提取数据的len,也就是http响应,所以我可以正确生成以下序列号来ACK http响应。

我也试过:ans,uns=sr(get1) 但我也找不到从中获取长度的好方法。

我也试过:print len(pkts.getlayer(TCP)) AttributeError: 'list' object has no attribute 'getlayer'

如有任何帮助,我们将不胜感激

正如您怀疑的那样,因为您使用了复数形式,pktsPacketList 而不是 Packet.

您可以使用:

for p in pkts:
    if TCP in p:
        print len(p[TCP].payload)

如果你想跳过没有数据的数据包,你可以添加and not isinstance(p[TCP].payload, NoPayload)

您还可以修改 BPF 过滤器,使其显示为:"host 31.31.31.17 and tcp port 80"(添加 tcp)。

Scapy 在其基础 class 中重载了许多内部属性,其中之一是 __len__。基于@Pierre 的回答,我认为

for p in pkts:
    print len(p)

如果您只需要 TCP 数据包的长度并且只需要向前,请尝试:

for p in pkts:
    print len(p[TCP])

查看位于 scapy/packet.py 的 Scapy 源代码,了解 class Packet.

还重载了什么

不要单独使用 packet[TCP].payload,它包括填充,如果数据包有填充,它会给你一个不正确的长度。

相反,您可以使用:

tcp_payload_len = len(pkt[TCP].payload)
if pkt.haslayer(Padding):
  tcp_payload_len -= len(pkt[Padding])

参见:https://github.com/secdev/scapy/issues/707