David
David

Reputation: 41

Python socket.bind() to host does not show incoming packets with SIO_RCVALL while sniffing for traffic on an interface

I'm attempting to read incoming/outgoing TCP packets through an interface on the host for a project I'm working on. I really want this to be done using sockets instead of using a library like scapy or pypcap. To have a better understanding of what is happening as well as more control over what is happening. This is on a Windows10 system.

import socket
import threading
from PacketParse import PacketParse

host = socket.gethostbyname(socket.gethostname())

sniff = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP) 
sniff.bind((host, 0))

#include ip headers - IP PROTOCOL, IP HEADER INCLUDE
sniff.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)

#receive all packages - INPUT OUTPUT CONTROL
sniff.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

def start_sniffing():
    while True:
        raw_packet = sniff.recvfrom(2000)
        packet = PacketParse(raw_packet)
        if packet:
            print(packet.src_addr + ":" + str(packet.src_port) + " --> " + packet.dst_addr + ":" + str(packet.dst_port) + " Protocol: " + packet.ip_prot + "(" + str(packet.ip_prot_raw) + ")")
            print("Data(" + str(packet.data_size) + "): " + str(packet.data))
            #file.write(packet.src_addr + ":" + str(packet.src_port) + " --> " + packet.dst_addr + ":" + str(packet.dst_port) + " Protocol: " + packet.ip_prot + "(" + str(packet.ip_prot_raw) + ")")
            #file.write("Data(" + str(packet.data_size) + "): " + str(packet.data))'''

file = open("dump.txt", "a")
t = threading.Thread(target=start_sniffing)
t.start()
t.join()

file.close()
sniff.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

PacketParse is a class I made to 'unpack' the packet. I've been using Python documentation for most of this script and tutorials for sniffing packets from many sources.

from struct import unpack

class PacketParse:
    def __init__(self, packet):
        self.extract(packet)

    def extract(self, packet):
        # extract ip header
        packet = packet[0]
        self.packet_raw = packet
        '''
        eth_raw = packet[:14]
        eth_hdr = unpack('!6s6sH', eth_raw)
        self.eth_prot = socket.ntohs(eth_hdr[2])
        self.src_mac = 
        '''
        ip_raw = packet[0:20]
        ip_hdr = unpack('!BBHHHBBH4s4s', ip_raw)
        #self.ip_length = ip_hdr[5]
        self.ip_prot_raw = ip_hdr[6]
        self.ip_prot = self.ip_prot_parse(ip_hdr[6])
        self.src_addr = socket.inet_ntoa(ip_hdr[8])
        self.dst_addr = socket.inet_ntoa(ip_hdr[9])
        version = ip_hdr[0] >> 4
        ihl_length = version & 0xF
        iph_len = ihl_length * 4

        tcp_raw = packet[20:40]
        tcp_hdr = unpack('!HHLLBBHHH', tcp_raw)
        self.src_port = tcp_hdr[0]
        self.dst_port = tcp_hdr[1]
        self.seq_num = tcp_hdr[2]
        self.ack_num = tcp_hdr[3]
        doff_reserved = tcp_hdr[4]
        tcp_length = doff_reserved >> 4

        header_size = (iph_len) + (tcp_length * 4)
        self.data_size = len(packet) - header_size

        self.data = packet[header_size:]

    def ip_prot_parse(self, num):
        return {
        1: 'ICMP',
        6: 'TCP',
        17: 'UDP',
        }.get(num, "Unknown")

The issue is this only shows packets being sent out from this host. Incoming packets are not displayed. A different script I've tried using scapy is capable of displaying incoming packets as well. Why is this happening? SIO_RCVALL should be allowing ALL packets being touched by the interface to be seen. I haven't tried a Linux equivalent of this script... so I don't know if the problem is specific on Windows. Most TCP reading scripts I've found have been Linux specific.

Upvotes: 0

Views: 855

Answers (1)

David
David

Reputation: 41

Alright... so it seems the problem was my firewall. When I turn it off, I can see all incoming packets just fine. That was a bit annoying. I believe there is a python library that allows you to edit firewall settings.

https://github.com/austin-taylor/bluewall

I haven't played around with it yet... it could be interesting. I haven't read into it enough yet to understand if this is what it seems. I believe it only gives you the configuration on Windows without changing anything. It could be fun on a Linux system.

Upvotes: 2

Related Questions