如何获取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'
如有任何帮助,我们将不胜感激
正如您怀疑的那样,因为您使用了复数形式,pkts
是 PacketList
而不是 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])
所以我正在编写一个 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'
如有任何帮助,我们将不胜感激
正如您怀疑的那样,因为您使用了复数形式,pkts
是 PacketList
而不是 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])