Envoyer des paquets à partir de pcap avec un src/dst modifié dans scapy

j'essaie d'envoyer un trafic déjà enregistré (au format pcap) avec scapy. Actuellement je suis coincé à rayer la couche D'éther originale. Le trafic a été capturé sur un autre hôte et je dois essentiellement changer les couches IP et éther src et dst. J'ai réussi à remplacer la couche IP et à recalculer les sommes de contrôle, mais la couche éther me pose problème.

Quelqu'un a de l'expérience dans la revente de paquets à partir d'un fichier de capture avec des modifications appliquées à la couche IP et éther(src et dst)? Aussi, l' la capture est plutôt un gros couple de Go, Que diriez-vous de performances scapy avec de telles quantités de trafic?

17
demandé sur Jason Bart 2012-01-04 16:29:03

4 réponses

cochez cet exemple

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

commentaires:

  • utiliser les méthodes rdpcap,wrpcap scapy pour lire et écrire à partir d'un fichier formaté pcap
  • vous pouvez utiliser sniff(offline="filename") pour lire des paquets, et vous pouvez utiliser prn paramètre comme ceci sniff(offline="filename",prn=My_Function) dans ce cas My_Functions sera appliqué à chaque pkt reniflé
  • la bonne façon d'écrire votre nouvelle ip ou mac est de la considérer comme une chaîne ex:ip="1.1.1.1" et ainsi de suite, comme illustré ci-dessus.
  • dans l'exemple: la méthode sendp incluse dans for loop qui est plus lente que de faire une autre boucle pour envoyer des paquets
  • Conseil de performance: en python utiliser pour loops est trop lentcarte au lieu de cela si vous voulez une vitesse comme a pour boucle en C, Ref
  • le rdpcap tel qu'utilisé ci-dessus lit le fichier à la fois, si la mémoire disponible lors de la lecture dire 1,5 Go et vous lisez un 2,3,.. Go de fichier, il échouera.
  • si le problème de performance est critique pour vous pouvez utilisez winpcap mais vous devez écrire du code plus complexe en C;Faire la même tâche en utilisant python / scapy est assez facile un simple mais ce n'est pas plus rapide que c
  • ça dépend à utiliser sur le niveau de performance requis
  • si je devine que vous envoyez des paquets de flux vidéo dans ce cas, j'utiliserais un winpcap si j'envoie une vidéo de 1 méga pixel ou scapy dans d'autres cas(taille inférieure par image)
  • en cas d'utilisation de C / winpcap vous devez obtenir une grande performance en lecture pcaps et de changer les données et de le renvoyer, mais vous devez être conscient de le même problème (gros fichiers), vous devrez créer un tampon avec une taille appropriée à utiliser pour la lecture d'envoyer les paquets dans une performance
  • si la taille du paquet est constante(ce qui est rare dans la plupart des cas, je suppose) vous pourriez avoir un avantage à profiter au maximum de votre mémoire disponible
  • si vous souhaitez utiliser python/scapy pour l'ensemble du "projet/programme", vous pouvez créer le haut les fonctions de performance dans C / Wincap et compiler comme dll alors vous pouvez importer cette dll à votre programme python et vous pouvez l'utiliser à l'intérieur d'un programme python. De cette façon, vous obtenez les avantages de wonderful easy python/Scapy et vous n'écrivez qu'une fonction spécifique en c pour que vous puissiez faire votre travail plus rapidement et votre code pour être concentré et maintenable
23
répondu Abdurahman 2014-07-20 11:28:59

Si j'étais vous, je laisserais Scapy traiter avec le Ether calque, et d'utiliser le send() fonction. Exemple:

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)
6
répondu Pierre 2014-03-26 21:25:23

Eh bien, avec scapy j'ai trouvé ce qui suit (désolé pour mon Python). J'espère que ça aidera quelqu'un. Il y avait un scénario plus simple possible où tous les paquets du fichier pcap sont lus dans la mémoire, mais cela pourrait conduire à des problèmes avec les grands fichiers de capture.

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
5
répondu Jason Bart 2012-01-05 14:25:03

pour la somme de contrôle correcte, j'ai aussi dû ajouter del p[UDP].chksum

0
répondu Catalina 2015-11-30 14:39:51