python - 用netfilterqueue和scapy修改HTTP头

标签 python http tcp scapy

我想使用 netfilterqueue(0.6 - 最新版)和 scapy 将“主机” header 更改为我的值。这是我的 iptables 规则:

iptables -A OUTPUT -p tcp --dport 80 -j NFQUEUE --queue-num 0

我有我的代码:

from netfilterqueue import *
from scapy.all import *

def change(pkt):
    scapy_pkt = IP(pkt.get_payload())
    if scapy_pkt.haslayer(TCP) and scapy_pkt.getlayer(TCP).dport == 80 and scapy_pkt.haslayer(Raw):
        http_content = scapy_pkt.getlayer(Raw).load
        list_of_headers = http_content.split("\r\n")
        new_headers = []
        for i in list_of_headers:
            if "Host" in i:
                new_headers.append("Host: google.pl")
            else:
                new_headers.append(i)

        pkt.set_payload("\r\n".join(new_headers))

    pkt.accept()

nfqueue = NetfilterQueue()
nfqueue.bind(0, change)
try:
    nfqueue.run()
except KeyboardInterrupt:
    print

但是它不起作用..我不知道为什么.. 我在更改前后打印标题,唯一的更改是“主机”标题。 Soo.. 为什么它不起作用?有没有人有任何想法? :)

我使用 CURL 进行测试,使用 wireshark 进行调试。请求未发送。我在 wireshark 中找不到它。

编辑: 我试图解决这个问题,并将我的代码更改为:

from netfilterqueue import *
from scapy.all import *

def change(pkt):
    scapy_pkt = IP(pkt.get_payload())
    print dir(pkt);
    if scapy_pkt.haslayer(TCP) and scapy_pkt.getlayer(TCP).dport == 80 and scapy_pkt.haslayer(Raw):
        #http_content = scapy_pkt.getlayer(Raw).load
        #list_of_headers = http_content.split("\r\n")
        #new_headers = []
        #for i in list_of_headers:
        #   if "Host" in i:
        #       new_headers.append("Host: google.pl")
        #   else:
        #       new_headers.append(i)

        scapy_pkt.dst = 'google.pl'

        del scapy_pkt[IP].chksum
        del scapy_pkt[TCP].chksum
        pkt.set_payload(str(scapy_pkt))
    pkt.accept()

nfqueue = NetfilterQueue()
nfqueue.bind(0, change)
try:
    nfqueue.run()
except KeyboardInterrupt:
    print

但还是不行。在 wireshark 中,我通过 HTTP 进行过滤。但是,当我通过 TCP 和 destport == 80 进行过滤时,我可以看到包,但目标是从传递给 CURL 的参数到 IP,而不是我在上面的代码中注入(inject)到数据包的 IP。

感谢提前:)

最佳答案

这里有几个问题。

[更新:正如评论中指出的那样,PyPI 的最新版本 0.3 已过时。版本 0.6 确实实现了.set_payload()] 在任何事情之前,您要使用的库似乎没有实现.set_payload() 改变数据包(见 here )。您可能想使用 nfqueue-bindings相反。

首先(与您的第一次尝试有关),如果您必须更改数据的长度(此处就是这种情况,因为您尝试添加 HTTP header ),则更改 TCP 有效负载很困难),因为您必须更改同一连接中其他数据包的序列号和确认号。

要实现这一点,您有两个选择:

  • 使用透明的 HTTP 代理,它将修改或添加您想要的 header ,并将您想要篡改的连接重定向到代理。
  • 确保您所做的更改将保留数据的大小(例如,用另一个标题替换一个标题,并注意长度)。

第二(与您的第二次尝试有关),scapy_pkt.dst = 'google.pl' 设置 IP 层的目标(并且不更改数据),类似地执行 IP 目标 NAT。这是非常不同的,应该更容易做到(不要弄乱这里的序列号/确认号)但是你必须做同样的修改:

  • 接收到的不包含数据的数据包(您的代码仅更改具有 TCP 负载的数据包,因此保留 SYN+ACK,例如,数据包未修改)。
  • 您收到的数据包(您还需要一个 INPUT iptables 规则)。

关于python - 用netfilterqueue和scapy修改HTTP头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36508055/

相关文章:

python - Sqlalchemy 为 parent 过滤父子表

python - 未能在 psychopy 中附加变量

javascript - Angular 8 jsonp 回调未调用

javascript - Angular 工厂方法不是函数(dataFactory.addContact 不是函数)

ios - Apple 设备上发生错误定向请求

gps - 将 GPS 跟踪器数据检索到 Web 服务

Python - 简单的 TCP/IP S/C : Not all strings converted error for a print statement

java - 跨平台和跨语言的客户端/服务器应用程序连接

python - MemoryError : ipython convnet module. 正常吗?

python - 是否可以使用 matplotlib 绘制时间线?