2016-04-08 18 views
2

netfilterqueue(0.6 - 最新)とscapyを使って自分の値で "host"ヘッダーを変更したいと思います。これは私のiptablesのルールです:netfilterqueueとscapyを使ったHTTPヘッダーの変更

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 

しかし、それは動作しませんが...そして私は私が前にヘッダを印刷した理由.. 見当がつかない私の変更後、唯一の変更は "ホスト"ヘッダーです。それがうまくいかない理由は?誰にもアイデアはありますか? :)

私はテストには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であり、上記のコードでパケットに注入するIPではありません。

ありがとうございます。

答えて

1

ここにいくつかの問題があります。

[更新:PyPIの最新バージョン0.3は、コメントで指摘されているように古くなっています。バージョン0.6 を実装します.set_payload()を入力してください 何かをする前に、使用するライブラリはパケットを変更するために .set_payload()を実装していないようです( here参照)。代わりに nfqueue-bindingsを使用します。

まず(あなたの最初の試みに関連する)、あなたはデータのを変更する必要がある場合は、TCPペイロードを変更することは、難しいです(あなたがHTTPヘッダーを追加しようとするので、ここではそうである)、以来、同じ接続でさらにパケットのシーケンス番号と確認応答番号を変更する必要があります。

  • 変更またはしたいヘッダを追加し、あなたがプロキシに改ざんしたい接続をリダイレクトします透明のHTTPプロキシを使用します。

    はこれを実装するには、次の2つのオプションがあります。
  • 変更がデータのサイズを保持することを確認してください(ヘッダーを別のヘッダーに置き換え、長さに注意してください)。

scapy_pkt.dst = 'google.pl'はIP層の宛先を設定します(データは変更しません)。同様にIP宛先NATを実行します。

  • データが含まれていない受信パケット(コードのみがパケットを変更します)は、 TCPペイロードを使用して、SYN + ACKをそのままにします。たとえば、パケットは変更されません)。
  • 受信したパケット(INPUT iptablesルールも必要です)。
+0

返信いただきありがとうございます。 Soo ..私が使ったこのライブラリはset_payload()を実装しています - 私は0.6バージョンを使用しています、0.3バージョンのリンクを提供しています。 ハム..だから私は思ったほど単純ではありません。あなたは私の入ってくるデータの修正を見てみることができますか? - http://pastebin.com/u0F6YeCB? – user3025978

+0

私はあなたのコメントの最初の部分の答えを更新しました。 pastebinのあなたのコードは 'Content-Length' HTTPヘッダー(HTTPヘッダーではなくHTTPデータ長を変更する場合に必要です)の値を修正しようとしますが、依然としてTCPシーケンス/確認応答番号の問題がありますこのパケットの後に間違っています。私はより簡単なオプションが答えに記載されていると思う(TCPデータの長さを保持するか、透過的なHTTPプロキシを使用する)。 – Pierre

+0

さて、私はTCPのことを十分に理解していないと思います...シーケンス番号はTCPトークのパケット数です。私が1つのパケットのシーケンスを変更するとき、私はこの "話"の中で他のパケットを変更すべきですか? ACKとは何ですか? – user3025978

関連する問題