我想使用 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/