Python 如何向使用scapy嗅探的数据包添加http头

Python 如何向使用scapy嗅探的数据包添加http头,python,http,network-programming,packet-sniffers,scapy,Python,Http,Network Programming,Packet Sniffers,Scapy,我正在尝试使用scapy嗅探一个即将过时的http包,在其中添加一些新的http头并提前发送。这里的目的是在保持数据包完整的情况下只插入新的报头。如果需要,最多应重新计算校验和 我们已经解决了几乎所有的问题,但没有找到解决方案 以下是我所做的 def parse(pkt): if pkt.haslayer(TCP) and pkt.getlayer(TCP).dport == 80 and pkt.haslayer(Raw): pkt = pkt / "New Head

我正在尝试使用scapy嗅探一个即将过时的http包,在其中添加一些新的http头并提前发送。这里的目的是在保持数据包完整的情况下只插入新的报头。如果需要,最多应重新计算校验和

我们已经解决了几乎所有的问题,但没有找到解决方案

以下是我所做的

def parse(pkt):

    if pkt.haslayer(TCP) and pkt.getlayer(TCP).dport == 80 and pkt.haslayer(Raw):
        pkt = pkt / "New Header:value\r\n\r\n"

        # OR i tried this
        #pkt = pkt.getlayer(Raw).load / Raw.load(load="New Header:value\r\n\r\n")

        #pkt.getlayer(Raw).load("New Header:value\r\n\r\n")
        pkt.show()
        #del pkt[IP].chksum
        send(pkt)
#end parse function

# start sniffing
a=sniff(filter="tcp and ( port 80 )", prn=parse)
问题是上面的代码插入了一个新的原始有效负载部分,而不是添加一个普通的头。根据HTTP标准,已经有一个双换行符\r\n\r\n来指示标头终止

为了克服这个问题,我尝试按如下操作删除最后一个\r\n

   #pkt = pkt.getlayer(Raw).load[-2:] / Raw.load(load="New Header:value\r\n\r\n")
但这会剥离所有以前存在的标题,只剩下“新标题”

我已经在LinuxMint上试过了

更新:
我正在尝试创建一个新的http负载,它将包含以前的头,我将添加一些。如果我理解正确,您遇到的问题是您想用新的头更新现有HTTP请求。您想要的是就地更新一个字符串,而Python不能直接这样做(字符串是不可变的)

因此,您应该做的是获取HTTP头:

old\u hdr=pkt[Raw]
old\u hdr=pkt[TCP]。有效负载

并像操纵字符串一样操纵它:

new_hdr = 'New Header: value'
hdr = old_hdr.split('\r\n') # This is a crappy hack. Parsing HTTP headers
hdr.insert(new_hdr, 2)      # is a [solved problem][1].
send_hdr = '\r\n'.join(hdr)
pkt[TCP].payload = send_hdr
如果发现校验和未更新,请在发送数据包之前删除它们:

del pkt[TCP].chksum
Scapy会用正确的值为你把它们放回去


编辑:我刚刚注意到我的链接失败了。是如何解析HTTP头。

这是一个非常高层次的事情,可以尝试使用数据包分析工具来完成。如果HTTP头在两个(或多个)数据包之间分割,该怎么办?同意。但我可以暂时忽略它。一个高性能的真实应用程序可能需要用c语言编写。一个带有基本测试用例的POC就可以了。@GregHewgill顺便问一下,您是否有另外一个工具可以在现场嗅探时执行上述操作?我的意思不是要修改pcap。当然,如果您想向HTTP事务添加特定的头,您应该使用HTTP代理应用程序,而不是试图直接处理IP数据包。代理应用程序将创建自己的数据包并转发它。它将包含代理的源ip,而不是原始发件人。然后代理也必须接收回响应,并转发给原始发件人。这会在代理上产生额外的处理开销,我正在努力避免。非常感谢。我会尝试一下,如果我有问题会给你回复。