Archive for March, 2008
Sniffing World of Warcraft
Update2: Blizzard fixed there encryption, a plain text attack will no longer work. MITM should. See comments for details.
Update: Please see in the comments for discussion and some sample code. Please don’t ask for more.
This is an analysis of the World of Warcraft network protocol. It is based on work I did to create a bot for World of Warcraft about 12 months ago. The bot was still working when I stopped playing World of Warcraft shortly after the release of The Burning Crusade. I have decided against releasing the bot and its source code in light of recent events.
While I don’t think anyone could successfully sue me if I released the bot I couldn’t handle the stress if they did.
Whether or not the techniques described in this article still work I do not know. I would say they do.
First I will describe the architecture of my bot and how it differs from the likes of glider and other bots out there. The game stores in memory all the objects the player encounters in the game as well as the players location / health etc. Most bots work by trying to hook into the Warcraft process on windows and read out information about the world from the games memory. Key presses are sent to the game window to control the character.
The major flaw however is Warden. Warden is a process that runs when you start World of Warcraft and attempts to detect these sorts of hacks. It has been quite successful and it is a constant cat and mouse game between Blizzard and the bot developers.
My Bot is structured a little differently instead of looking in the games memory I decode the network protocol on the wire as WOW talks to the game server. My bot is separated into two parts. Watcher and Actor.
Watcher holds all the logic for the bot. It builds up an in memory representation of all the objects in the game and then runs a simple state machine to determine what the bot should do next. It also has a GUI designed in QT4 that shows a radar of the player with different coloured arrows for all the NPC’s and players running around. Since this program was only used by me it was hard coded with horde as blue and alliance as red. I was a horde player
I actually used the radar more then the bot. The bot grew out of the radar project.
In Watcher it is also possible to view all chat messages in Watcher, including chat messages from the other faction. Interestingly the other factions chat messages are sent down to the client in plain text and the client garbles them. I spent many nights in world PVP reading my enemies plans and finding where they were hiding using this tool J
The beauty is that watcher can run on a different machine on your network. You could even run Watcher on a gateway machine somewhere on the internet and watch a radar of a player who’s traffic passes by. Watcher on its own is impossible for Blizzard to detect.
The second part of the bot is called Actor. It is a simple daemon that runs on the machine with WOW. It listens on an arbitrary udp port for messages from Watcher and uses some low level windows api’s to press keys on the keyboard. It is a very simple design and EASILY detectable by Blizzard.
As a sole user of Actor they would never detect me but if this was released main stream the Warden would detect it with no problem. Actor wasn’t designed to be stealthy however it was meant to be as simple as possible. The trick would be for everyone to be able to implement their own “Actor” daemon because it is so simple. Overnight you could have hundreds of them, they could be embedded in mIRC scripts or firefox addons whatever you want. That would truly be hard for Warden to detect.
Now I will describe the process I used to create Watcher.
Watcher runs on Linux and Windows. I developed it on Linux and later ported it to windows. I used the libPCAP library www.tcpdump.org for packet sniffing.
The first challenge was sniffing all the packets. My Linux development machine was set up as the default route from my windows machine and I got to work. This was a great learning experience for me in the intricacies of the TCP/IP protocol. The packet capture library would just throw you a raw IP packet.
From there you need to split up the IP header, the TCP header and the payload. You need the source and destination numbers from the IP header and you need the sequence numbers from the TCP header. Under Linux the packets always came in order. When I later ported Watcher to Windows the packets were frequently out of order so I had to follow the sequence numbers correctly. This meant putting every packet into a queue and releasing the payloads to the decryption module complete and in the correct order.
At this stage I had a simple hex dump of every packet as it went past. All to the terminal with a different colour for incoming and outgoing packets. Nothing I couldn’t get from an off the shelf sniffing program but I was on my way.
I then browsed to http://www.mangosproject.org and downloaded the source code. Mangos is a World of Warcraft server emulator. They must get the credit for a lot of my work because it was them that worked out the majority of the protocol. I learned from reading that site that only the first bytes in every message are encrypted. I also learned that in the first few bytes is the length of the message and the type of the message.
When your client connects to WOW it goes through a fairly complicated handshake to come up with an agreed session key. It looks like some sort of PKI procedure I didn’t look too far into the handshake because there is such an obvious flaw in the encryption. The session key is used over and over again and only XOR’ED with the first few bytes of the message.
What’s in the first few bytes? The length of the message! 90% of the time the length of the message can be determined because if fits inside a single TCP packet.
That means you can determine 2 bytes of the plain text + 2 bytes of the cipher text = 2 bytes of the session key with > 90% accuracy on every packet that comes in. You can simply repeat this until you get the same session key twice and you are pretty much guaranteed to have the session key. Generally Watcher can fetch the session key before you have finished logging in.
I do this on messages coming from the server to the client. Once that is done I just need to determine where in the session key the client is up to. I wait for a PING packet from the server and know that the next packet from the client is a reply. I then simply apply the session key to the REPLY packet shifting it along 1 byte until it decodes correctly. I can then cleanly decrypt every message.
Using the tables from Mangos http://www.mangosproject.org I could determine every message type. The first thing I noticed was all the other factions chat messages! They are all in plain text.
Decrypting the packets was the easy part however the hard was decoding the object update messages. When you walk into a large area like Undercity your client receives a huge message as hundreds of items come into your view. These are all bundled in one message. The difficulty in reading this message is that every object type has a different length. All the objects are just in a long sequence with nothing telling you when one ends and another begins. If you can’t work out how long a certain type of object is then you fall out of sync and miss all the rest of the objects in that message.
This is something not fully covered in Mangos. You see if Mangos doesn’t handle bats it doesn’t have to, it’s sending out the update messages. If however I get a message updating 100 items and item 2 is a bat flying through the air I need to almost fully understand the structure of that object. For example byte 50 might be the number of waypoints, byte 70 onwards might be a list of those waypoints. Depending on a flag earlier on in the message those waypoints may either be described in 10 bytes each or 12 bytes each. If I can’t work out the exact length of that object then I miss out on the other 98 objects in the same message as it’s very hard to determine where one message ends and the next begins.
I probably spent the majority of my time on the bot working on this problem. I would spend countless nights walking across Undercity, debugging all the errors and starting again. Gradually I could walk most of the way across the city without an error. After that I got it down to multiple trips around Undercity with only the occasional error message every 4th or 5th crossing. The hardest objects to decode are the players. The length changes depending on so many factors.
During this debugging I made the GUI it QT4. Using a CGraphicsScene I think it was I had a nice radar up of all the objects on the screen represented by little arrows based on the direction they were facing. Alliance players were in red. It was awesome running through the world and noticing a little red dot hiding behind a tree or over a hill. It was also cool to read all the Alliance players abuse me over their general chat after I PK’ed them. HeHe
Finally I wrote the bot portion of watcher. It was a fairly simple state machine. It just walked around killing mobs in a certain level range. It got fairly complicated before I stopped playing WOW. It was totally un flexible and hard coded in C++ though. It required my class, my key bindings and my level of character. It was still smart enough to war stomp multiple enemies, frost shock difficult enemies, run away and navigate past alliance players. It killed quite a few alliance noobs that tried to pk me thinking I was afk
I will post some screen shots of watcher in action if i can find any.
61 comments 31 March, 2008
Why can’t we work out this whole booting your computer thing?
Think about it,
Windows Vista or a modern Linux desktop machine takes ages to boot up and its doing the same thing every time. Why do we need to go through the same start up code, driver loading and service starting every single time we start a machine?
We have got hibernation worked out ( at least in the windows world ) .
Why don’t we save an image to disk when the Window Vista desktop is up. You probably have at most 512MB in RAM then. It would be so quick to just write that to disk and always boot from that image.
You then trigger an out of hibernation event like normal. All of the drivers now can handle hibernation anyway.
Writing 512MB of continious disk into RAM would take no time. That would make book up like < 10secs.
If there is a change in Services / Startup programs / Device manager trigger a new start up. We shouldn’t be running the same code on billions of computers every single day it’s stupid.
4 comments 30 March, 2008
Something doesn’t add up here
Kevin Rudd on murdering protestors:
“These most recent developments in Tibet are disturbing and from my point of view, I would call upon the Chinese authorities to exercise restraint”
Kevin Rudd on killing whales:
I don’t have a magic wand, but the Australian Government will do everything within our power to put pressure on the Japanese government to bring this slaughter to an end.
I think Kevin might be a bit dyslexic and is mixing his sentences up.
Add comment 19 March, 2008
Brendan Nelson Hyprocrecy
Here is Brendon Nelson arguing that the Baby bonus his government instituted shouldn’t be given directly to aboriginal families.
Baby Bonus ‘like human tornado’
“I don’t care if I’m accused of being patronising.”
“When you have four or five thousand dollars turn up into an impoverished community which is dysfunctional in every way, shape and form, it has a devastating impact.”
What a fucking hypocrite. The biggest criticism of ALL of the Howard governments one off payments was that people would spend all the money on shit and not on the children. People going out and buying plasma TV’s and finishing off their extensions.
Beasley came out and suggested the payments be spread out over time and he was slammed by Brendon Nelsons government for patronising voters and treating them like children who can’t control their own money.
So it’s only OK to treat aboriginal parents like children then is it?
Add comment 18 March, 2008
Exciting Code
I used to work on poker machine games. It’s was very exciting working in an embedded environment as it’s was so simple to step through the nitty gritty details of how the system worked.
The operating system, the drivers, the backend and the actual game are all compiled into a single binary image and written to a ROM.
Running the machine through a debugger you could freely step in and out of the operating system. It was great to step out of your drawing routine into the graphics driver as it refreshed the screen.
You could step through the sound driver as it copied blocks of wave data across the pci bus. Or step through the assembly that flashed the lights on the box.
It was awsome trying to debug really complicated problems, watching the CPU registers to debug a rare crash that ended up being caused by a few byte stack overflow.
Exciting for me, Whatever floats your boat though right?
Add comment 14 March, 2008
Mapping Data
Mapping Data is such a painful process in Software.
I have a html form with 30 or so fields. A php script reads the form and puts it into a database. A C# program running as a scheduled task then takes the rows from the database and using the a COM API loads them into a financial system.
Through all these steps I have to spend so much time mapping out these fields. I give them all the same name but its still,
form variable = database column
php variable = form posted variable
database column = php variable
C# variable = database column
Financial System variable = C# variable.
The problem is that I’m crossing so many language / system boundaries. I wish everything just accepted XML. I could just do a simple transform and be done.
Add comment 14 March, 2008
Changing The World
Had a post in my drafts about changing the world. Basically saying why bother? Like voting it’s only really an illusion that you can make a difference.
I won’t post that draft, I deleted it but I should be changing the world. Why am I wasting my time doing IT. I like to think I have a bit of talent.

