import socket
import os
import struct
import sys
from ctypes import *
# host to listen on
host = sys.argv[1]
class IP(Structure):
_fields_ = [
("ihl", c_ubyte, 4),
("version", c_ubyte, 4),
("tos", c_ubyte),
("len", c_ushort),
("id", c_ushort),
("offset", c_ushort),
("ttl", c_ubyte),
("protocol_num", c_ubyte),
("sum", c_ushort),
("src", c_ulong),
("dst", c_ulong)
]
def __new__(self, socket_buffer=None):
return self.from_buffer_copy(socket_buffer)
def __init__(self, socket_buffer=None):
# map protocol constants to their names
self.protocol_map = {1:"ICMP", 6:"TCP", 17:"UDP"}
# human readable IP addresses
self.src_address = socket.inet_ntoa(struct.pack("<L",self.src))
self.dst_address = socket.inet_ntoa(struct.pack("<L",self.dst))
# human readable protocol
try:
self.protocol = self.protocol_map[self.protocol_num]
except:
self.protocol = str(self.protocol_num)
# create a raw socket and bind it to the public interface
if os.name == "nt":
socket_protocol = socket.IPPROTO_IP
else:
socket_protocol = socket.IPPROTO_ICMP
sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol)
sniffer.bind((host, 0))
# we want the IP headers included in the capture
sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
# if we're on Windows we need to send some ioctls
# to setup promiscuous mode
if os.name == "nt":
sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
try:
while True:
# read in a single packet
raw_buffer = sniffer.recvfrom(65565)[0]
# create an IP header from the first 20 bytes of the buffer
ip_header = IP(raw_buffer[0:20])
print "Protocol: %s %s -> %s" % (ip_header.protocol, ip_header.src_address, ip_header.dst_address)
except KeyboardInterrupt:
# if we're on Windows turn off promiscuous mode
if os.name == "nt":
sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
To jest kod z książki Black Hat Python. Ten kod ma na celu wykrycie surowych gniazd i wyświetlenie informacji z nagłówka IP. Działa dobrze dla mnie w systemie Windows (przy użyciu Windows 8.1 64bit). Gdy próbuję uruchomić to na linux (Kali Linux 1.1.0-amd64) pojawia się następujący błądPython Sniffing z książki Black Hat Python
ValueError: Buffer size too small (20 instead of at least 32 bytes)
Aby obejść że dodałem 12 obowiązuje do bufora jak ten
ip_header = IP(raw_buffer[0:20]+' '*12)
When robię, że pojawia się następujący błąd
struct.error: 'L' format requires 0 <= number <= 4294967295
ten występuje na linii
self.src_address = socket.inet_ntoa(struct.pack("<L",self.src))
Próbowałem zmienić symbol przed L na> i! i próbowałem tego z L, wszyscy oni dają mi ten sam problem. Próbowałem też owinąć self.src w ntohs jak tak
self.src_address = socket.inet_ntoa(struct.pack("<L",socket.ntohs(self.src)))
myślę to ma coś wspólnego z bajt, ale nie jestem pewien. Każda pomoc będzie bardzo ceniona.
UWAGA: W systemie Windows musisz działać jako administrator, a na Linuksie musisz działać jako superuser z powodu surowych gniazd. Jeśli uruchomisz to na Linuksie, otwórz inny terminal i pinguj www.google.com, aby móc wygenerować kilka pakietów ICMP do przechwycenia.
EDIT: Próbowałem również odwrócenie bufor z
ip_header = IP(raw_buffer[0:20][::-1]+' '*12)
EDIT 2: Próbowałem zarówno 65535 i 65534 na poniższej linii przed wykonaniem którejkolwiek z pozostałych pozycji I tutaj wymienione.
raw_buffer = sniffer.recvfrom(65565)[0]
EDIT 3: To działało na komputerze z systemem ubuntu Pythona 2.7.6 i mój kali distro został 2.7.3 więc postanowiłem pobrać najnowszą wersję Pythona na moim polu kali co zdarza się 2.7.9 . Wciąż nie ma szczęścia.
umieściłem następujący kod do nowej funkcji w moim struktury aby zobaczyć rozmiar bufora
print sizeof(self)
na moim Ubuntu i Windows maszyn było 20 ale na moim komputerze kali było 32
Twój kod działa. sys.version '2.7.6 (domyślnie, 22 marca 2014, 22:59:38) \ n [GCC 4.8.2]'. 'uname -a' 'Linux laptop 3.16.0-25-generiC# 33-Ubuntu SMP Wt. 4 listopada 12:05:25 UTC 2014 i686 i686 i686 GNU/Linux' –
spróbuj przekazać cały bufor' IP (raw_buffer) 'lub 'IP (raw_buffer [: 32])' –
Interesujące .. po prostu przyjrzałem się wersji pythona, którą mam na moim komputerze w Linuksie, która jest 2.7.3, a moje okno to 2.7.8 ... Spróbuję uaktualnić i zobaczyć co dzieje się. –