diff --git a/Black Hat Python/chapter_03/README.md b/Black Hat Python/chapter_03/README.md index c0db367..49f6cd8 100644 --- a/Black Hat Python/chapter_03/README.md +++ b/Black Hat Python/chapter_03/README.md @@ -10,3 +10,9 @@ Open another terminal pick a host to ping. ping google.com ``` Then you should see some garbled output + +### sniffer_ip_header_decode.py + +```bash +sudo sniffer_ip_header_decode.py +``` \ No newline at end of file diff --git a/Black Hat Python/chapter_03/sniffer_ip_header_decode.py b/Black Hat Python/chapter_03/sniffer_ip_header_decode.py new file mode 100644 index 0000000..d083eae --- /dev/null +++ b/Black Hat Python/chapter_03/sniffer_ip_header_decode.py @@ -0,0 +1,72 @@ +import ipaddress +import os +import socket +import struct +import sys + +class IP: + def __init__(self, buff=None): + header = struct.unpack('> 4 + self.ihl = header[0] & 0xF + self.tos = header[1] + self.len = header[2] + self.id = header[3] + self.offset = header[4] + self.ttl = header[5] + self.protocol_num = header[6] + self.sum = header[7] + self.src = header[8] + self.dst = header[9] + + # human readable IP addresses + self.src_address = ipaddress.ip_address(self.src) + self.dst_address = ipaddress.ip_address(self.dst) + + # map protocol constants to their names + self.protocol_map = {1: "ICMP", 6: "TCP", 17: "UDP"} + try: + self.protocol = self.protocol_map[self.protocol_num] + except Exception as e: + print('%s No protocol for %s' % (e, self.protocol_num)) + self.protocol = str(self.protocol_num) + +def sniff(host): + # should look familiar from previous example + 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)) + sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) + + if os.name == 'nt': + sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) + + try: + while True: + # read a packet + raw_buffer = sniffer.recvfrom(65535)[0] + + # create an IP header from the first 20 bytes + ip_header = IP(raw_buffer[0:20]) + + # print the detected protocol and hosts + 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) + sys.exit() + +if __name__ == '__main__': + if len(sys.argv) == 2: + host = sys.argv[1] + else: + hostname = socket.gethostname() + host = socket.gethostbyname(hostname) + print("Using host:", host) + sniff(host) \ No newline at end of file