Home > Visualization > Packet visualization with Python

Packet visualization with Python

September 13th, 2009 Leave a comment Go to comments

A long-time pet project of mine is decoding the network protocol of Valve Software’s “Source” game engine, used in Half-Life 2, Counter-Strike: Source, Team Fortress 2, and Left 4 Dead.  I’ve never made it very far, but it has led me down some interesting paths in reverse engineering, debugging, and visualization.  One example of the latter is this Python script I wrote to analyze a series of packets.  It creates an image in which each row represents a packet, and each pixel represents one byte of the packet.  The pixels range from black (for a value of 0×00) to bright green (0xFF).  I got the idea from Greg Conti in his interview on the Network Security Podcast.  Here’s what I did:

1) Start Counter-Strike: Source and connect to my server.

2) Use Wireshark to capture packets going from my machine to the server.  Filter out any extra packets captured, and save the capture to a file called “capture.pcap”.

3) With the Python Imaging Library and Scapy installed, run this script in the same directory as the capture file:

from scapy import *
from PIL import Image

capture = rdpcap('./capture.pcap')
imgHeight = len(capture)
imgWidth = 0
for pkt in capture:
 if(len(pkt.load) > imgWidth):
 imgWidth = len(pkt.load)

imgSize = imgWidth, imgHeight
print 'Image Size: ', imgSize

img = Image.new('RGB', imgSize, (255,255,255))
putpixel = img.im.putpixel

for i in range(0, imgHeight):
 for j in range(0, len(capture[i].load)):
 color = ord(capture[i].load[j])
 print 'Writing pixel', (j,i), 'with value:', color
 putpixel((j,i), (0, color, 0))

img.save('./result.png')

(This could be done more quickly in newer versions of the PIL, but for now I don’t care.)

The resulting image, saved as “result.png”:

Packet Visualization Result

As you can see, you have to zoom in to really see what’s going on.  Once you do, you can easily see some patterns.  For example, here’s the first 100 or so lines:

Packet Visualization 2

I put red rectangles around a couple of columns that correspond to 4-byte counters incrementing by 1.  You can see it by the long, steady gradient.  Orange rectangles highlight some columns that mostly stay constant.  The yellow box highlights two cycling values.

It’s interesting to see that a few of the rows seem out of place, going by the alignment of those constant values.  I have no idea why this is, but it’s interesting.

Going back to the original image, I can look for the things I was doing in-game during the packet capture.  During this portion, my character was running straight across the map:

packetviz3

The packets started carrying more data when I started running (in the image, the fat part corresponds to my running).  Since the data seems to be constant, I would venture to guess that the game transmits deltas in each packet (the equivalent of “I’ve moved a foot forward from my last position” in each packet).

The noisy part at the bottom was when I rotated my character 360 degrees (using the “+left” command in-game so as not to pollute the data with rotation around the other two axes):

q

This is really interesting.  I have no idea what to make of it, yet.

So that’s all I’ve got for now.  Hopefully this sort of thing will help me continue my quest to conquer the Source multiplayer network protocol.

Categories: Visualization
  1. September 13th, 2009 at 13:02 | #1

    Brad,

    This is very cool. Here are some random ideas/thoughts…

    - perhaps also try plotting a single bit per pixel (e.g. on or off)
    - maybe try incorporating the packet time stamp into the analysis by showing blank rows to indicate passage of time, you’ll be able to see what happens quickly
    and what happens slowly. (a log scale might be helpful here)
    - the similarities appearing in the columns probably indicate fields in the protocol
    - I’m assuming pkt.load extracts only the payloads, this is a great idea. The headers would only add extra clutter. That being said it might be worth checking that only a single source_ip:source_port and destination_ip:destination_port pair is in use. If packets are going to various ports it might be worth using wireshark to break these out into separate pcap files.
    - Similarly it might be worth using different colors to show inbound and outbound packets (e.g. green outbound, blue inbound, or something)
    - It may also be worth experimenting with color to highlight specific/interesting strings or byte sequences within the packets (perhaps some of these could be identified by viewing the hex in wireshark)
    - If you see payloads (or portions thereof) that look like white noise, that would indicate encryption or compression was in use)
    - It would be very helpful if you could correlate the individual lines with a text view that shows the printable ASCII and Hex of each payload so you can see what is going on. If this text view showed one packet per row in a monospace font I expect some of the fields would emerging in this view too.
    - If you could view the visualization in real time by capturing packets you could see how the protocol responds as you take different actions in the game.
    - It might be worth loading the file into rumint and experimenting with some of the views and its live packet capture.
    - Using your script you might build up a series of snapshots of what the different actions look like. e.g. rotating in different directions, firing a weapon, changing weapons, moving, etc. As this set of pictures grows I bet some interesting constants or variables will emerge.

    Anyway, just some random thoughts. Very cool stuff.

  2. Brad
    September 13th, 2009 at 17:47 | #2

    @Greg
    Thanks for the comments, Greg. Time isn’t really an issue in this case because I set the game and server at 10 updates/second. I did use filters in Wireshark to make sure I was only capturing game traffic, and this capture is only outbound. I also saved the inbound traffic from the server – I’ll have to see what that looks like.

    I’m a fan of Rumint. Of course it does many of these things, and it will probably inspire future analyses. I’ll also try out some of your suggestions here. It’ll be interesting to see if the one-bit-at-a-time pictures reveal anything that these pictures don’t.

  3. Mike
    March 11th, 2011 at 07:46 | #3

    Curious if you have ever tried to reverse the authentication and authorization protocol for the Steam client. I’m looking at doing some vuln research and bug hunting around that and wondered if you had any pointers.

  4. Brad
    March 11th, 2011 at 09:26 | #4

    I started to do that a few months ago, as a project for another website, but then I got distracted by shiny things and didn’t get back to it.

  1. November 3rd, 2012 at 23:25 | #1