Отправка пакетов из pcap с измененным src/dst в scapy - программирование
Подтвердить что ты не робот

Отправка пакетов из pcap с измененным src/dst в scapy

Я пытаюсь отправить ранее записанный трафик (записанный в формате pcap) с помощью scapy. В настоящее время я застрял в чередующемся исходном слое эфира. Трафик был захвачен на другом хосте, и мне в основном нужно изменить как IP, так и Ether-уровень src и dst. Мне удалось заменить уровень IP и пересчитать контрольные суммы, но уровень Ether создает проблемы.

У любого есть возможность перепродать пакеты из файла захвата с внесенными изменениями на IP и Ether-уровень (src и dst)? Кроме того, захват - это довольно большая пара Gb, как насчет scapy производительности с таким количеством трафика?

4b9b3361

Ответ 1

проверьте этот пример

from scapy.all import *
from scapy.utils import rdpcap

pkts=rdpcap("FileName.pcap")  # could be used like this rdpcap("filename",500) fetches first 500 pkts
for pkt in pkts:
     pkt[Ether].src= new_src_mac  # i.e new_src_mac="00:11:22:33:44:55"
     pkt[Ether].dst= new_dst_mac
     pkt[IP].src= new_src_ip # i.e new_src_ip="255.255.255.255"
     pkt[IP].dst= new_dst_ip
     sendp(pkt) #sending packet at layer 2

комментарии:

  • Использовать методы rdpcap, wrpcap scapy для чтения и записи из файла формата pcap
  • вы можете использовать sniff(offline="filename") для чтения пакетов, и вы можете использовать параметр prn, подобный этому sniff(offline="filename",prn=My_Function), в этом случае My_Functions будет применен к каждому pkt sniffed
  • правильный способ написать новый ip или mac - считать его строкой ex: ip="1.1.1.1" и т.д., как показано выше.
  • в примере: метод sendp включен в цикл for, который медленнее, чем другой цикл для отправки пакетов
  • подсказка производительности: в python, использующем для циклов, слишком медленно используется map, если вам нужна скорость, например, цикл for в C, Ref
  • Используемый выше rdpcap читает файл сразу, если доступная память при чтении составляет 1,5 Гб, и вы читаете файл 2,3,.. Gb, он не работает.
  • Если проблема с производительностью имеет решающее значение, вы можете использовать winpcap, но вам нужно написать более сложный код на C; выполнение одной и той же задачи с помощью python/scapy довольно просто, но это не быстрее, чем c
  • зависит от того, какой из них следует использовать на уровне требуемой производительности
  • Если моя догадка правильная, вы отправляете пакеты видеопотоков, в этом случае я бы использовал winpcap, если я отправляю 1 мегапиксельное видео или scapy в других случаях (меньший размер для каждого кадра).
  • в случае использования C/winpcap вы получите отличную производительность при чтении pcaps и изменении данных и повторной отправке, но вы должны знать об одной и той же проблеме (большие файлы), вам нужно создать буфер с соответствующим размером используйте его для чтения, отправляя пакеты с довольно высокой производительностью.
  • Если размер пакета является постоянным (что редко бывает в большинстве случаев, я думаю), у вас может быть преимущество получить большую часть вашей доступной памяти
  • Если вы хотите использовать python/scapy для всего "проекта/программы", вы можете создать высокопроизводительные функции в C/Wincap и скомпилировать как dll, тогда вы можете импортировать эту DLL в свою программу python, и вы можете использовать ее внутри программа python. Таким образом, вы получаете преимущества замечательного простого python/Scapy, и вы записываете только определенные функции в c, чтобы вы могли быстрее выполнять свою работу, а ваш код был сфокусированным и поддерживаемым.

Ответ 2

Хорошо, с scapy я придумал следующее (извините за мой Python). Надеюсь, это поможет кому-то. Был более простой сценарий, когда все пакеты из файла pcap считываются в память, но это может привести к проблемам с большими файлами захвата.

from scapy.all import *
global src_ip, dst_ip
src_ip = 1.1.1.1
dst_ip = 2.2.2.2
infile = "dump.pcap"

try:
    my_reader = PcapReader(infile)
    my_send(my_reader)
except IOError:
    print "Failed reading file %s contents" % infile
    sys.exit(1)

def my_send(rd, count=100):
    pkt_cnt = 0
    p_out = []

    for p in rd:
        pkt_cnt += 1
        np = p.payload
        np[IP].dst = dst_ip
        np[IP].src = src_ip
        del np[IP].chksum
        p_out.append(np)
        if pkt_cnt % count == 0:
            send(PacketList(p_out))
            p_out = []

    # Send remaining in final batch
    send(PacketList(p_out))
    print "Total packets sent %d" % pkt_cn

Ответ 3

Если бы я был вами, я бы разрешил Scapy работать с слоем Ether и использовать функцию send(). Например:

ip_map = {"1.2.3.4": "10.0.0.1", "1.2.3.5": "10.0.0.2"}
for p in PcapReader("filename.cap"):
    if IP not in p:
        continue
    p = p[IP]
    # if you want to use a constant map, only let the following line
    p.src = "10.0.0.1"
    p.dst = "10.0.0.2"
    # if you want to use the original src/dst if you don't find it in ip_map
    p.src = ip_map.get(p.src, p.src)
    p.dst = ip_map.get(p.dst, p.dst)
    # if you want to drop the packet if you don't find both src and dst in ip_map
    if p.src not in ip_map or p.dst not in ip_map:
        continue
    p.src = ip_map[p.src]
    p.dst = ip_map[p.dst]
    # as suggested by @AliA, we need to let Scapy compute the correct checksum
    del(p.chksum)
    # then send the packet
    send(p)

Ответ 4

Для правильной контрольной суммы мне также необходимо добавить del p[UDP].chksum