
[Music] I wanted to start with a video real quick [Music] so this is from the most recent Street Fighter game right schedule mutation all right that's it for the video you can turn off my computer audio so that's what we're going to do today is we're going to do our own Hadouken this one we're going to do against Street Fighter 5 the game itself and we're going to exploit that to get access to the kernel and get into our root kit in to bring 0 I'll quit touching that so just a quick intro like I said I'm professor plum I just cute threat researcher at Symantec so any day that I'm working in Ida I'm usually happy a lot of certs
just about all the something plus the comp taa ones I've got not sure they mean much but my handle 200 schools because I was slow to the Twitter scene but here's what we're going to do today I do want to talk about how to exploit this driver but to get there we need to get through some basic windows primer a rootkit information how we're hits work how windows kernel kind of works then we'll talk about Street Fighter do a little bit background kind of talk about what led to this exploit where it came from then we'll talk about the driver self how to exploit it finally will exploit it and we'll do a demo and install our
own route K so what is route kids good place to start right let's talk about how the system's laid out modern Auto prating systems work in a ring system that is enforced by hardware it specifically the kernel or specifically to meet the CPU whereas stuff in ring zero it has the most access it can directly access physical memory it can directly access hardware or firmware or anything that attach to the system and then down the line you go down to ring zero which has the least access and that's where your typical applications and what they can get into windows in reality doesn't use ring 1 & 2 it for legacy reasons really the only ones we
need to be concerned about is ring 0 the kernel and ring 3 where applications run applications can't directly access Hardware when you do a open file or whatnot it goes up to the kernel the kernel checks all the things it wants to check and then it accesses the hardware and relays the information back down to you so you can't just say I'll go right to sector X and once you're in the kernel you can't say oh what's in this physical memory location unless you're in the kernel so that's kind of a reason why if you're malware you might want to be in the kernel because in the kernel you have all power right if you want to
do something that infects the boot sector or be able to do a boot kit you need to be in the kernel if you want to hide your activity from like Wireshark you can hide Network coms from even showing up in Wireshark if you're in the kernel you can directly access the firmware of hard drive if you're in the kernel all these type of things are power that you may want if you're malware additionally the stealth is a great possibility right you can hide processes you can hide files you can hide network traffic you can do a lot from the kernel that's just hidden from the user so there's a lot of reasons like things want to get in the kernel you're on
equal footing against antivirus or security products in the kernel because you're both at the same level so you can cat and mouse game there there's a lot of reasons that things don't always run in the kernel most malware we see today isn't in the kernel one because it's really hard to get in the kernel first off the Windows was doing a good job of making it harder to get execution into the kernel - it's hard to develop code for the kernel if you crash or if you've got a bug which most malware has lots of bugs if you have a bug in your code then you crash the process doesn't just fall out the whole kernel falls out and you end
up with a blue screen and that's a very easy way to get caught so writing kernel code is very difficult more so if you do know you have a bug in your trying to debug it kernel code debugging is very hard because you have to debug a remote system the debugger has to live on the other machine because you can't have a debugger on a kernel and stop the whole thing it'll just is just not possible so there's a lot of caveats to doing work with kernel code writing rootkits and it's a lot of difficulty and there's a most of things you want to do as a malware author like get credit cards or prose passwords or whatever you can do
neutral lamps or not rootkits have kind of fallen off recently but they still exist and that's what we're going to talk about because worse we're power-hungry fools here today so for this course I have written a special rootkit this is this group hid the whole purpose of it is very simple it just hides any file on the file system with b-sides in the file name or directory so if it's got b-sides in it you won't see it still there it can be accessed but for anybody running the system you won't see the file at all the goal is to install this rootkit into the kernel using the exploit in Street Fighter 5 a little background when I say a rootkit
most rootkits are really just a current implemented as a kernel driver that's loaded onto the system these drivers used to be is just install this driver and it would just write right into the kernel you just be able to tell your driver as long as you had admin rights and you're done rootkit e installs easy Microsoft has over the time added a lot of security features to make this a lot harder kernel assigning patch guard secure execution of only kernel and process as a memory excuse me an address space layout randomization in the kernel so like I said we started out you could just install your rootkit as a service so you say hey service here's my driver
when you start the service the service would load a driver into the kernel root get installed just that easy then Windows has said kernel bold signing all drivers must be signed and I have to be signed by a trusted publisher does that cut down on malware rootkits dramatically I'm not going to sign my malware that's going to tell you who wrote it or I'm not going to pay $300 to get my malware signed or or whatnot furthermore Microsoft has now made it for like Windows 10 Don that has to be co-signed by one of their certifications and they have to go through a certain process to ensure that the driver does meet certain requirements and is good code and pretty
good chance you're not going to get malware to get that signal so Colonel Oh tiny code-signing has put a large stand to just writing a rootkit driver and having to be installed so how did the malware get around this well there's a little flag inside the kernel that was like do I need to check the certification about the drivers or do I just allow any driver in and malware would use some kind of exploit to flip that switch off then say hey load this driver it's like oh I don't need a check drive the signature so I'll just go ahead and load this and that's how they got their driver or rootkit into the system Microsoft got smart and like you
know what we really should watch that flag and if anything changes it we've been poned and shut it down and so that's what patch guard does patch guard watches a lot of key structures inside the kernel to make sure that nothing's being mucked with one of them now is the little flag the switch that says hey do I have to sign this code and if that switch is flipped it notices it it'll throw a blue screen shut down the system easy way to get detected so now that brings us to where we currently are in this kind of cat-and-mouse game where if we want to load something into the kernel we can't do it as a service
anymore unless it's been signed and verified so we need to manually load our driver into the kernel some way and that's what this talk is really going to focus on now finding an exploit is extremely hard especially for the kernel right like the kernel is getting tougher and more secure every every iteration every bug fix and so it's hard to find an exploit in the kernel even if you find one you probably want to use it just for this but there are numerous numerous drivers for the kernel that are of shady quality and you can find exploits in one of those drivers and they execute in the kernel so if you exploit one of them
you're granted access to the kernel now the great thing is is you don't have to find an exploit in the driver that's running on your target you can simply find an exploit in any sign driver and then just bring that driver with you say hey but install this in the kernel window says uh you're an admin yeah oh is it signed yeah okay I'll load this in the kernel then you just exploit that driver and get yourself into the kernel and rootkits do this often Turla was very famous for doing this they would bring along a signed driver for a an older VirtualBox driver they would install that driver into the kernel and then exploit it to get access
into the kernel themselves windows would gladly install that VirtualBox driver because it had been signed and verified and the cool thing is this VirtualBox has now made newer versions of that driver but the older driver is still valid still sign and so it still works for these guys and that brings us to where Street Fighter 5 comes into the picture you've noticed I've had some Street Fighter 5 characters along the side this whole way that's kind of the theme here Street Fighter 5 is the 17th game in the series yeah they count as well they're counting seems weird but I think Street Fighter 2 had like six variants right like that's the one most of us know I feel asked
when I play sorry but so there's like six versions of two and and that's how they eventually got up to 17 it's been going on for thirty years now so this is like 30 years the Street Fighter and I'm not counting here like Street Fighter pinfall or Street Fighter versus tech more you know some of the tangent version this is just the main series line it's a very very popular franchise for them it's 305 has a lot of features that Capcom wanted to make sure hackers or cheaters weren't allowed to break Street Fighter 5 has online cross-platform multi-player gaming right anybody who's played online gaming knows the thing that can kill an online gaming series
faster than anything else is rampant cheating if there's rampant cheating nobody wants to play it anymore so there's a huge incentive to Capcom to do want to curb somebody from hacking their local content and doing some kind of automated bot keying or I don't know what you'd want to do to make yourself win better but I'm sure there's plenty of ideas and things you could do furthermore the game uses microtransactions you can buy in game currency or earn it by doing certain feats I'm sure you could probably scrip that if you wanted to hack it and get money and so they wanted to curb that and then finally there's a global player ranking so there's a lot of incentive
for Capcom to want to curb cheating locally on the machine and so in September about six months after the game's release they added a patch that says oh this is our new anti cheating mechanism is coming down to the machines and that's really where this caught my eye as I was browsing a reddit forum and somebody was common in the forum that their game keeps crashing and causing a blue screen and I thought to myself games shouldn't be causing blue screens because blue screens only happen if something's mucked up in the kernel so something about this game must be mucking in the kernel which is not a good idea game shouldn't be in the kernel game
still belong to everybody any means so emeritus I felt it merited some more attention I got a hold of the the code the Capcom driver within a few hours I realized this is really really bad this driver has an exploit it doesn't do a lot of good things what it does it's designed to load code from user land and execute it yes I think it's designed to say hey Street Fighter game do you have something you want me to check for you I'll check it for you and so it will just accept code from the Street Fighter game to run in kernel land but it doesn't do any kind of on a second authentication so any user line process
could talk to this code and say hey I want you to run this for me like it basically is just opening the door and say anybody won in the kernel because I've give you access right here when I noticed this I read we we reached out to Capcom as quickly as we could within a few hours we had trying to figure out who to talk to who's the right person and we sent emails to our contact and say hey you've got a really bad problem here but at the same time we were doing that it was a very easy bug to notice and that's why I'm using this driver here it's a very great example of how to
exploit the kernel because the bugs really easy to spot others had spotted it and they just went public with it it was all over Twitter at the same time we're trying to reach capcom under the covers Capcom was very good about it very cool within 24 hours they had rolled back to patch they realized the mistake and so they clean it up very quickly now I had done some research on this driver hello to the code I'm a malware reverser so I I like to find the history of something I like to see where it came from I like to try to figure out who's behind it and it turns out this particular code probably
wasn't written by Capcom themselves because I can find very very similar code almost the exact same type of same code to state back almost ten years this has been around for quite this particular code has been around for talk sometime it has been used in numerous other gaming other games these are icons for those other games or images I don't recognize any of them and that's probably why this hasn't gotten any attention until now is really low under the wire small fry stuff it wasn't until Capcom picked it up and that it got noticed Capcom's got a lot more attention I can't completely unlit cap come off though because where they got this co-brother they got it from a forum or
they hired a guy that brought it in or they subcontracted I don't know I can't say but they signed the code that's not a good idea to think somebody else was called that you didn't write it just not good for your own reputation so that signature is what allows us to let this code into modern kernels so I want to let's take part this driver now I'm going to we're going to look at the key functions in this driver it's really small there's like three main functions we're going to look at and I'm going to show some code I'm going to try to stay out of assembly there's like five and assembly instructions I'll talk about
this whole course so the most of it's going to be sea level code so every driver has a main function which is
you
you give me does the address before it point back to that same pointer because I want to know that it does for some reason not sure why but it wants to know that it does and then if so then I'm going to turn off s ma P now s MEP is what says kernel-mode code must run over here and user mode code run must run over here and if you're a colonel you can't be running code from over here they turn that off they said oh yeah yeah yeah colonel you can read code from the user that's fine and then it finds an address of a routine and it passes that as an argument to the user land
pointer it zooms what you give it was a pointer to code and it just jumps to the code that the user gave it once that's done then it comes back and it says okay let's rien a bit that says kernel mode code can only run in kernel and let's not run user mode code because truthfully that is a bit that's in later versions the window monitored my patch guard and so patch guard notices that's changed it's going to send you up the blue screen it's going to shut you down but we have a window because blue patch guard doesn't watch every bit at all times it actually kind of runs through the cycle of I'm checking these things
now I'm going to check these things can go back and check these things and so if you're quick you can flip that bit run some code flip it back and patch guard would be none the wiser and so if the user man code that you pass to this is very small very quick you won't be caught by patch guard now the pointer thing is really kind of weird I'm not going to dwell on too much but let's just assume that it's stipulation we have to meet as part of our next exploit because whenever you're exploiting drivers that are harder or real exploits like this one's not then there's there's going to be stipulations you have to
meet so this is a very easy stipulation to me we just have to make sure there's a pointer to our a pointer to our pointer right before our pointer really kinda hard to say but so boom that's it that's all there is to that driver there's really not much else to it it doesn't do anything elbow can open up a window for you to run user code so in user land how do we exploit this all we have to do is open a handle to the driver that string shown there at the top it is the handle to the driver we call device i/o control with that particular code and then we just pass it
the address of our show code and if everything's happy it'll run our shellcode our user line code now that's not we're not done though that's not just it remember we're not exactly in the route we're not in Colonel yet we're just running from user land in a kernel thread so we want to get our rootkit up in kernel land and we want to be officially in the kernel and furthermore remember this thread has to return very quickly otherwise patch guard is going to catch us so we have to be kind of careful what we do here so what I've got here is I've got a little rootkit kicker function I just call it my launch shell
which is for launch L code and basically its whole point is
you
but in 64-bit land there's not a long jump one instruction so that's why I have to do it with these two instructions now I've made it as a struck two like this to make it a little easier I could have wrought assembly code like I said I don't like writing assembly I like to Li use command line foo and so this first structure right here is the structure the pragma pack tells the compiler do not whatsoever put any spaces in between this to make it memory lined or whatever because those spaces will totally screw up my assembly line I really want this to be tight packed these parameters to be right next to each other so that's all that says
you can see that I've got a pointer and move the jump de três I want to move in and then a jump instruction and then down below is where I actually initialize it and I can just initialize it as a constant and so I say hey here's the address I want in that pointer that the b84 8 is the move to EAX instruction the launch shell is the value I'm moving into EAX and then the EF e 0 FF is the jump instruction so I've already initial I've just been filled out that structure it's already got everything set up just right I'll pass that the address of that shellcode to the kernel it'll run it and then
it'll just jump to the launched shell function just fine the pragma there is something that I like this kind of tricky so when you initialize something in Visual Studio as a constant then it's going to put it in memory that is read-only because it's a constant but that's memory is not marked as executable so if I tried to pass that normally to the kernel then they'll try to go there in the min and the process is high this memory is not marked executable I'm going to throw an error and you're in the kernel land so I'm going to blue screen so to prevent that I despaired my says hey put this particular structure in the code section
just just do it don't ask why just do it and so sure enough link Visual Studio will put this constant structure in the coat executable memory which then doesn't cause any problems it saves me from at runtime having to malloc some executable bramley memory copy the structure into it and then find the right offsets to fix up my pointers it's just a lot cleaner this way in my mind okay so now we have some shellcode we have all we need to get chill code into the kernel but getting chill code into the kernel it's not the same as having a rootkit driver installed in the kernel because a driver has initialization routines has some imports that has to be
found there has to be some relocations some memory layout changes we still have a little jump to go from shellcode to rootkit installed if you're not familiar with the a PE file when a driver is a PD file a drivers just a different type they exact same format with just some slight variations a DLL at PE at drivers are all the same like I was just saying we need when a driver or a PE file is loaded there's some steps it does it has to copy all the sections into memory expanded it will fix up any relocations based on where it was loaded into memory it will find any function that calls that's in a different library it has to
find the address of that pull it in so these all these things are things we're going to have to do and we're gonna have to do it manually because we can't rely on any kernel function to do it at this point because there's not a kernel function to load a load of driver for memory there's only kernel functions to load drivers from disk but then all of them also do the code signing verification stuff not things we want to be screwing with so I'm going to compare side by side loading a DLL for a memory because that's very well talked about process meterpreter does that all the time it's called reflective DLL loading I'm going
to do that but I'm going to do that for a driver and so side by side the steps are almost the same but there's differences in the user land called virtual Alex to allocate some memory in kernel an you call EXL like a pool with tags to come to allocate some memory mem copy memset they're both the same in user land you have to there's not a clean function for doing the relocations exposed by the AP is you have to do it by hand that exact same code works for drivers we can just kind of cut and paste that code put it in our in our reflective driver resolving import that's kind of a stickier one userland
you would say load library deep library say get proc address say get the function from that library I need so I can get the address there's not the equivalent for that in kernel-space there is what we talked about before and get system routine address which can get the address of system routines but it only pulls functions from anta's kernel or how if you need any kind of exported function that's not in one of those two mm get system routine address will not find it for you and unfortunately because I'm interacting with file system I do need my rootkit needs some functions that are not there so I'm going to have to do some manual work there to find the
driver I need or to find the library in the kernel I need get the exported function from its port so that I can load my driver the next thing is after you're all done setting up the memory you set the memory protections on it and use the line you say this member is read-only this member is executable this memory is rewrite this it's actually kind of optional if you just set the memory to read write execute like it's fine you probably get caught and use the line when you do that kind of thing but in kernel space the memory protections don't quite work the same as they do in user land and furthermore since this is
optional we can kind of just skip this space in kernel and as long as the memory is marked executable which we can mark when we allocate the memory then we should be fine here and then the last thing you do is to notify the DLL or the executable or the driver that you're you're ready and that that's just the name of the function based on a page our DLL a PE or a driver it's driver entry for a driver you know we can call this directly but there's a nice kernel function called IO create driver where you just pass it the address of this function and then in its initializes some nice memory structures for the
driver in and that's the best and cleanest way to actually kick off the driver so in a minimum we need to find two functions on our shellcode
you
we'll find some other functions that make this a lot easier so my code uses a bunch of other functions in there to make the loading process a little easier just so I don't have to write as much code and that I know if when those changes that it's going to change these functions too so at a minimum I need to somehow find the functions I need I need to find out where the heck I am in memory so that I can parse start parsing my own PE header and find out where my relocations are what what five functions the driver actually needs I need to then copy my condensed driver into the memory section I needed to copy the text
section over to a spa I need to talk code section over need a copy each of these particular sections over in to the right locations I then need to fix three locations inside and say hey I moved this to here this is over here this over here and set the pointers correctly that way find all the imports my driver needs and then finally call create driver passing at the address of my rootkits driver entry function and then I'm good to go my driver can just run like normal so the code to do this like I said is all on github nothing in there
you
finding exports and there's a undocumented kernel function called RTL query module information what it will do is if you call that it will pass you a linked list of every module loaded in the kernel I can then walk this list and find the modules like oh I need to find an import from you know beat crypt or whatever so I can just walk that module list until I find beat crypt oh that's the one and then I have my own get proc address routine and my own implementation of it it's the same implementation as any other load from memory library would do because it's kernel ants just the same as user LAN so I just have my own get
proc redress routine I passed the address of that module then it'll find the exported function I'm looking for that's really the only piece that's kind of different or new so anyways I post the code here on github I posted it like last week and in honor of streetfighter I wrote the code in hadouken style programming now if you're not familiar with Dugan style programming is this might give you a hint this is why it's called hadouken style programming because it will do the nested if statements that it looks like the whole thing is being pushed over by a token personally I don't really like this kind of style of writing it's kind of ugly to
me but it was fun for a change cool I think I talked way too fast but I'm sorry let's do this alright this is my machine that I plan to infect
you
that's how we do this now the Capcom driver really isn't that exciting is it basically just handed us access but I hope that what I showed here can at least explain how the process works right like you now know this is how I exploit something get my kernel code into the kernel and install my rootkit so that you can hunt on a different driver that may be a little bit more harder to get execution on but the process is still the same it's just kind of like this was a great baby food to get to sink our teeth into kernel mode expectation the current medications just kind of in review current windows medications do make this a lot harder
than it used to be but it's still possible many many drivers exist with exploits that are signed that they're approved to run on Windows machines and those are the most lucrative place to be looking for an exploit to get your code into the kernel and kernel drivers just like dll's can be reflectively loaded that's about it I talked fast so there's plenty of time do you guys have any questions any other questions thank you for that one how do I get rid of it mind has no uninstall routine either so the only way to get rid of mine is to reboot the machine soon as I reboot the machine if everything goes back to normal I don't
do any kind of persistence cool well thank you guys I hope you have a good conference