USB mapping with python
Question: While reading some CTF write-ups I came across this script

    
    
    #!/usr/bin/env python
    import struct
    import Image
    import dpkt
    
    INIT_X, INIT_Y = 100, 400
    
    def print_map(pcap, device):
        picture = Image.new("RGB", (1200, 500), "white")
        pixels = picture.load() 
    
        x, y = INIT_X, INIT_Y
    
        for ts, buf in pcap:
            device_id, = struct.unpack("b", buf[0x0B])
    
            if device_id != device:
                continue
    
            data = struct.unpack("bbbb", buf[-4:])
    
            status = data[0]
            x = x + data[1]
            y = y + data[2]
    
            if (status == 1):
                for i in range(-5, 5):
                    for j in range(-5, 5):
                        pixels[x + i , y + j] = (0, 0, 0, 0)
            else:
                pixels[x, y] = (255, 0, 0, 0)
        picture.save("riverside-map.png", "PNG")
    
    if __name__ == "__main__":
    
        f = open("usb.pcap", "rb")
        pcap = dpkt.pcap.Reader(f)
        print_map(pcap, 5)
        f.close()
    

And when I run it on my usb.pcap I get this error:

    
    
     Traceback (most recent call last):
          File "test.py", line 39, in <module>
            print_map(pcap, n)
          File "test.py", line 31, in print_map
            pixels[x, y] = (255, 0, 0, 0)
      IndexError: image index out of range
    

Why it is happening?


Answer: Depending on the dataset in your usb.pcap file, you may need to adjust the
INIT_X and INIT_Y variables. The problem is that struct.unpack returns a
signed value, so if the data is over 127 then it appears negative and you are
exceeding the array boundaries. If the data is really always positive, you can
test for that and force it to a positive value. Something like:

    
    
    data = [item + 256 if item < 0 else item for item in data]
    

