Packet sniffing em Python (Windows)
Pergunta
O que é a melhor maneira de pacotes de rede Sniff usando Python?
Eu ouvi de vários lugares que o melhor módulo para isso é um módulo chamado scapy, infelizmente, faz acidente python.exe no meu sistema. Eu diria que é apenas um problema com a forma como eu instalei ele, exceto que muitas outras pessoas já me disseram que ele não funciona particularmente bem no Windows. (Se alguém estiver interessado, estou executando o Windows Vista, o que pode afetar as coisas).
Alguém sabe de uma solução melhor?
UPD:
Depois de ler a resposta me dizendo para instalar PyPcap, eu brinquei com ele um pouco e descobri que scapy, que eu tinha tentado usar, estava me dizendo para instalar PyPcap bem, exceto que é uma versão modificada para a sua utilização . Foi este modificado PyPcap que estava causando o problema, aparentemente, uma vez que o exemplo na resposta também causou uma parada.
Eu instalei a versão original do PyPcap (a partir do site do Google), e scapy começou a trabalhar bem (eu não tentei muitas coisas, mas pelo menos não falhar assim que começou a cheirar). Enviei um novo bilhete de defeito para os desenvolvedores scapy: http://trac.secdev.org/scapy/ bilhete / 166 , espero que eles possam fazer algo com ele.
De qualquer forma, apenas pensei que eu iria deixar vocês sabem.
Solução
Usando 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)
Exemplo de saída:
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'))))
Outras dicas
A maneira dura
Você pode cheirar todos os pacotes IP usando um socket raw.
socket raw é um soquete envia e recebe dados em binário.
Binário em python é representado em uma corda que tem esta aparência \x00\xff
... cada \x..
é um byte.
Para ler um pacote IP que você precisa para analisar o pacote recebido no acordo binário para o protocolo IP.
Esta é imagem e do formato do protocolo IP com o tamanho em bits de cada cabeçalho.
Este tutorial pode ajudar você a entender o proccess de compreender um pacote cru e dividindo-a cabeçalhos: http://www.binarytides.com/python-packet-sniffer-code-linux/
A maneira mais fácil
Outro método para pacotes IP Sniff é muito fácil de usar o módulo scapy.
from scapy.all import *
sniff(filter="ip", prn=lambda x:x.sprintf("{IP:%IP.src% -> %IP.dst%\n}"))
Este código irá imprimir para você o IP de origem eo IP de destino para cada pacote IP. Você pode fazer muito mais com scapy por lê-lo de documentação aqui: http: // www .secdev.org / projetos / scapy / doc / usage.html
Depende do objetivo que você está tentando alcançar, mas se você precisa para construir um projeto a suas características sniffing pacotes IP, então eu recomendo usar scapy para mais scripts estáveis.
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()
Você pode usar soquetes brutos, com o seu endereço de IP da interface (no modo admin),
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
Se scapy, pleae tente o seguinte método. (Ele funciona em 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()