 We have been working with Patrick which is here for about a year on reversing games and fuzzing games, online games particularly and before I start we have a bunch of questions for you guys. The first one would be how many of you ever play online games? Please raise your hand. All right. Some people don't. Okay. Don't expect that. How many of you ever thought of cheating? Come on. Don't be shy. Don't be shy. All right. How many of you really succeeded in doing that? All right. Well, so all of you probably ever one who tried to cheat at one game like Diablo 3 or League of Legends which will be the focus of the talk today, we realized quickly that it is very, very hard and when we started to do the presentation for this talk we had two options. The first option was well, how about doing a talk where we show you a bunch of attacks or a bunch of how we crash games and the second one was more into telling you how we did it. And we decided to take the later route because I've been doing a lot of fuzzing and a lot of reversing on games for the last three years. I have been cruising a bunch of forums and most of the thing I read is I know assembly code and I know C++. How do I do reversing games? And most of the skill set that you need to do that are not your standard reverse technique idea or skill set. So what we hope to you to get from this talk is ideas on how next time you want to test a game not for cheating of course but for intellectual satisfaction you have the right skill set, right? By the way, if you start cheating at Diablo 3 I would be super angry because I'm still playing it so please hold for a little while before you start doing that. Thank you. It's a very, very tough place and over the last year we met incredible people and before starting we want to acknowledge them because they did some of the work and we want to take credit for it. So we want to thank particularly Drew, Moises which did a lot of work on Diablo 3 and Incline 9 which did a lot of work on League of Legends and we are building on what they did and we helped them along the way and they helped us so it's really like they should be there together with us or at least here in spirit I guess. So why fuzzing online game is so hard? Well, interior is super simple. You have a server and you have a game and nothing special in it except a few things. First, well, you don't have the server. When you try to fuzz, let's say Apache or an FTP server you usually have the binary as a very least so you can actually instrument it, look how it works and you can relaunch it and stuff. When you are fuzzing games, you don't. You simply don't have the server. The server is something out of your reach, you don't know how it works, you don't know how it's run, on which platform it is run, it's completely obscure to you. And by the way, do not fuzz games server. Fuzzing game server is illegal and I have to put this disclaimer somewhere. Do not try to fuzz Diablo 3 server and never tell you to do that. Do not do that. You can maybe fuzz the client that may be legal. I'm not a lawyer but I'm pretty sure fuzzing server is illegal. The second thing is when you look at the protocol, over the time it became more and more complicated, I'm going to tell you more about the one about Diablo 3 and the one on League of Legends but most of them, maybe except FormVir, how very, very complex and encrypted and you don't really know what's inside so it's really hard to just fire up a sniper and just look at packet, won't give you much these days. You have to really work harder on that. And finally, well, games try to do the basic and to prevent you from debugging code so they have anti debugging techniques, they also have active security checks. The most well known would be the warden. I'm going to give you a few words on this in a few slides which is Blizzard active security checker and they're a very, very, very complex piece of code. You're looking at huge binary with a ton of DLR so if you just say, well, I'm going to just reverse it, let's pop up ADA or any type of analysis and you're going to fail because it's just too big. And then when you look at that, you are like this. That's actually my usual face which is like, oh, that hurts, it's really hard and you make no progress. When Patrick joined me like six months ago, he spent probably like two months doing zero progress. It's like very frustrating and we don't want you guys to feel the same so we try to give you a point of how to not be stuck. It's possible and most people are like this in the forum. I don't know what to do. How am I starting? What is the thing I should need to know? Well, friends, there is hope. It is possible to first game, it is possible to have results. You just have to be very creative and we really have to think out of the box and use some sort of technique that you might not feel like are linked to reverse but actually are really useful. And yes, I'm going to give you statistics and yes, we're going to do some mathematical analysis of packets because at some point, as you will see, there is no the way and it actually would be faster than just reverse the same. So what we really want you to take out from this talk is the new techniques or the techniques revamped to first games that we come across over the last year and then you can take them home and try to play with them and hopefully you will help a bunch of open source projects that are around games and a lot of good come out of that. So here is our master plan for today. We have the game, we have the server, so what we try to do usually is we try to be in between. We want to have our tool to actually intercept the traffic and be able to see the packets and there is here is our first twist is we also want our tool to correlate that with memory offsets. One of the things which is very powerful is when you combine network traffic with memory analysis because you know what packet affect which state and then you can write things like if I see this packet, what are the packet I see when this value comes up or which value comes down and so forth. So it's actually a very useful technique to combine both of them. So today we're going to show you four things. One is how do you intercept traffic, which is the first step. Then how you have to bypass encryption. So every game you use encryption so you have to do that before doing any works. Then how do you reverse the traffic? When you have decrypted your packets, how do you actually come up with a understanding of what it is? And then we finish by telling you a little bit of when you have the packet and you have the ability to first and you sort of know what you want to do, how you monitor the results on the client side. So intercepting traffic. There is mainly three ways for intercepting traffic. The first one is you take your game and you do something which is well known, which is GI injections. I'm speaking of Windows games. For Linux fans it's more like a LD preload where you try to overwrite a specific set of functions. The other one is you work at the OS level and where you have to write the driver or you use a VM, you put your game into the VM depending on how graphic intensive is your game, you might or might not be able to do that and then you write the driver which is going to intercept the packet before they leave the box and before they eat the router or the last way is to actually have the network or the IPI advisor and just use this interception after the packets leave the box. Okay. So hooking WinSocks. So most of the games in Windows use WinSocks which is a Windows socket API which is a standard way to send and receive packets. I have yet to see a game which doesn't use it. And basically there is a couple of functions that you want to basically overwrite. The first one is connect which allows you to manipulate where the game connects. The second one is receive for receiving packets and the third one is obviously sending packets. These are the three functions that you want to hook and there is two ways mainly to do that. The first one is to use Microsoft D2 libraries which is a way for you to write a DLR which says I want to intercept this, this, this and this and then it's going to inject a DLR into the game and you would have like a bypass to these functions. The other one if you don't want to use D2 and there is a lot of discussion for communities on what is the best way to do you can actually not use Microsoft D2 and use IAT hooking which is basically you write the table of the pointer directly by yourself and then they go into your function and then you return to the real functions. That's where things become harder when you do a game. If you do that on a browser like IE it works perfectly. If you do that on Diablo 3 you have to face a warden. So what is a warden? So a warden is the code name for Blizzard anti-chilling engine. It is meant basically to do three things. The first thing which we know most about is it really does certain offset in the memory. So it looks at different offset in the game and try to see if these offset have been modified in any ways. It also can the list of process you have run on your computer for known bots or known executable like debuggers, packet interceptor, sniper and so forth and report it to Blizzard and last thing it actually seems to be able to run blob of code. So basically sometimes it's fetch a blob of code and just run it and return the result to Blizzard. What it means for us is that if you use hooking you will get code. You will. There is like no, you might not be code right away because you might inject or hook a little bit differently that the receive or send function and you can be upper this function but sometimes it will figure this out and you get code because the wardens can for every time ways of injecting the allows. So the other options that we sort of work, we use for the last six months is write a driver. Two years ago we were starting to do use an LSP which was the old way to do it by Microsoft. There was actually a talk at DEF CON 15 on that. It's fun to tell you how old is like five or six years old. There is a new one we came out which is actually easier so if you want to look at doing that the easiest way to do is to use the Windows filter platform which make basically you can tell I want to intercept TCP connection or I want to intercept the stream on top of it and make it easier for you because it's going to re-sync TCP counter for you and so forth. So it's pretty good. The thing you have to be careful when you write the driver is actually the driver what you do is basically you stop the packets to go to the server and you re-enject them. The problem when you do that with the driver is your own packet are going to go back to your own driver so you have to tag them. It seems easy to explain. When you implement it it's sort of tricky and you might find weird bugs like having the same packet send twice to the server and so forth so you have to be careful. On a side note you can't really redirect IPs so I saw that a bunch of times in the forums people say well but what you can do is simply tell Diablo 3 to go and connect to your own IPs. There is like a common line option for that. The truth is it's used to work in beta. In release you can't do that. Basically the server send a packet a challenge packet to Diablo 3 with the IP of the server and if it actually doesn't match the release it has into a DLR which is downloaded every time you launch a game it's going to refuse to connect. So you actually have to the Diablo 3 has to believe that you connect to the right IP otherwise you can't actually launch a game. And some people will say well but I can hook this function. Well if you hook this function the world is going to catch you so you can't do that. You have to either remove the IP to a different box or you have to do the driver interceptions. So to summarize this part you can do the injection and it works fine on games which don't have like active checks like League of Legends. That's probably the current way of doing it for League of Legends. When you deal with games which are really really secure like Diablo 3 you have to do something more fancy. We use driver for a very good reason is as I said in my master plan I want to be able to read the game state. I want to be able to collect packets with what is happening in the memory and the only way for me to do that is to be on the same computer. I might be able to do it with a second box but I have to do socket and so forth and there will be some latency which might not be which might seem trickier. So our current approach what we recommend to do is actually use the driver and use the WPF way of doing it just like we did it. Encryptions. Let's start with the easy one. League of Legends. So League of Legends use bluffish. I have no idea why they choose bluffish which is slow but somehow someone they must have read that bluffish is great so they implemented bluffish. So League of Legends have two binary one which is the launcher where you find your game and then you click play and it launch the game. The interesting part of that is actually when you click on launch the key with a bluffish key appear in the command line. So they have some sort of encryption. Not a big deal. Let's go back to something way more complicated under Diablo 3. So you have the game and you have the batonnet server which is the first server you connect to. The first thing you're going to do is what is called SRP6 challenge which is basically a way for you to prove that you have the right login and password without transmitting it in clear. It's a six step protocol. I'm not going into details. If you look Google SRP6 you're going to find it. The basic idea is you hash your password with like a secret with an ounce and then you exchange that with some sort of Defianman crypto and basically the network attacker has no way to brute force your password. That's why it's pretty good. It's actually very, very the right way to do that. And when you have done that what you obtain is a secret key which is shared between the batonnet server and the game and change out every instance of the game of course. And then you use that to start TLS. So you do TLS PS key which is pressure at key so basically they start to do TLS instead of using certificate to exchange the keys actually use the keys they have used in SRP6. And when this is done and you say okay I can do all of this. You have the RSA challenge. And I'm going to explain you a little bit what is the RSA challenge is. And then after that you actually connect to a second server which is what we call the game server where the actual game occur. You know when you click play actually you are moving to another server. And no please do not put the key into the command line. Not this time. So why a RSA challenge? So TLS PS key is basically using SSL with a pressure key which is the one you exchange it during the SRP6 challenge. And it should be perfectly fine for us because well I know my password so I can recreate the SRP6 challenge on my interception mechanism. And so there is no way for Blizzard to know that it's an end-to-end connection so they use a RSA challenge so the client expect a message which is signed with the private key of Blizzard and if this is not showed by, if it's not valid then the game will refuse to launch again. It's actually located into the password DRL. So basically what happened is we don't know the key. We don't know the Blizzard private key and the game expect you to have this challenge signed by the private key of Blizzard otherwise it will refuse to launch. So it's a way for them to do authentications. And it's actually perfectly meant to be prevent for exactly what we want to do which is manage the middle attacks. So there is two ways to bypass the challenge. One is you're going to factor an RSA key which is as far as I can tell impossible or you're going to patch the game. But if you patch the game, you know what happened? The warden is going to go after you. Remember the warden we should look at the offset, they actually look at the offset of the key so if you try to change the key or change the task they're going to catch you. So that's probably what the happy face you make. And you're like okay that's become complicated so you start to thinking well maybe I can do put into debug mode swap on during the challenge and be very quick and remove the swap or might intercept the warden and I might actually trick the warden into not scanning the right offset. And then you look more and more and then you realize something really deep. Traffic to the game server is not encrypted. So when you realize that you're like yes I can't so you can't what's it mean is we can monitor the game by itself but we can't do for action auction a house protocol is encrypted. So if you want to basically try to first the auction and again it's illegal you might not be able to do that because these packets are encrypted so they protect your login, the character selection and the auction house. If you just want to be in the game like bashing monster and doing quest this is not encrypted so that's the part we focus with. So at that point we give up on managing everything and we just like let the game do all the authentication for itself and we pick up the connection after all this is done and we just give up on basically the auction so forth. All right. Reversing protocol. Here's what a Diablo 3 game packets look like. So they use TCP and on top of TCP they use RPC which is remote procedure calls so they send a lot of calls to the server say do this, do that, for instance I'm facing this, I'm going there and the server going to say play this animation or I'm going to kill this monster so basically you say I'm going to attack there and the server is going to send you back how much DPS you did because all the computation are done on the server side to prevent cheating again and then on top of that they use what we call Protobuf. Protobuf is a way to create nested protocol which is developed by Google, there is an open source implementation of that. The community has created a C sharp version of it so you have it for Python, C++, Java and C sharp currently available open source and if you want to know what a Diablo 3 packets look like this is a packet which is half reversed so you have this is an attack packet so when you attack packets this is what we have been able to isolate so you have something which is like an aim target message where you have three fields we believe it's actually five or six fields we don't know exactly how to split it yet and then you have the location where you want to eat which is like three coordinates which are at the bottom of the screen. This is the kind of stuff you're going to get and you can see it's a Protobuf because it has nested component and that's how they probably say they have like a bunch of components and you unlock them. On the other side League of Legends use something completely different they use UDP and on top of that they use INET which is a reliable connection on top of UDP. On top of that they have Bloffish and on top of that they have a new protocol which is a League of Legends protocol which is their own custom protocol which is the thing you care deeply about. So INET is just a way to multiplex. Basically the League of Legends packet format is something like this you have an OP code which tells you what the action is followed by an ID which is an integer, so little bits, little Indian and then followed by some content and then they are multiplexing across multiple channels and each channel have a set of flags so you usually have like four or five channels and one or two flags for this. Usually three is for sending information and one is for receiving information or something like that. And then you're like, at that point you feel pretty good. You're like, well okay now I'm, I know the protocol, I'm able to manipulate it, I'm happy, I did all the hard work right? It seems fair and from now it should be done here. Well, let's take some check. We recorded a game which lasted 21 minutes and in 21 minutes we get 60,000 packets. That's a lot of data as a process. And on average you get about 48 packets second so if you try to do that with a sniper, well you won't see anything. If you try to process that with a sniper, well it's going to take you a lot of time and we have isolated 78 different OP codes so there's also a lot of different packets. So if you want to grab that, you have some birth to up to 80% or 90 packets a second at some point and then it's very, very, very oscillating and it's not easy to do that with that. And then, well, yeah there is too much stuff to process. You can't just look at it and just figure out what it is because it's actually too much data. Well there is no searching as too much data. You know, having a lot of data is good because if we have a lot of data we can start to do something like statistical analysis and don't be afraid it's pretty easy to actually figure out a lot of things by themselves and then use that. So what I propose to do from there is first we're going to bucket which is basically split the traffic by OP code because we know that each OP code is sort of separated and then try to do some what I call differential analysis. I'm going to show you how it works. Then we're going to try to mutate this to do the fuzzing and then we can inject the code and just look at the data and see how it's going to work. So bucketing is very simple. All you do is you look at the OP code and you say well, if it's OP code A I'm going to put it into the bucket A and if it's B I'm going to put it into the bucket B and that's all there is to it. So it's not hard and it's going to be like four lines of Python or something. And then you have your bucket and then you can work on each of them in installations. When you have each bucket what you do is you take each packet and what you're going to do is you're going to do the first packet followed by the second packet and you're going to look at how many of them are differences in the same offset. So you're going to compare offset by offset which is column by column and you compare all of them. And for instance you can see that for the first offset the value is from two to nine. We have the range because the lowest one is zero two and the highest one is zero nine. And the second one hasn't moved so it's basically some sort of static field. Either an identifier or a split, a separator or something like that. And the third one is also separated. When you have that you have to do a second step where what you do is you do a differential analysis between traces. So you have one traces which might have this shape where the first offset is variable, the second one is fixed, the third one is fixed and then you for instance look for the second player trace and you compare those two. And what you can see from there is that of course the first offset have variations, the second one is fixed but actually the third one is also variable because it's probably the idea of the user or idea of the player so you can actually get more data. If you want all of this I put all the differential analysis on the League of Legends protocol into the Github. If you look for League of Legends in net line you're going to find them and I have all of them in public. And when you have that you can say well now I can first everything. So now what I'm going to do is I'm going to take every range and for each range I'm going to just you know just mutate all of those. Well, the problem is it looks like this. It's what we call the curse of dimensionality. If you try to have one bucket which change it's perfectly fine. If you have seven range which actually change, even if you try to do four mutation by range and combine all of those you're going to end up with millions and millions of packets. To give you an idea, when we started to generate all the fuzzing vectors for the League of Legends client and we only used three value which is minimum, maximum and median value. We ended up with 1.5 million packets. And the problem is League of Legends is very brittle, the client. So most of the time we actually crash the client. So and the problem is then you have to click on reload the game, reset the game and then click and then start. And even if you automate that with let's say auto it then you have to do it in super slow. So, well, you have to take it to the next level. It's not good enough. Even if you are to that point where you know what is fixed, what is not fixed and you're able to try to do all the fuzzing, you're not good enough. You need something better. So you can start with something very simple. You can look at frequency analysis. This is the plot. What you can see here is by opcode. And it's a logarithmic scale so the biggest bore are actually way higher than they look up here on the diagram. Some opcode are very, very frequent. There are mainly pings and update on location and stuff like that which are not really what you are interested in. On the other hand, there is a handful of code which are very, very, very rare. And these are the ones you actually care about. Why? Because the small stuff is usually the good stuff. For instance, when you do a level up, well, level up is not that often. You're not going to level up every second. So you might have like four or five of those into the trace. Same thing for buying items. You do not buy like 20 items or a million items. You buy maybe 10, 20 items so it's very, very low. And something for attacking. You do not attack that often. So there is very, very few packets. So if you discard all the stuff which is very, very frequently updated, then you end up with a small chunk of opcode which are more manageable to do. That been said, remember, it's an online game. So when you send a comment, you also want to know what the answer is linked to it. So the problem is with League of Legends that I said, there is multiple packets as they sort of multiplex each other. So it's actually hard to know which one is related to one another. So you need to actually do correlations between opcodes. For instance, when you have an attack trigger, you want to know what is the response from the server for that. Or when you assign a new skill, what you really want to know is, well, what is the server entering to me and how I can play with that. So to do that, you do something which is fairly standard, which is called ngram analysis. It's very, a big word for, and I'm going to show you a big word. It's actually a big word for something which is that simple. What you do is you take the, you only take the opcode and then you take the first packet and then the second packet and then you say, well, I see these two opcodes one after the other one time. And then you move and you say, well, I see these two opcodes one after the other one time and the fourth. And at the end, if you repeat across all the trace, you're going to get some of them which are more frequent than the other. And it's going to get actually rid of the noise. So if you actually trigger something multiple times, it's likely that at some point, the answer and the response which are related are going to appear close together more often than the other. I'm simplifying a little bit because you need to be a little bit more fuzzy, but that's the essence of this. And there is one gotcha with that. If you try to do that, do not try to keep high frequency packets into it because you have some packets which are like 10 times a second, so they're going to mess up your analysis, so you need to actually get rid of all the high frequency packets before inserting it into it. So let me give you a concrete example. So far we've been doing a lot of hand waving. Here's a League of Legend set skill packet. So every time you gain a level, you have the ability to select a skill and say I want to increase this skill or this skill or this skill. What you actually do is we pull out the trace for you. And in blue there is the opcode 3E, and then you have 1B, 1C, 1A, 1B which is the second column which is basically the player ID. How we know that, we know that because if you look at one trace it's fixed. If you look at multiple trace with multiple players, it's actually become viable so we know it's actually linked to the player. And then at the end you have 0, 0, 2, 0, 3, 0, et cetera. It's actually called from 0, 0 to 0, 5. And then we took a deeper look at that by basically clicking on one of the slots and then looking at what packet we got by playing the game and looking at the output at the same time. And it's actually the slot position. So what the packet says is I want to put the player ID X, I want to put one more point to this slot. And then you need the answer, right? And so we did this frequency analysis and then gram and we get the answer and the answer is 18. And so 18 is the same thing. You have the player ID. Followed by the slot position you actually said and then the server tell you how much you have. Right? So basically it tells you well for slot position 1, which is 0, 0, you get a skill between 0, 1 and 0, 6, which is the maximum you can get for a given skill. And you look at that and you're like, mm-hmm, is there a bug? Yes? No, maybe? Yes. It seems to be there is a bug where you're like, well, if the server send me how much power I can get for a given slot, what will happen if I rewrite 0, 1 to let's say 0, 6? So I get like, I said I'm going to assign one point and then I stop the packet from the server and I say, well, no, in reality you don't get one more point, you get like six more points. It sort of work in a sense that your client is going to believe that you actually have six. So your client is going to believe what the server say and it's going to say yes, you have a spell level six. But when you try to use it, it won't work because actually the server keep tab of how much DPS you do. So actually even you can pretend to have the skill, but it's actually not going to do anything because they do the computation on the server. I don't know when they fixed it, but it's fixed. All right. Another way to do it, we found very useful is binding a specific set of keystroke to our keyboard before we're doing an action. So we actually say we usually use control X. And so we press control X just before we want to, the action we're interested in and then our software actually add to the trace or a click event into the trace. And after that what we do is we usually look at the end few packet after that. So it's actually helping basically and transmitting the game and looking at the trace at the same time, putting the click at that point is actually help us to isolate the packet we want to look at. If you don't want to do all the different analysis and stuff, the easiest way is just to record a specific one and say well I want you to know what are the packets from this particular point in time and then you can actually look at only these packets. Again, what we want to come across is don't try to reverse the entire protocol because most of the protocol port are sort of independent. Just try to focus on the one you are really interested in, like attacking or setting an item or removing an item and then just look at those packets and if you look at enough of those packets you're going to find a recurrence and then with this you can actually figure out how the protocol works. And then for the next part I'm going to let Patrick tell you a little bit more how we monitor the results. Okay, so what about monitoring the results? Remember the bigger picture is to build a fuzzer so we kind of need some way to automate the monitoring of the results so that we can build some scripts for example that is going to check whether or not we succeeded. So how do I do that? As my packet affected the game state. To do that we need to read the state of the game. We have a couple of ways to do that. The first one is to read the game memory. So we are going to inject a packet and then we need to find the memory offsets of the potential value that is going to be affected. And this value will give us an idea of how we succeeded in changing the state of the game. For example if we take the health of the player of the number of gold pieces we can say that I have 10 gold and now I'm going to buy an item and I have 11 gold. So did my injection work? Now how can I find the offset in the memory? The idea is to start with the complete armor for example and take a whole snapshot of the memory. Then you remove one piece of armor and you do the same thing. You filter all the values that didn't change and you keep the good stuff. And then you do it again. You change another piece of armor and you take another snapshot and filter the values. And again and again. And at the end it's likely that you will find the relevant value in a couple of iterations. What if the offset is encrypted or if you're skating? Usually not all the structure is encrypted. It's only the interesting values. So you need to find a field in the structure for example the player structure that is not encrypted. The idea is for instance in Diablo 3. The gold value is not encrypted in the player structure. So it's actually a float. So you can find this value and then climb up or down in the structure to find the health value. And then you get the offset in the structure and you can get the actual memory address. Another option would be to do more set and unset on the value until you get only one value. But this can take a lot of time and a lot of iterations. If it's obfuscated the thing that you can do is just look for a value that changes or do not changes and try to extract what is important for you. And then find out how it's obfuscated. Okay so that's it for the game analysis J.O. Thank you for coming. And you can follow us on Twitter or gplus.