Nitescu Lucian
Nitescu Lucian

Reputation: 285

USB mapping with python

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?

Upvotes: 5

Views: 922

Answers (2)

Teivaz
Teivaz

Reputation: 5675

As Steve Cohen noticed your data is unsigned byte in range -128...127 but if these are indexes of the array than most probably they should be unsigned.

Python's struct has format characters for most cases, use the right ones:

data = struct.unpack("BBBB", buf[-4:]) # tuple of four unsigned bytes

Upvotes: 0

Steve Cohen
Steve Cohen

Reputation: 712

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]

Upvotes: 3

Related Questions