Отправка пакетов из pcap с измененным src / dst в scapy - PullRequest
17 голосов
/ 04 января 2012

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

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

Ответы [ 4 ]

24 голосов
/ 13 января 2012

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

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, методы scry для wrpcap для чтения и записи из файла в формате pcap
  • , который вы можете использовать sniff(offline="filename") для чтения пакетов, и вы можете использовать параметр prn, подобный этому sniff(offline="filename",prn=My_Function), в этом случае My_Functions будет применяться к каждому pkt-снифферу
  • правильный способ написать ваш новый ip или mac - это рассматривать его как строкунапример: ip="1.1.1.1" и т. д., как показано выше.
  • в примере: метод sendp включен в цикл for, который медленнее, чем выполнение другого цикла для отправки пакетов * Совет производительности: 1016 *
  • : в python с использованием forциклы слишком медленные, используйте map вместо этого, если вам нужна скорость, подобная циклу for в C, Ref
  • rdpcap, как указано выше, читает файл сразу,если объем памяти, доступной во время чтения, скажем 1,5 Гб, а вы читаете файл 2,3, ... Гб, произойдет сбой.
  • , если проблема с производительностью критична, вы можете использовать winpcap , ноВы должны написать более сложный код на C; DoiЕсли та же задача с использованием python / scapy довольно проста, но она не быстрее, чем c
  • , это зависит от того, какую из них использовать на необходимом уровне производительности
  • , если мое предположение правильноотправка пакетов видеопотока в этом случае я бы использовал winpcap, если я отправляю 1-мегапиксельное видео или scapy в других случаях (меньший размер на кадр)
  • в случае использования C / winpcap вы получитеотличная производительность при чтении pcaps, изменении данных и повторной отправке, но вы должны знать о той же проблеме (большие файлы), которую вы должны создать буфер подходящего размера, чтобы использовать его для чтения, посылая пакеты с вполне высокой производительностью
  • если размер пакета постоянен (что, как я полагаю, редко встречается), у вас может быть преимущество получить большую часть доступной памяти
  • , если вы хотите использовать python / scapy для всего«проект / программа» вы можете создать высокопроизводительные функции в C / Wincap и скомпилировать как dll, затем вы можете импортировать эту dll в вашу программу на python иг вы можете использовать его в программе Python.Таким образом, вы получаете преимущества замечательного легкого Python / Scapy и пишете только определенные функции на c, чтобы вы могли быстрее выполнять свою работу, а ваш код быть сфокусированным и обслуживаемым
6 голосов
/ 23 января 2014

Если бы я был вами, я бы позволил 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)
5 голосов
/ 05 января 2012

Ну, со 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
0 голосов
/ 30 ноября 2015

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

...