Python Sniffing from Black Hat Python book

后端 未结 2 1758
孤街浪徒
孤街浪徒 2021-02-07 12:15
import socket
import os
import struct
import sys
from ctypes import *

# host to listen on
host   = sys.argv[1]

class IP(Structure):

    _fields_ = [
        (\"ihl\",         


        
2条回答
  •  花落未央
    2021-02-07 12:48

    So it's a 64/32 bit problem. The fact that it needed 32 bytes instead of 20 means that the struct was not packed correctly. "c_ulong" is 64 bits in 64 bit linux, and was being mapped that way in the "IP" class.

    The IP header is 20 bytes + optional fields. The source and destination ip addresses end by byte 20, which is what the current IP structure is picking up. (if you want the options, you're going to have to parse those out by hand).

    I looked up the UDP bit fields and directly set them into the class "IP". Looking at the ctypes docs, integer types can be mapped to limit the number of bits.

    class IP(Structure):
    
        _fields_ = [
            ("ihl",           c_ubyte, 4),
            ("version",       c_ubyte, 4),
            ("tos",           c_ubyte, 8),
            ("len",           c_ushort, 16),
            ("id",            c_ushort, 16),
            ("offset",        c_ushort, 16),
            ("ttl",           c_ubyte, 8),
            ("protocol_num",  c_ubyte, 8),
            ("sum",           c_ushort, 16),
            ("src",           c_uint, 32),
            ("dst",           c_uint, 32),
        ]
    

    If you sum the bit offsets, they sum to 160. 160/8 = 20 bytes, which is what ctypes packs this struct to.

    Running that on a ping yields something that looks acceptable.

    Protocol: ICMP 127.0.0.1 -> 127.0.0.1
    Protocol: ICMP 127.0.0.1 -> 127.0.0.1
    Protocol: ICMP 127.0.0.1 -> 127.0.0.1
    Protocol: ICMP 127.0.0.1 -> 127.0.0.1
    

    Further, packet size is a function of MTU (or Maximum Transfer Unit), so if you plan on running this on ethernet, the limiting factor is the MTU of the frame. Larger packets will get fragmented in the tcp/ip stack before being pushed out of the ethernet port.

    $ ifconfig eth0
    eth0      Link encap:Ethernet  HWaddr 00:00:00:ff:ff:ff  
              UP BROADCAST MULTICAST  MTU:1500  Metric:1
    

    Also, this question should help clarify the issue on why some platforms have different sized ints and longs:

    What is the bit size of long on 64-bit Windows?

    As an alternative, I have found that dpkt is a rather good library for decoding/encoding ip packets, unless you specifically need to use or want ctypes.

    https://code.google.com/p/dpkt/

提交回复
热议问题