[PYTHON] Astuces Scapy

Aperçu

Scapy Tips Collection (ajouté séquentiellement)

Documentation officielle

https://scapy.readthedocs.io/en/latest/

Scapy API reference https://scapy.readthedocs.io/en/latest/api/scapy.html

Tips

Je souhaite connaître le nom de l'interface de l'adaptateur Ethernet

Utilisez get_windows_if_list ().

Il peut être défini sur iface dans le paramètre de chaque API.

référence

[Scapy can't see_use some Ethernet interfaces on Windows · Issue #1542 · secdev_scapy · GitHub]( https://webcache.googleusercontent.com/search?q=cache:qS0tKu17dBoJ: https://github.com/secdev/scapy/issues/1542) écrit en gpotter2 commenté le 7 août 2018d

code

from scapy.all import *
get_windows_if_list()

résultat

La valeur de name peut être définie dans l'argument iface de chaque API. Dans l'exemple ci-dessous, Ethernet 6 '', Ethernet 2 '', etc. Recherchez l'adaptateur Ethernet souhaité par adresse MAC ou IP. Vous pouvez définir le nom sur iface.

In [6]: from scapy.all import *
   ...: get_windows_if_list()
Out[6]: 
[{'name': 'Ethernet 6',
  'win_index': 15,
  'description': 'ASIX AX88179 USB 3.0 to Gigabit Ethernet Adapter #2',
  'guid': '{93E3CFB5-11A7-43F4-9BE0-E42AD69529A3}',
  'mac': '74:03:bd:7f:83:21',
  'ipv4_metric': 5,
  'ipv6_metric': 5,
  'ips': ['fe80::b964:9105:342:b0e1', '192.168.51.123']},
 ...
 {'name': 'Ethernet 2',
  'win_index': 11,
  'description': 'Intel(R) Ethernet Connection (5) I219-LM',
  'guid': '{6091155D-A8EA-491C-BA3D-CD5CB22B29BE}',
  'mac': '40:b0:34:1a:78:6f',
  'ipv4_metric': 25,
  'ipv6_metric': 0,
  'ips': ['10.168.38.67']},
   ...

Note

~~ Nmap Loopback Adapter (un adaptateur virtuel pour vérifier la communication entre 127.0.0.1) apparaît également ici, mais lorsque j'essaye de convertir le paquet obtenu par sniff () en pcap avec wrpcap (), cela échoue. enquêter. ~~

Cela s'est également produit sur l'interface réelle. Ce qui s'est passé dans l'interface réelle, c'est que le paquet obtenu par sniff () est stocké dans la liste. C'était parce que je le passais à wrpcap (). En termes d'image, c'était comme suit.

[<Sniffed: TCP:0 UDP:5 ICMP:0 Other:5>, <Sniffed: TCP:0 UDP:5 ICMP:0 Other:5>, ...]

(Je créais une liste d'instances de scapy.plist.PacketList)

Bien que append () etc. ne soit pas pris en charge, + = pouvait être utilisé, la méthode d'écriture suivante était donc possible.

all_packets = None
#boucle
...
    pkts = scpy.sniff(iface="Ethernet 4", count=10)
    if all_packets :
        all_packets += pkts #Après la première fois+=Je vais l'ajouter avec.
    else:
        all_packets = pkts #Première fois
wrpcap(fname, all_packets )

Il semble que cela ne sert à rien si Loopback Pseudo-Interface 1 est sélectionné lorsque vous voulez voir le loopback ("127.0.0.1").

  File "C:\Python37\lib\site-packages\scapy\arch\windows\__init__.py", line 706, in dev_from_pcapname
    raise ValueError("Unknown pypcap network interface %r" % pcap_name)
ValueError: Unknown pypcap network interface 'Loopback Pseudo-Interface 1'

Lorsque j'ai défini "Npcap Loopback Adapter" sur ifcace, j'ai pu obtenir le pcap de "127.0.0.1". Cependant, si vous mesurez le "Npcap Loopback Adapter" directement avec WireShark, vous pouvez analyser correctement le paquet, Lorsque j'ouvre le pcap acquis, N / A s'affiche même si les données sont les mêmes.

image.png

Puisque vous pouvez obtenir l'interface réelle, y a-t-il un problème? .. .. Voulez-vous effectuer un contrôle qualité avec github ou un débordement de pile? .. ..

https://github.com/nmap/nmap/issues/200 Par https://wiki.wireshark.org/NullLoopback Il est devenu?

Je souhaite publier facilement le résumé (adresse IP, port) du paquet reçu sur la console pour le moment

référence

scapy.sendrecv.sniff(*args, **kwargs) https://scapy.readthedocs.io/en/latest/api/scapy.sendrecv.html#scapy.sendrecv.sniff

code

Ce qui suit est une méthode synchrone, vous devez donc l'arrêter avec Ctrl + C. Il est également possible de définir des conditions d'arrêt en fonction du nombre de paquets reçus et du délai d'expiration.

from scapy.all import *
sniff(iface='Ethernet 4', prn=lambda x: x.summary())

résultat

In [7]: from scapy.all import *
   ...: sniff(iface='Ethernet 4', prn=lambda x: x.summary())
Ether / IP / UDP 192.168.50.12:30490 > 237.50.0.1:30490 / Raw
Ether / IP / UDP 192.168.50.12:30490 > 237.50.0.1:30490 / Raw
Ether / IP / UDP 192.168.50.12:30490 > 237.50.0.1:30490 / Raw
Ether / IP / UDP 192.168.50.12:30490 > 237.50.0.1:30490 / Raw
Ether / IP / UDP 192.168.50.12:30490 > 237.50.0.1:30490 / Raw
Ether / IP / UDP 192.168.50.12:30490 > 237.50.0.1:30490 / Raw
Ether / IP / UDP 192.168.50.12:30490 > 237.50.0.1:30490 / Raw
Ether / ARP who has 192.168.51.2 says 192.168.51.1 / Padding
Ether / IP / UDP 192.168.50.12:30490 > 237.50.0.1:30490 / Raw
Ether / ARP who has 192.168.51.2 says 192.168.51.1 / Padding
Ether / ARP who has 192.168.51.2 says 192.168.51.1 / Padding
Ether / IP / UDP 192.168.50.12:30490 > 237.50.0.1:30490 / Raw
Ether / ARP who has 192.168.51.2 says 192.168.51.1 / Padding
Ether / ARP who has 192.168.51.2 says 192.168.51.1 / Padding
Ether / IP / UDP 192.168.50.12:30490 > 237.50.0.1:30490 / Raw
Ether / ARP who has 192.168.51.2 says 192.168.51.1 / Padding
Ether / ARP who has 192.168.51.2 says 192.168.51.1 / Padding
Out[7]: <Sniffed: TCP:0 UDP:10 ICMP:0 Other:7>

Je veux recevoir un paquet dans un autre thread et le sortir dans le journal + pcap.

AsyncSniffer sera écrit séparément.

Voici un exemple de classe qui ajoute une méthode pour créer pcap basée sur l'article Programmation réseau utilisant Python Scapy --Qiita.

code

import threading
import scapy.all as scpy
import datetime
from logging import getLogger, basicConfig, NullHandler,DEBUG, INFO, WARNING
mylogger = getLogger(__name__)
mylogger.addHandler(NullHandler())

class Sniffer(threading.Thread):
    def __init__(self, iface, count=20, timeout=3, logger=None):
        self.stop_event = threading.Event() #Drapeau pour arrêter
        self.thread = threading.Thread(target = self._sniffer_main_loop)
        self.iface = iface
        self.count = count
        self.timeout = timeout
        self.packets = None
        if logger:
            self.log = logger
        else:
            self.log = mylogger
        
    def start(self):
        self.log.debug(f"try to start thread.")
        self.packets = None
        self.stop_event.clear()
        self.thread.start()

    def stop(self):
        self.log.debug(f"try to stop thread.")
        self.stop_event.set()
        self.thread.join()

    def _sniffer_main_loop(self):
        self.log.debug(f"start thread.")

        try:
            while not self.stop_event.is_set():
                pkts = scpy.sniff(iface=self.iface, count=self.count, timeout=self.timeout)
                if self.packets:
                    self.packets += pkts
                else:
                    self.packets = pkts
        except Exception as e:
            self.log.error(f"exception occurred. stop sniffer main loop. {e}")
            self.stop_event.set()
        
        self.log.debug(f"end thread.")

    def create_pcap(self, fname=datetime.datetime.now().strftime("doip_test_%H%M%S.cap")):
        self.stop() if not self.stop_event.is_set() else None
        scpy.wrpcap(fname, self.packets)

résultat

Comment utiliser est ajouté séparément.

Recommended Posts

Astuces Scapy
astuces python
Le tour de Jupyter 4
astuces numpy
Astuce de Jupyter 5
Astuce de Jupyter 3
Le tour de Jupyter 2
scapy IPv6
Astuces Python
Astuces Python
Conseils Python Conda
Conseils personnels de Django
Conseils de débogage Python
Astuces de clic Python
[pandas] Conseils GroupBy
De manière inattendue (?) Connaissance du bean Python
Tensorflow mes propres conseils
Astuces pour les modèles Django
Conseils d'écriture sur tissu
Conseils de traçage LTTng
Collection de conseils chorégraphe