Как фильтровать файл pcap по определенному протоколу с помощью python?

У меня есть некоторые файлы pcap, и я хочу фильтровать по протоколу, то есть, если я хочу фильтровать по протоколу HTTP, все, кроме HTTP-пакетов, останется в файле pcap.

Существует инструмент под названием openDPI, и он идеален для того, что мне нужно, но нет оболочки для языка python.

Кто-нибудь знает какие-либо модули python, которые могут делать то, что мне нужно?

Спасибо

Изменить 1:

HTTP-фильтрация была всего лишь примером, есть много протоколов, которые я хочу фильтровать.

Изменить 2:

Я попробовал Scapy, но я не понимаю, как правильно фильтровать. Фильтр принимает только выражение Berkeley Packet Filter, то есть я не могу применить msn или HTTP или другой фильтр с верхнего уровня. Кто-нибудь может мне помочь?

Ответ 1

возможно, это может помочь Scapy?

Ответ 2

Я знаю, что это очень старый вопрос, но я просто наткнулся на него, подумал, что предоставил мой ответ. Это проблема, с которой я сталкивался несколько раз на протяжении многих лет, и я продолжаю находить себя обратно в dpkt. Первоначально из очень способного dugsong, dpkt является в первую очередь библиотекой создания/анализа пакетов. Я понимаю, что разбор pcap был запоздалым, но он оказался очень полезным, потому что разбор pcaps, заголовков IP, TCP и TCP является простым. Он анализирует все протоколы более высокого уровня, которые становятся потоком времени! (Я написал свою собственную библиотеку python pcap для анализа dpkt)

Документация по использованию функции разбора pcap немного тонкая. Вот пример из моих файлов:

import socket
import dpkt
import sys
pcapReader = dpkt.pcap.Reader(file(sys.argv[1], "rb"))
for ts, data in pcapReader:
    ether = dpkt.ethernet.Ethernet(data)
    if ether.type != dpkt.ethernet.ETH_TYPE_IP: raise
    ip = ether.data
    src = socket.inet_ntoa(ip.src)
    dst = socket.inet_ntoa(ip.dst)
    print "%s -> %s" % (src, dst)

Надеюсь, это поможет следующему парню пройти через это сообщение!

Ответ 3

Быстрый пример с помощью Scapy, так как я только что написал один:

pkts = rdpcap('packets.pcap')
ports = [80, 25]
filtered = (pkt for pkt in pkts if
    TCP in pkt and
    (pkt[TCP].sport in ports or pkt[TCP].dport in ports))
wrpcap('filtered.pcap', filtered)

Это будет отфильтровывать пакеты, которые не являются ни HTTP, ни SMTP. Если вам нужны все пакеты, кроме HTTP и SMTP, третья строка должна быть:

filtered = (pkt for pkt in pkts if
    not (TCP in pkt and
    (pkt[TCP].sport in ports or pkt[TCP].dport in ports)))
wrpcap('filtered.pcap', filtered)

Ответ 4

Что-то вдоль линий

from pcapy import open_offline
from impacket.ImpactDecoder import EthDecoder
from impacket.ImpactPacket import IP, TCP, UDP, ICMP

decoder = EthDecoder()

def callback(jdr, data):
    packet = decoder.decode(data)
    child = packet.child()
    if isinstance(child, IP):
        child = packet.child()
        if isinstance(child, TCP):
            if child.get_th_dport() == 80:
                print 'HTTP'

pcap = open_offline('net.cap')
pcap.loop(0, callback)

используя

http://oss.coresecurity.com/projects/impacket.html

Ответ 5

Попробуйте pylibpcap.

Ответ 6

чтобы фильтровать/удалять определенный протокол, который вы должны выполнить для анализа пакетов, иначе вы могли бы пропустить некоторый трафик HTTP на нетрадиционном порту, который протекает в вашей сети. конечно, если вам нужна свободная система, вы можете проверить только номер порта источника и назначения, но это не даст вам точных результатов. вам нужно искать определенную функцию протокола, такого как ключевые слова GET, POST, HEAD и т.д. для HTTP и другие для другого протокола, и проверять каждый TCP-пакет.

Ответ 7

Я пробовал то же самое с использованием метода @nmichaels, но он становится громоздким, когда я хочу повторить его по нескольким протоколам. Я попытался найти способы прочитать файл .pcap, а затем отфильтровать его, но не нашел никакой помощи. В принципе, когда читается файл .pcap, в Scapy нет функции, которая позволяет фильтровать эти пакеты, с другой стороны, используя команду like,

a=sniff(filter="tcp and ( port 25 or port 110 )",prn=lambda x: x.sprintf("%IP.src%:%TCP.sport% -> %IP.dst%:%TCP.dport%  %2s,TCP.flags% : %TCP.payload%"))

помогает фильтровать, но только при обнюхивании.

Если кто-нибудь знает какой-либо другой метод, где мы можем использовать синтаксис BPF вместо оператора for?

Ответ 8

sniff поддерживает автономный параметр, в котором вы можете предоставить файл pcap в качестве входного. Таким образом, вы можете использовать преимущества фильтрации команды sniff в файле pcap.

>>> packets = sniff(offline='mypackets.pcap')
>>>
>>> packets
<Sniffed: TCP:17 UDP:0 ICMP:0 Other:0>

Надеюсь, что это поможет!