Packet sniffing in Python (Windows)

谁说我不能喝 提交于 2019-12-17 08:53:36

问题


What is the best way to sniff network packets using Python?

I've heard from several places that the best module for this is a module called Scapy, unfortunately, it makes python.exe crash on my system. I would assume that it's just a problem with how I installed it, except that many other people have told me that it doesn't work particularly well on Windows. (If anyone is interested, I'm running Windows Vista, which might affect things).

Does anyone know of a better solution?

UPD:

After reading the answer telling me to install PyPcap, I messed around with it a bit and found out that Scapy, which I had tried using, was telling me to install PyPcap as well, except that it's a modified version for it's use. It was this modified PyPcap that was causing the problem, apparently, since the example in the answer also caused a hang.

I installed the original version of PyPcap (from Google's site), and Scapy started working fine (I didn't try many things, but at least it didn't crash as soon as I started sniffing). I sent a new defect ticket to the Scapy developers: http://trac.secdev.org/scapy/ticket/166, hope they can do something with it.

Anyways, just thought I'd let y'all know.


回答1:


Using pypcap:

import dpkt, pcap
pc = pcap.pcap()     # construct pcap object
pc.setfilter('icmp') # filter out unwanted packets
for timestamp, packet in pc:
    print dpkt.ethernet.Ethernet(packet)

output sample:

Ethernet(src='\x00\x03G\xb2M\xe4', dst='\x00\x03G\x06h\x18', data=IP(src='\n\x00\x01\x1c',
dst='\n\x00\x01\x10', sum=39799, len=60, p=1, ttl=128, id=35102, data=ICMP(sum=24667,
type=8, data=Echo(id=512, seq=60160, data='abcdefghijklmnopqrstuvwabcdefghi'))))

Ethernet(src='\x00\x03G\x06h\x18', dst='\x00\x03G\xb2M\xe4', data=IP(src='\n\x00\x01\x10',
dst='\n\x00\x01\x1c', sum=43697, len=60, p=1, ttl=255, id=64227, data=ICMP(sum=26715,
data=Echo(id=512, seq=60160, data='abcdefghijklmnopqrstuvwabcdefghi'))))



回答2:


The hard way

You can sniff all of the IP packets using a raw socket.
Raw socket is a socket the sends and receives data in binary.
Binary in python is represented in a string which looks like this \x00\xff... every \x.. is a byte.
To read an IP packet you need to analyze the received packet in binary according to the IP protocol.

This is and image of the format of the IP protocol with the sized in bits of every header.

This tutorial might help you understand the proccess of understanding a raw packet and splitting it to headers: http://www.binarytides.com/python-packet-sniffer-code-linux/

The easy way

Another method to sniff IP packets very easily is to use the scapy module.

from scapy.all import *
sniff(filter="ip", prn=lambda x:x.sprintf("{IP:%IP.src% -> %IP.dst%\n}"))

This code will print for you the source IP and the destination IP for every IP packet. You can do much more with scapy by reading it's documentation here: http://www.secdev.org/projects/scapy/doc/usage.html

It depends on the goal you are trying to achieve but if you need to build a project the one it's features is sniffing IP packets then I recommend to use scapy for more stable scripts.




回答3:


Use python-libpcap.

import pcap

p = pcap.pcapObject()
dev = pcap.lookupdev()
p.open_live(dev, 1600, 0, 100)
#p.setnonblock(1)
try:
    for pktlen, data, timestamp in p:
        print "[%s] Got data: %s" % (time.strftime('%H:%M', 
                                                   time.localtime(timestamp)),
                                     data)
except KeyboardInterrupt:
    print '%s' % sys.exc_type
    print 'shutting down'
    print ('%d packets received, %d packets dropped'
           ' %d packets dropped by interface') % p.stats()



回答4:


you can use raw sockets, with your interface ip address (in admin mode),

import socket
s = socket.socket(socket.AF_INET,socket.SOCK_RAW,socket.IPPROTO_IP)
s.bind(("YOUR_INTERFACE_IP",0))
s.setsockopt(socket.IPPROTO_IP,socket.IP_HDRINCL,1)
s.ioctl(socket.SIO_RCVALL,socket.RCVALL_ON)
while True:
   data = s.recvfrom(10000)
   print data



回答5:


Another option is pypcap.

To parse the results, Construct is very slick.




回答6:


If scapy, pleae try the following method. (It works on Windows 10)

# -*- coding: utf-8 -*-

# pip install scapy

"""
[{'name': 'Intel(R) 82574L Gigabit Network Connection',
  'win_index': '4',
  'description': 'Ethernet0',
  'guid': '{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}',
  'mac': '00:0C:29:5C:EE:6D',
  'netid': 'Ethernet0'}]
"""

from pprint import pprint
from scapy.arch.windows import get_windows_if_list
from scapy.all import *


# disable verbose mode
conf.verb = 0


def parse_packet(packet):
    """sniff callback function.
    """
    if packet and packet.haslayer('UDP'):
        udp = packet.getlayer('UDP')
        udp.show()


def udp_sniffer():
    """start a sniffer.
    """
    interfaces = get_windows_if_list()
    pprint(interfaces)

    print('\n[*] start udp sniffer')
    sniff(
        filter="udp port 53",
        iface=r'Intel(R) 82574L Gigabit Network Connection', prn=parse_packet
    )


if __name__ == '__main__':
    udp_sniffer()


来源:https://stackoverflow.com/questions/462439/packet-sniffing-in-python-windows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!