Packet Editing Live Connections with Python

Remy
5 min readJan 21, 2019

--

When I was a kid I played a lot of a game called Runescape. For those of you unaware, this is a Massive Multiplayer Online Roleplaying Game built in Java by a company called Jaegx that was made to run on even the crappiest computers with dialup. The game has evolved since then, but still lives to this day. As with any online game, there were many “cheats”, which in this case would automate the highly repetitive (see: grindy) nature of the game. These were more often than not very simple scripts that would click the same location on the screen over and over again or they were simply just malware made by another player to steal your account credentials. I mention all of this because the one exception in the “cheats” was AutoRune (https://web.archive.org/web/20180216161417/http://www.kaitnieks.com/AutoRune/history/). AutoRune at a high level was a proxy that sat between the game client and the internet that did these repetitive tasks without clicking, but simply by editing and sending the very packets the game relied on. This incredible tool was used as leverage to manipulate the game itself, ultimately resulting in some legitimate cheats (note it isn’t in quotes now) such as spawning infinite amounts of items, killing NPC’s you usually shouldn’t be able to, and other tomfoolery. This naturally resulted in a massive ban-wave which didn’t kill the cheating community, but the likes of AutoRune at scale was never seen again.

I mention all of this because the acronym for this toolset I jokingly named DCAR (Decent Compared to AutoRune) a riff off of the basic scripting tool SCAR (Shit Compared to AutoRune) that succeeded the death of AutoRune itself. If 2 college students on dialup can edit packets, surely I can as well. How hard can it be?

DCAR, or the project outline below comes with the following disclaimers.

  1. Back up your installation and build the tool in a fresh Virtual Machine with nothing of value on it. You will be messing with the very communications the internet is built on and stuff WILL break. Assume that you can and will lose all progress at any given time (Virtual Machine snapshots highly recommended)
  2. Disconnect your Virtual Machine from the internet, your home network, etc… Seriously. Proceed at your own risk. Packets go where they’re told and do what they’re told to. I’ve mistakenly messed up a Windows Update, router reboots, restored my iPhone, and messed up my VM countless times. Take your sandbox seriously do not connect stuff you are not ready to lose.

Still here? Great! You’re in good company. That stuff doesn’t scare me either.

Getting started:

  1. Create a New Virtual Machine in VirtualBox (https://www.virtualbox.org/wiki/Downloads) with Ubuntu 18.04 (https://www.ubuntu.com/download/desktop). Minimal Installation is fine.
  2. git clone https://github.com/xen0bit/dcar.git
  3. ./setup.sh will load and install everything you need

Easy right?

There are existing tools that allow you to to manipulate packets (scapy https://scapy.net/). These are incredibly useful in their own right, but these tools seemed more aimed at creating and receiving packets. The path to editing packets didn’t seem straightforward with this toolset as I ran into problems with 2 different packets with the same sequence number, tons of TCP resets, etc… I needed to capture the packets in flight and modify them before my system even tried to look at them (the root cause of the 2 aforementioned problems). Enter NetFilter:

You’re gonna want to “View Large”

Using iptables we can route traffic into a NetFilterQueue at PREROUTING. As you can probably guess by the name, this is literally a queue of packets that kinda just sit there until programmatically released. Note: If you aren’t actively processing the queue and it fills up, all packets will be dropped. Combined with the NetFilterQueue Python Bindings (https://pypi.org/project/NetfilterQueue/) we can selectively accept/drop packets from this queue.

Since we now can hold the packets in a queue and move them in and out at will, now we need to look into modifying packets. Remember Scapy? It’s gonna be your friend in modifying packets

So now we can modify packets, What’s next?

FUZZING

Fuzzing is (paraphrasing) the concept of using algorithms or even purely random garbage input for programs and then looking to see what comes out the other side as a way of finding bugs. As part of the setup script, radamsa (https://gitlab.com/akihe/radamsa) should have been installed as a general purpose fuzzer. We can feed our packets into radamsa to get algorithmically generated mutations on our input. The fuzzed packet is then loaded into our script and has the necessary checksums recalculated before passing it along.

Putting it all together:

With /dcar as your current directory

  1. sudo su
  2. ./setup.sh
  • Installs all needed tools

2. ./shell/ramdisk.sh

  • Creates a mountable disk that resides entirely in RAM. This allows us to write the packets to disk for fuzzing without compromising as much on throughput read/write speed (Note: You only need to do this the first time, but there is no harm in doing it again)

3. ./shell/run.sh

  • Runs the Python script that listens to the queue

4. (In another terminal) ./shell/setip.sh

  • Sets iptables rules to route packets into the queue. In the example given this is packets from port 80, what HTTP typically runs on

You should now see packets that are coming from port 80 on the server side being fuzzed in the python window.

Packets from server port 80 (http) being fuzzed before/after

If we load a site that uses HTTP (port 80) such as https://www.httpvshttps.com/ we might see something like the following on a normal connection.

Normal (no editing)

But if we load the same page from our Virtual Machine (or in my case an iPhone I have connected to my VM) we see very obviously that we are successfully editing packets.

DCAR fuzzed packets

5. ./shell/resetip.sh

  • Flushes all iptables rules so that your queue does not fill up (all packets are dropped by default at that point)

6. CTRL+C in the python window to stop it from reading from the queue

This endeavor has been a great learning process for me over the past few months. Looking back, there are countless things I would have done differently, but hindsight is 20/20 and this implementation works (and handles 20mbps throughput!)

--

--

Remy

Insatiable cyber-security enthusiast with a knack for finding things. All thoughts are my own and are not representative of my employer, friends, or family.