1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Scapy Tips

Last updated at Posted at 2020-03-08

概要

scapyのTips集(順次追加)

公式ドキュメント

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

Tips

Ethernetアダプタのインターフェース名を知りたい

get_windows_if_list()を使います。

各APIのパラメータにあるifaceに設定可能です。

参考

Scapy can't see_use some Ethernet interfaces on Windows · Issue #1542 · secdev_scapy · GitHubの gpotter2 commented on 7 Aug 2018dで書かれている

コード

from scapy.all import *
get_windows_if_list()

結果

nameの値が各APIの引数ifaceに設定できる。
下記の例でいうと、'イーサネット 6', 'イーサネット 2'など
MACやIPアドレスから所望のEthernetアダプタを見つけます。
nameをifaceに設定することができます。

In [6]: from scapy.all import *
   ...: get_windows_if_list()
Out[6]: 
[{'name': 'イーサネット 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': 'イーサネット 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']},
   ...

メモ

Nmap Loopback Adapter (127.0.0.1同士の通信を確認するための仮想的なアダプタ)もここに出てくるが、sniff()で取得したpacketをwrpcap()でpcap化しようとすると失敗する。調査中。

実インターフェースでも発生した。
実インターフェースで発生したのはsniff()で取得したpacketをリストに入れて格納してしまっており、
それをwrpcap()に渡していたためであった。
イメージでいうと以下のようになっていた。

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

(scapy.plist.PacketListのインスタンスのリストを作成していた)

append()などがサポートされていなかったが+=が使えたので、以下の書き方ができた。

all_packets = None
# ループ
...
    pkts = scpy.sniff(iface="イーサネット 4", count=10)
    if all_packets :
        all_packets += pkts # 初回以降は+=で追加していく。
    else:
        all_packets = pkts # 初回
wrpcap(fname, all_packets )

ループバック("127.0.0.1")を見たいときにLoopback Pseudo-Interface 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'

ifcaceに "Npcap Loopback Adapter" を設定すると"127.0.0.1"のpcapを取得することができた。
ただ、wiresharkで直接"Npcap Loopback Adapter"を測定するとパケットを適切に解析できるが、
取得したpcapを開くと、データ的には同じにも関わらず、N/Aが表示されてしまう・・・。

image.png

実際のインターフェースなら取得できるので、問題なしとするか。。。githubかstack overflowでQAしてみるか。。。

https://github.com/nmap/nmap/issues/200
によって、
https://wiki.wireshark.org/NullLoopback
になっている?

受信したパケットのサマリ(IPアドレス、ポート)をとりあえず簡単にコンソールに出したい

参考

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

コード

以下は同期のメソッドなのでCtrl+Cで止める必要あり。
受信パケット数やタイムアウトなどで停止条件を設定することもできる。

from scapy.all import *
sniff(iface='イーサネット 4', prn=lambda x: x.summary())

結果

In [7]: from scapy.all import *
   ...: sniff(iface='イーサネット 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>

別スレッドでパケット受信して、ログに出力したい+pcapにしたい。

AsyncSnifferについては別で書く。

ここではPython Scapyを使ったネットワークプログラミング - Qiitaの記事をベースにpcapにするメソッドを追加したクラス例。

コード

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() #停止させるかのフラグ
        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)

結果

使い方は別途追記。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?