4 comments 12 March, 2008
Web 2.0
Besides web 2.0 being mainly just a bunch of pastel bullshit a lot of good apps are now online.
Personally I like the old way.
I like to have my applications running locally.
I like to control my personal information.
I like my data stored in my own home with sub millisecond seek times.
I like the tight integration a desktop app has with my desktop.
I don’t like having to open firefox for every little thing I want to do.
I hate when google locks me out of my google account for maintenence and I basically can’t operate as they have all my data and most of my programs.
Most of these problems can’t be easily solved. As things move into the “cloud” as they seem to be doing you can’t help loosing control of your information.
I do however see the desktop integration problem being partly solved by this widget / plasmoid / dashboard phenomenon.
I can’t speak for Vista but Plasma in KDE has taken the dashboard concept like in OSX and moved it from being a throw away thing that you occasionally use to the basis of their desktop.
Having Twitter and RSS widgets sitting behind my windows is awsome.
Add comment 6 March, 2008
Wow
It doesn’t just look awsome.
An interface is considered user friendly if it is intuitive, a computer desktop is intuitive because we can associate it with things in real life that we are familiar with. Files, Folders and desktops are all real things that are used to make a computer interface intuitive.
Unfortunately Windows has been dominant for so long that Windows is now so familiar that you need to copy windows to make an intuitive desktop.
Sitting down at a KDE desktop you might not find it user friendly or intutive. I guarantee that is not the case. If you took someone that had never used a computer before and sat them down at a KDE desktop I guarantee they would find it extremely intuitive.
The usability is just awesome.
One small example. I needed to burn a cd image in windows. Not an uncommon task. Downloaded an iso then what? I am presented with a few options. Pirate some software, Buy something that burns CD’s or go through 10 demos until I find some adware laden piece of junk that only burns 300mb at a time.
Linux, right click the iso, select burn.
Lets look at drivers. New install of windows. Need drivers for graphics card, sound card, wireless card, motherboard chipset, sata controller, the list goes on. I need visit each manufacturers site, download and install a driver, each with its own setup program.
The linux approach is a kernel upgrade. Seems pretty extreme but i think thats because your used to the Windows way.
A kernel upgrade on most binary distros can be done with one command. You tell me which is more user friendly.
Add comment 5 March, 2008