 I'm Rob and this is if you give a mouse a microchip it will execute a payload and cheat at your high stakes video game tournament. And this is going to be a talk about video games, a little bit of hardware hacking, a little bit of vulnerability research and a lot of trying it out at home. Can't do that either. All right. So, brief history of competitive gaming. 1958, kind of the first video game. You know, you're kind of precursor to Pong or Breakout. 1972 is the first recorded sponsored video game tournament. It was a game called Space War built in the 1960s. And that was a like five or six player game, competitive, had to run on gigantic lab computers. And Rolling Stones sponsored a Space War Olympics in 72. The prize for which was a subscription to Rolling Stone, which I assume was worth more back then than it is now. This is a picture from last year at the International, which is a Dota 2 tournament. And the International 2016 had teams from all over the entire world. It had a $20 million prize pool. 19 million of itch was crowdfunded by fans of the game buying in-game cosmetics, in-game items. 17,000 people were watching that game at the venue live. And over 5 million people were concurrently watching the finals online for the grand finals. So over 40 years, Esports has gotten a little bit bigger. And you can kind of see that, you know, there's some money riding on it now. So Esports events have some kind of unique security challenges. You've got these massive temporary networks that have been set up in a matter of days, maybe weeks if you're lucky. And they might only be used for three or four days. And, you know, you're setting them up in convention centers or in sports arenas. You've got up to 100 or 200 computers or, you know, other gaming systems being plugged into them potentially. And you've got hot seed computers. So, you know, you'll have stage computers that are set up and some teams will play on them and then they'll get off stage the next set of teams will plan on. And you're going to have all these different people using these machines or the course of the day or the weekend. These computers generally require internet connectivity because pretty much every popular game nowadays has to phone homes that, you know, they're making sure you're not playing on your own private servers or, you know, doing anything illegal. And most of these tournaments require you to support player-owned peripherals. You know, everyone brings their own mouse, everyone brings their keyboard, they're familiar with their devices. You know, they like how they work. Or oftentimes they have an obligation to use their sponsor branded devices as well. Computers at these events typically close a lot of kind of obvious attack vectors. You have internet access restricted so you can't go to csgocheats.com and download some EXCs, right? Player accounts don't have admin, that's kind of a gimme. Drivers and configs are often pre-installed. A lot of times you'll have hot swappable SSDs and every player has, you know, a storage device associated with them so when they plug into a computer, all of their drivers and set up and, you know, everything's all good to go. USB mass storage is disabled so you can't run your executables off of a thumb drive you sneak in there. And extra USB ports are disabled, often in the BIOS and sometimes even by dumping some epoxy in there. But again, these players are able to plug their own mouse and keyboard into the computer. So I decided to hack with a mouse. Uh, why? I found a mouse with what I considered to be an overpowered microcontroller. Uh, and then I found out more recently that a whole bunch of different mice from a wide variety of manufacturers are using the same family of microcontrollers that has a whole, you know, bunch of extra capabilities that they're not really needing. And I, you know, anecdotally, I think there's not really enough scrutiny over devices at these eSports tournaments just from what I've observed. Oh, we're missing an image. Alright. So I have a gaming mouse with a STMicro STMF32F103CB microcontroller. Uh, it's an ARM Cortex M3 processor. It supports their, uh, STLink programming interface just to build every program it easily. It has 128K of flash memory. That's, that's a lot of space. And I'm hoping that there's some space in there for me to add some additional code. Uh, it's got lots of buttons. It's got RGB LEDs, you know. Make the kids buy it. So the goal here is to connect to the microcontroller that's built into this mouse. Insert some code that acts as a USB keyboard. And when you plug the mouse in, sends a whole bunch of keystrokes to, you know, create and then execute a payload on the target computer. Unplug itself and run the original mouse code. And like the point here is, you know, I show up to this eSports tournament, I got my mouse and my keyboard. If I plug the mouse in and it does, you know, whatever, and then doesn't work after that, well now I don't have a mouse. And if I show up there and I plug a mouse in and I look around real sneakily, and then I unplug that mouse and I throw it away and I plug another mouse in, also kind of obvious. So we want to be able to like, hide our, you know, code injection in the mouse and still be able to use the mouse afterwards so it's, you know, less obvious. So record scratch, isn't that just a rubber ducky in a mouse? Yes, it is. One of the takeaways of this presentation is that all USB devices have microcontrollers in them and whether it's like an 8 kilobyte pick microcontroller or a 1 megabyte, you know, arm super over power microcontroller, any USB device can, you know, someone can open it up, attach to that microcontroller and really replace the code that's on it with anything they want. So these are the hardware tools we used if you want to try this at home. There's the ST Micro Discovery Development Board, which is, it has both an onboard arm processor that you can use to like, initially test and develop your code, whatever you want to do with it. And it also has some jumpers that you can disconnect that let you program any external arm devices. So it can be used both for development and for attaching to your target device. And one of the most convenient things about these boards is that they cost like 10 or 15 bucks. So there is a very low barrier to entry to doing this kind of thing. And then you need a mouse, you know, with an arm cortex processor or whatever else you're targeting. You need a saturing iron. You need some wires. Software tools, these are all free. ST Micro made the processor we were looking at so we just basically used their whole suite of free utilities. And then, you know, we got into obj dump at the end because we needed to be able to look inside the binaries and we didn't have the money for IDA. Sponsor us. All right, so we opened this mouse up and we see a microcontroller. It's pretty small. You've got a mouse wheel there for size. We need to talk to this microcontroller somehow. So we're going to go to the documentation. We're going to find this eye chart that you see on the right and it's got, you know, a whole bunch of teeny tiny text on it and you look through it with a magnifying glass and you find out that for the SD-Lang programming interface you need pin 14 for clock, pin 13 for digital, like data in and out, and the ground pin. And then you get really excited and you've had a couple beers and you're like, I'm a really good solder and, you know, I used to do this in college and I had a microscope back then and really good equipment and now I have this little like thing that doesn't even melt the solder. But you're like, I'll do it anyways. And you get this. Those pins are real screwed up. And this was the first mouse we lost. So then I flipped the board over and I found solder pads for ground, clock, and data. Which are the exact pins I needed, right? So the takeaway here is if you spend 30 seconds to look at both sides, right, you can avoid nuking a 60, 80 dollar mouse. So we're onto the second piece of hardware and we've got our wires connected and we're doing a lot better. This slide is more to help you along if you're following at home. This just describes the pins on the development board that you need to connect to the pins we just soldered from the mouse. So you can look at that if you want to recreate it. This is that discovery board. We've got this SD-Lang connection jumper. You pop those two jumpers off, plug your wires into the mouse. This is our required hacking picture where we have wires exploding all over the pace and some exposed circuit boards. Every presentation has to have one of these. Oh, and my highly technical insulating scotch tape because I didn't have electrical tape on hand. So we're attached to the mouse. It's plugged into our programming interface. We plug it in and it's still doing mouse things because the manufacturer, very smartly disabled things like debug and reprogramming when it's plugged in and out in production. So good job. That was awesome. But we have physical access to this thing. We've opened it up. We've read the manual so we know how to get it into a programmable mode. So this was a little bit trickier because there weren't any convenient pads for this. So using one strand of stranded core wire, I've applied three volts to the boot zero pin which there's an arrow pointing towards it and ended up actually smoking another mouse doing this because we shorted it out to another voltage line on the processor. It's a little tricky. But on the third mouse, we finally connected to the micro controller and this is the SD link utility. You can see we're getting a bunch of hex information in the memory there and we're in. If we want to keep the mouse working and we want to add code to it, we probably want to save this original set of firmware that's running on it. If we just pull this off and modify it and screw it up, we're going to have to go buy a fifth mouse and I'm running out of a, my mouse budget is drying up. So we're going to extract this original mouse binary. We're going to build an application that registers as a keyboard, dumps a whole bunch of text on the computer, saves it and then you know executes that program and we're going to find empty space in the mouse's binary and insert our application. And we're kind of just hand waving through that whole code dumping software because it would be really boring to explain to you how to just write ARM code. So we're just going to go through the interesting parts of the hack instead. Alright, so once we're connected we're going to open up Notepad. We're going to type out an encoded PowerShell script which is going to decompress itself, fork and execute in the background. And then it's just going to delete itself after forking because you know we don't want to leave any traces, right? So what the mouse itself is going to do is save that to temp hack dot bat and that's because generally speaking as a user we can usually write to temp or somewhere along those lines. We're going to close Notepad and then we're going to run that temp hack dot bat. I think it really speaks to Mark and I's friendship that when I was writing this hack overall, so first off there's this base 64 encoded like PowerShell script and then even beyond that I actually wrote a little hexer Python script that would convert it to hex that he just dumped into a care buffer in the code itself and then just you know trusted to run that. So kudos for trust. And so this is basically a slide if you're following along at home on basically the syntax to use for obj dump to essentially adjust things and get it to basically output in the right form. And so what we're really looking for here is a nice big spot of like just tons of zeros to put our code in. And so it looks like we found that. So this is going to get a little dry for a couple seconds here but this is kind of the important information you need to know if you want to build an ARM application at an offset in that ARM processor because they expect to start at the beginning and that's not going to work for us. So there's this uh since we've found a whole bunch of zeros at address you know 10A00 in that binary we think hey that's probably a good place to put our code so we need to edit some files to link and so that you know the software knows and compiles for that location. In this flash dot ld file there's actually two important things that we found uh it defines the size of the stack here and ARM stack is subtractive so that's both like the starting point and the size. When we were looking at the binary from the mouse we noticed that it had a very small stack uh like a 70 and all the software we were building had a stack size of like 5000. Much larger. And when we tried to run our code with that default small stack size from the mouse it just completely didn't work we needed way more space. So that's one of the values that we had to modify. Uh the other thing is that you know just specifying the flash memory area instead of starting at address 8 million it starts at address 8 million 10A00. And then over in the system dot c file we're defining the vector table offset for that same starting point because there's a vector table at the beginning of your ARM program and that's uh important. So the ARM boot process uh by default address 8 million contains this vector table that I just mentioned. The very first piece of data stored there is the location of the stack pointer in RAM. Again it's subtractive so it's basically like the size and the location all in one. And then at address 4 is the location of the entry point of your program. So that processor gets power it sets the stack pointer and then it immediately branches to the address at that offset 04. And then on the right there's this little gotcha for ARM programming. Uh if you're doing any branch operation you have to have bit 0 be a 1 or else a little hard fault on you and it's just telling the processor some internal uh execution mode. So how do we execute our code? We'll patch the vector table. To get the mouse to run our application we need to find the entry point of the code that we built and fortunately we uh set our. So we have to do this obj dump again do it at the memory offset of you know where we're running our code out of and then we just look at the beginning of that file and we can see that you know our code's entry point is 8013625. So we're going to patch the values at 00 and 04 and that binary we extracted from the mouse with these new values. So on the left and this uh SD link utility we've got that you know 2 million a 70 and the 8 million 141 and then we just updated those two memory locations for our new code. And now we need to add it to the binary so using your hex editor of choice navigate to that offset in the code where hopefully all those zeros are and use the elite hacker tool copy paste to add all of your code into that into that binary. So the mouse should now run our application and it did but it didn't do anything else. So I plugged it in I got this whole keyboard dumping thing it you know typed out my program saved it and executed. I gave myself a whole bunch of high fives uh but then it just sits there and it's a dumb brick afterwards. So we need to make it return to the original functionality. And this is where I called my buddy Rob and he gave me a whole bunch of help here. So overall um the really cool thing is you can actually turn basically any device into a rubber duck using the process that we just described using nothing but C code. So now the cool thing is to be able to do this kind of stuff and retain the original functionality of whatever device you're using. And so income some sneaky assembly usage where we essentially need to save the state of the mouse kind of as it was before. So this is uh a picture of how the entire memory of the mouse essentially looks like. And so like from the vector table down to the mouse entry and the mouse and the hack main. And the hack end and the hack entry and then below that's a little bit of our own little data that we inserted there. So all of this is basically just going um everything in red is essentially in main at that point. And so the control flow is the vector table is gonna kick us off and it's gonna hit the hack entry which is then gonna call into hack main and then once we're done executing our payload we're actually just gonna fall through to the end of the you know just into the like last assembly that's there which then calls into the mouse entry point which then runs the mouse. Or in your case if you are doing any other like device that you want to use it would be that instead. So this is just um some of the assembly for what's going on in kind of each of these pieces. So this first part is now our new entry point. So when we patch the vector table this is the first thing we do. So one of the things we need to save is the address of the stack pointer um that the boot loader gave to us to start with. And we also need to push any of the registers that the boot loader might have set up for us that the mouse is going to need. So for any of you that have ever like written a packer or done any hot patching this is kind of how you make sure you don't mess up the state of the thing itself. Finally we're gonna load our hack entry into R0 and go ahead and branch. So now after our applications run and we've done everything bad that we want to do we're gonna fall through here to this jump to mouse code and essentially this is just gonna restore everything back the way it was. So essentially putting the stack pointer back um restoring the registers loading the desired stack size that the mouse originally wanted because we had different stack sizes and then setting the stack pointer going ahead and loading back to you know back in R0 the entry point of the mouse itself and then branching to the original mouse code. And then this is a slide that just basically describes the data that kind of follows after that. These are all of our offsets and other things that we put in there. Um the really cool thing about when you do inline assembly in C is you can actually use labels they're really helpful and they save you a lot of time. And then oh sorry and at the very end we put feed beef which is just some breadcrumbs because it gets really annoying to find your code over and over again. So this was just to find it very quickly and it'll save you some time. So now we thought that we had you know everything good and ready to go. We had you know this whole control flow where we power on we execute our code. We restore the processor state to its original you know initialized area. We branch back to the mouse code and we have a mouse. Unfortunately what actually happened is we plug it in it runs our code. It you know our USB hardware input device stops. It goes to the mouses. We like see the mouse initialization happen and then it faults somewhere and my code tries to initialize again and we were just getting in this like infinite reset loop on this mouse where it was initializing and initializing and initializing and initializing. And one of the more difficult things about this like I mentioned was that when the mouse code initialized all of the debugging was disabled. So I didn't have any insight as to what was happening and like you know it was basically a black box that just kept turning on and turning off and turning on and turning off. So I'm thinking like how can I fix this? You know I don't have any information and I'm looking up you know how debugging works on ARM. I'm like well debugging requires interrupts and I can debug my code. Maybe I can make some changes to this binary or you know maybe I've screwed something up in these interrupt tables by having my code run before the mouse's code is running. So I you know did a little bit of research and found out that ARM interrupts use this change processor state command and there's a CPSI to enable interrupt CPSI to disable interrupts and there's some flags for configurable handlers and all fault handlers. And at this point I'm thinking you know I'm using interrupts but I'm probably using you know different interrupts than the mouse is using because it needs to be able to register all these button clicks and scroll wheels and you know the optical sensor at you know some crazy high rates so they're probably using a lot more interrupts than I am and I'm thinking you know maybe it's using some of these enable or disable commands and since I've overwritten these handler flags it's actually turning off stuff that it needs. So I'm looking through and I'm looking for these instructions in the object on the output and I find two instances where this interrupt disable instruction was being called and I replaced both of those instructions with a no op just skip right over it and I crossed my fingers and it worked so that was really cool. So now we're you know fully up we got a working mouse we're good to go. So I am thinking that I was just disabling some interrupt that it needed and you know now we're good and happy. And now we're going to try to do a demonstration. So I have this mouse right here it's got some wires coming off of it because you know makes it look cooler and I didn't bother stuffing them all back in but we're going to go ahead and try this. So plug it in or you want to talk about this? Sure. So overall we're you know this is obviously very obvious if we were doing it for real we would do some of the rubber duck tricks to hide this but this is for you so that you can see the fact that it's working and it's basically writing it out. Some other things you know this is a PowerShell script and you might be thinking well you just block PowerShell and boom you're done. I think that lacks imagination so you know there are other vectors that you might be able to leverage by writing out like for instance maybe the game's console itself allows you to type into it and the command itself you know has some kind of vulnerability that gets you code execution or you write out like some kind of HTML or and then just you know exploit the browser instead. There's a bunch of different vectors that this kind of technique opens up and as you can see he's using the mouse. It worked. So our little cheat demo here if you're like Rob and you're not really that good at Doom you can go ahead and give yourself a whole bunch of armor and you know maybe you want a slightly better weapon maybe you want unlimited ammo and maybe you just want to kill them all button. So for a real hack generally speaking an eSports tournament you wouldn't go with stuff quite as obvious as this. You would professional gamers really only need a little bit more of an edge than Mark and I need. So generally speaking it's some kind of aim helper that takes like a three pixel off headshot and gives it to them as a headshot instead. Very subtle things that are hard to find and just a little kind of FYI in terms of like detecting the fact that you're cheating like this. Using an external cheat the anti-cheat technology is very much still in the same spot that antivirus is in and it's mostly just you know partial file hashing and maybe a little bit more magic but as long as your cheat isn't a known cheat and you wrote it brand new for that one you're probably going to be able to get away with it. So to kind of close this out we have more like thought challenges than really a conclusion. You know can we defend against extra code in this device? You could have you know can we defend against exactly what we did? So you could have your application like look at the reset vector when it boots but you could also have your added code rewrite the reset vector after booting. You could hash your entire flash space but that would make it so you can't store user modifications like you know mouse DPI settings or you know configs that you want people to be able to save and you could also have that you know added code change the hash value or even clear the flash that it executes out of because you have capability to clear flash memory inside arm. You could get into some more hardware based tamper detection. These arm chips have some like basic tamper stuff and then you can buy more expensive like secure core arm chips that have more advanced hardening features but then you get into this cost trade off. You know no one wants to buy a $400 super secure mouse that's just too much money. So if we're not really going to change the mice around or the keyboards or whatever can we defend against this kind of payload style? You can only and now you know we could we could get some software to only allow normal behavior from peripherals right? If I plug in a mouse and it dumps out 2000 characters per minute that's you know probably not what it's supposed to be doing. You could try to get everyone to sign and verify their drivers and flash of all other devices that's never going to happen. White listing executables could get you pretty far right? You know if you only allowed the game executable to run on these tournament computers or if you whitelist executables in your you know office environment then people can't come in and you know hide whatever software they want inside a power shell. You could force everyone to use USB to PS2 adapters that's probably not going to work too well. People like their one millisecond response rates for their mice and keyboards and you can provide trusted hardware right? I mean if you let people walk in with whatever USB device they have you really have no guarantee what's running on that so you might just have to keep a whole stock pile of you know mice and keyboards for every sponsor and brand and manufacturer and whatever and just run from there. So we have source code up on a bit bucket and then these are all the references we use to get through this whole you know process from start to finish, arm application notes, all the ST link utilities and if there's any questions I guess we'll be up here.