 All right. So, hi, thanks for coming. This is weaponizing the Windows API with Railgun, which is an extension of Metasploit. So some of you probably have no idea who I am. I'm the light co‑sign. I am one of the core developers for the Metasploit Pro product. And before that, I was a long‑time Metasploit framework contributor and a professional penetration tester. Before I get started, there's just a couple people, and this is far from a complete list that I wanted to just give a shout‑out to. These are all the people who really helped me get to this point and mentor me, teach me a lot of the stuff that made me the person I am today. I've spent the past about two and a half years working on Metasploit as a contributor. And when I first started, H.D. Moore said something to me that I think is a quote that needs to be kind of immortalized. He said that if you don't think you're a noob, then you're not trying hard enough. So what I'm going to try and do with this talk is just kind of show that this stuff can be done by anyone who has the desire to learn it. And it's not as hard as you think. So hopefully at the end of this, you'll come away thinking Railgun is pretty cool. You'll want to contribute some modules back, and maybe next year you guys will do a talk on something cool you did with Railgun. So everybody knows Metasploit for its exploits and being able to get shells on a box. As a penetration tester, I said, well, that's great, but now what? There's a lot more you have to do than just get a shell on the box. You have to actually achieve some sort of objective that is meaningful for your client or your company. And that's where post exploitation comes in. There's a lot more that goes on in Metasploit now with the development of post exploitation from stealing credentials, gathering information, doing further reconnaissance on the network once you've gotten that first foothold. And in a very short period of time, we've come up with a lot of new possibilities through the advent of the post module. I don't know how well you can see that, but just in Windows post modules alone, there are 105 modules currently in the Metasploit framework. And these do everything from screw with the wireless cards to decrypting stored passwords to, I mean, just about anything you can possibly imagine. And this is all made possible on the Windows environment from our Meturpreter payload. For those of you who don't know what Meturpreter is, it is sort of like the default go-to payload now for Metasploit. It is a compiled CDLL that most of our exploits inject into memory via Stager. So it provides an enhanced command shell, but what's really important is that it provides a standard API that module developers can code to. And it provides a lot of functionality. One of the benefits of Meturpreter is that once we've gotten that initial shell, we can migrate it into other processes and gain system level access very quickly and easily. So jumping right into Railgun, Railgun is one of the extensions for Meturpreter. Basically it's a part of the standard API that allows for arbitrary loading of DLLs on the system. As long as you know the path of the DLL that you're trying to load, you can just pass that information into Railgun. It will map the DLL into memory and then you can actually get function pointers out of that module. So it's doing a runtime dynamic linking. And we're doing it on the fly. So we pass it a DLL name, then we pass it some function names, and we get to call that function as if it was already coded directly into Meturpreter. Since Windows API DLLs are always at a known location, this means the entire Windows API is ripe for exploitation and use for whatever nefarious purpose that we might have on that system. So Railgun is providing us a fully dynamic access to the Windows API. That's all the core functions that any Windows developer would want to use to do anything on that system. It doesn't sound that exciting at first, but when you start looking at what the possibilities that opens up for you are, it's very, very powerful. By calling these APIs from a user land process, we can actually impersonate any user on that system. And this can be very important for things like cryptographic context where the cryptographic context will change from user to user. So if we migrate from a system process into a user process, we can then call Windows cryptographic APIs as if we were that user. And the operating system will just go ahead and decrypt that data right for us. And you'll see a little bit of how some of that works later when we get to some of the demos. But basically Railgun and the access to the Windows API makes anything possible once you get that initial shell. Let's talk about Railgun and its history briefly here. In June of 2010, a community user called Patrick HVE submitted Railgun via the mailing list. And it was just an extension from interpreter to load at the time. By September, Steven Fuhrer had added 64-bit support. And February of 2011, Chaomu, another user on the IRC community, took over support for Railgun and started adding new features and patches and things. But by fall of last year, he kind of just disappeared off the face of the earth again. So here's where I get into some wishful thinking. Starting August 2012, some of you will start contributing back to Metasploit and Railgun. And December 2012, the minds predict the lives. Who knows? Maybe it's Railgun related. So how it works on the C side is that it uses a Windows API function called load library and another one called get proc address. So load library just takes a path to a DLL and maps that into memory if it's not already there and returns a handle to it. From there, get proc address takes that handle and actually takes a function name and get returns you a function pointer that you can then use to basically alias any function out of that module. There are some additional utility functions like some generic memory read and write functions. So as we return some of the data, we then read the return right out of memory. It can get a little hairy, and I'll show you what some of that looks like in the demo. On the Ruby side, we have a bunch of libraries. They all live in the Rex library under post, metterpreter, extension, standard API, Railgun. So the actual code for the Ruby side of the API lives there, but also what's important is the definitions for these libraries and these functions exist there. So you can, when you're writing a module, you can define the DLL and you can define your functions within your module or you can just go ahead and build it right into Railgun by creating these definition files. And here's a brief look. You can't see that really well, so I'm going to actually show you some, I'm flipping the wrong way. So this is what one of the definition files looks like. This is the definition for the advanced API 32 DLL. You can see there's actually a custom structure defined here. It creates the DLL, defines it by the path and puts in the Constance Manager. And then we can see all the functions, and it goes down quite a long way here, but these are all the different functions out of that DLL being defined for our API. Oh, sorry. So the basic anatomy of the function definition is that we have a function name, what type of function it is, basically what type of return value it has, and then just pass it in an array of parameters and flip it over here again so I can actually show you that. So this is the name of the function. Then we have our type, so this is a Boolean, it returns true false. And then here's our array of our parameters. And what you have is the type of data that goes into that parameter, the name of it, which is only sort of important. And then whether it's an in, an out, or an in, out parameter, for anyone who hasn't worked with the Windows API, what that basically means is an in parameter is one where you're just putting data in, an out parameter is where you're expecting to get back, and an in, out is where the function will read data in, but might change that data on the way back out. And so I mean, you can see once you actually know the structure, it's very simple and easy to define these functions and add new ones constantly. Railgun also knows about Windows Constants. They're defined in the APIConstants.rbe file in that same railgun folder. And flip back here again, flip back and forth off the slides, but it couldn't be simpler to add new ones of these either. It's just basically a call, you can copy, paste this, and just change it out for your name and value. So that way we don't have to constantly be looking up on MSDN like, well, what does that constant actually mean? Once you find it, just throw it in here and railgun will know about it forever afterwards. So just talk real quick about what those various data types are that are defined in those parameters. The most basic and probably the most common one you're going to see is a D word. The general rule of thumb, of course, is if it quacks like a duck, right? So if it acts like a D word, treat it as a D word. This goes for pointers, handles, you know, all the weird things that you're like, well, Ruby doesn't have any concept of that. Like, Ruby doesn't understand the idea of a function pointer or a handle, right? But in reality, all it is is a number. So we just treat it like a number. So from the Ruby side, we pass for a D word parameter, we just pass in a fixed number or a big num. Or if it's one of those defined constants, we can actually pass in a string representation of that constant and it will interpret it for us. We have the P D word, which is a pointer to a D word. You pass it as a fixed num in Ruby. And what you're doing is you're actually when you're passing it into the parameter for the function call, you pass in the content and Railgun will handle the actual referencing for you on the back end. So you just basically pass in the data and don't worry about the fact that it's a pointer. And the only kind of weird thing is if it's an out parameter, then you just pass it a four because that's the size of a D word and so it's the size of a pointer. And if you need an old pointer for any reason, you can just pass it nil. Then we have, of course, P Charges and PW Charges, which is just wide characters and pointers to characters and wide characters. Same thing, we pass the data. So we're passing it strings. And again, if it's an out only parameter, then we pass it the size of the buffer that we wanted to occupy. And that includes the null byte. So you have to watch that. You can get, you know, you're off by one errors there. But so here's just some example that shows some of those data types in use. So you can see the definition on the side here. We've got a PD word, pointer to a wide char and some D words in there. And if you actually look down at the acquire context call on the right, you can see that we point in four for the out pointer to the D word. We put a null pointer for the container. And then we have some basically fake constants that we define up above that we pass in for the other parameters. So just a quick little look to demonstrate those data types being used. And we'll have some demo here closer to the end. That we have a Boolean type, it's, there's not much I can say about it. It does exactly what you think it does. So you just pass it a Boolean, a true false in Ruby. And another example, here's the is debugger present Windows API call. And it returns an actual false value. Bytes and words basically do the exact same thing as D words, but they'll be truncated to the appropriate length by Railgun. So it handles all of that for you. And then the last sort of catch all is the pointer to a blob. And this is basically any data that doesn't fit any of the other data types. It's a blob. And on the Ruby side we just treat it as a string. And this is important also because Railgun doesn't really help you parse structures. So sometimes you have to do some kind of rejiggering there to work with some of the more advanced Windows structure types. There's just another, here's another example of a definition and then seeing how it's actually used with those data types. We, I mean, we'll go over all of this at the demo. I just wanted to make sure it was on the slides for anyone who didn't get to see the presentation. So sometimes we have to kind of fake it. And this is, I kind of made reference to this earlier with the D word thing. There's a lot of, there's a lot of crazy data types that you can run into with the Windows API, a lot of custom structures. You get, and even simple things like handles and pointers that Ruby doesn't have a concept of. So we kind of fake it. Anything that basically boils down to being a number, you just treat it as a D word. Otherwise it's a blob. If neither really works for your scenario, my recommendation is add support for it yourself. It seems intimidating at first, but it's actually really easy to work with this stuff. So when you make an actual function call, you're actually returned a hash. That hash will always contain at the very least the result of a get last error call. So basically Railgun will make the function call for you and then it will call the Windows get last error function, which will tell you any error code that occurred with the running of that function. And then the hash will contain any out values from that function call. So if anyone, for anyone who's not familiar with get last error, it'll return an error code of zero if everything went fine. Otherwise you'll get a system error code and there's a nice handy MSDN page where you can look up what any of those mean. I recommend that everyone have that page bookmarked because it's super, super useful. I reference it all the time. Okay. Oh, so this is, sorry, this is just an example of some code using Railgun using two different function calls. And basically we acquire the cryptographic context here and the return value is then used in the next function call. So it just shows you that we call the cryptifier context and we get that hash and we just make a reference to the pH provider value out of the return and pass that into the next function call. So some of the more tricky situations that you can run into, again, is the complex structures that you'll have to parse yourself. A lot of times you end up doing some funny things like having to get pointers back and then increment the pointer yourself and do another memory and do a memory and increment a pointer. And so you can end up with some kind of tedious work with that. Because you're reading everything directly out of memory, if you don't know the length of a string, you can run into some tricky situations with that too. Although somebody was just telling me that they got around that by actually then using Railgun, again, to call size of back on the pointer. So that's something that you should probably be able to do. And one of the downfalls right now with Railgun is that it's slow because every single request and every read operation has to be sent as a packet from your client back to the interpreter on the victim machine. And so like large numbers of string reads, for example, is a very slow process. So it seems like, you know, I'm just pulling this data structure out of memory on my victim. It should come back to me. But if it's got like a massive string in there or a bunch of different parameters, it has to send a new packet for each little bit that it's pulling back. And that can actually take some time. That was one of the things Chowmoo was working on fixing before he dropped off the face of the earth, was doing some nice multi-read stuff. So hopefully we can get that back on track in the near future. So tricks of the trade, these are just the things that I've found exceptionally useful for learning to do Railgun. MSDN is your friend. I don't know how many people do Windows API programming or spend time on MSDN, but it's, it gives you all the information you need right there. It will give you function definitions. It will give you examples. So use MSDN, find examples of the code in C, and write it, whatever you're trying to do, write it in C first. Because you're doing this weird transition from Ruby into C. And sometimes things don't behave the way you expect it to. So if you write it in C and kind of look at it in memory at the time, you can know exactly what to expect. And then when you go to do it on the Ruby side it goes much faster. So it's kind of like Microsoft wants to help you own their systems. Because I don't know how well you can see that. But there's the definition of the function. It looks very similar to the function definitions we have in that Railgun code, right? Seriously. Right there, they give you an example down at the bottom of the page of what that C code looks like. So, I mean, it's like they give you a walk through and hold your hand through doing all of this. They even give you great tools, the free visual studio. You can write your C code and then just look at exactly what those structures look like in memory. So there's no real mystery if you do it in C on a Windows box first and then just port it over to the Ruby. So by this point you're all saying, oh, God, this guy's going on and on and on about this stuff. And why do I care anymore? What is Railgun useful for? So anything you can do with the Windows API is available and one of the reasons Railgun makes this extra special is that we're not compiling new extensions into that DLL, right? If we wanted to add this the traditional way, we'd have to write new C code, hook it in and that's more data that has to go down and expand the size of that payload on the victim's machine. Slowing the victim down, making it more likely that it's going to be detected. So here's some example mayhem that's been caused with Railgun. Smart FTP is a FTP client that stores encrypted passwords but it does it, it encrypts all the passwords with the Windows cryptographic API. So using Railgun we make those same exact function calls and get the victim machine to go ahead and decrypt the passwords for us. There's no pulling down the encrypted password and having to crack it and use our own processor time for it. The victim does all the work for us. Another contributor added one that Windows has a credential store where it stores passwords for things like RDP and a couple other Microsoft specific things and it's all exposed through the Windows API. So as long as you are in the context of the user who stored those passwords, you basically just ask the operating system to give them to you and it will because it doesn't trust it. You're that guy. Why wouldn't it give it to you? There are some post modules that will actually use the wireless API and with that we can actually get any stored profiles, so saved passwords for wireless networks. We can make the wireless card on our victim actually actively scan for new networks, disconnect from networks, connect to new networks. One that I haven't gotten around to doing but is on my plate is actually to use the victim's wireless card to then set up a fake access point. So if you think about that, you take control of a desktop, they're wired in and then you set up a fake wireless API off their card. You've got basically another whole network that you've set up that you can pivot into and trick people into connecting to. It's just some really fun things you can do. So enough blathering and slides, it's time for some demos. Hopefully this will be a little more exciting for everybody. So I've got a, come on, a server 2008 VM set up here. We're going to just go ahead and make sure all our settings are correct. We're just going to pop a shell on it with the PS exec module. So we've got our interpreter session. We're going to run the PS command to get the process list. And let's find explorer. Okay, so what I'm going to do is I'm going to go ahead and migrate interpreter into the explorer process so that we're operating in user land. So you can kind of see some of this stuff interactively. And it'll take a little second here. It's basically just re-injecting itself into a new process. And so now we should, if we check our UID, we're running as that actual user. And we're going to drop into the IRB, which is basically IRB shell, which is just an interactive Ruby shell that we can basically write out commands as if we were writing a module, but do it in real time. And so we're going to just call on rail gun here. So everything's done through the client object that represents your connection to the victim. And then we're calling the rail gun extension. And within that, user 32 is the specific DLL that the first function we're going to use is based out of. And we're just going to throw a quick little message box up there just to be the simple, obvious example. So pass it a null pointer, pass it the message and the title of the window. And then we're going to pass it a string representation of the MBOK constant, which just tells that the message box is an OK button message box. And we're going to call that. And there you can see our simple little message box. So we go ahead and say OK to that. And that's kind of cool. But for a PAN test, who cares if you can pop up a little message box, right? So we've got calculator running here in programmer mode. That's for human else. And we're going to find that PID here in our back in our process list. Excuse me while I find the PID. Oh. There we go. OK. 100. OK. Is that right? I can't be right. OK. Yeah, it was 400. OK. So again, we're going to call client and then rail gun. And this time we're going to call the kernel 32 DLL. And we're going to call open process, which just open, whoops, if I could type. All this does is open up a handle to that process with a set permission. And again, we're going to pass it in a constant, which rail gun already knows about. And it's going to be the process terminate. And that's just basically the privilege level that we're opening that handle with. False here has to do with handle inheritance and process manipulation. It's really not important for this particular demo. And then we pass it to PID. And you can see here, this is the return hash I was talking about. We know it worked because our get last error is zero. And that number is actually the representation of the handle. So I'm just going to go shove that return value into a variable here. And then we're going to call a new function, terminate termin beat. Terminate process. And for terminate process, all we do is we give it the handle and an error code or an exit code. And our calculator is gone. So that's sort of the easy version of rail gun. And just kind of a quick demonstration to show you the simple and easy way you can call some of these predefined functions. What I want to show you now is the smart FTP. This is one of the saved XML files that smart FTP stores a saved connection in. And you can see we've got the name of the connection, some data about what host it was, what port, the username. And here we have an encrypted password saved in that XML file. So what we do is in our, and I just closed it. That was brilliant. Sorry. Let me pull that back up. Modules. Control shift T. Control shift T. I guess I could just do this file. Open recent. There we go. So in this module, we actually there's a lot of garbage here just for searching out for the XML files and parsing them. But what we're interested in here is the actual decryption routine. So we pass in that encrypted password we saw in the XML file. We do some packing to get it in the right format. And we have, I predefined some constants here that are useful for the cryptographic functions. But then you can see we basically just, we call a series of crypto API functions to acquire the cryptographic context, create a hash that hash data is then used to derive the cryptographic key that was used to encrypt these passwords, destroy the hash, we decrypt the password then destroy everything and do garbage collect behind us. So we can turn this into this. This. So I mean this is a very common problem and you'll find a lot of these modules sitting in Metasploit framework for decrypting these passwords because a lot of clients think that if they use a real encryption algorithm, surely it must be safe. But of course they hard code, they hard code the encryption key or the routine for gathering the encryption key directly into the app. So it's very easy to reverse engineer that back out and they've broken sort of the first rule of cryptography of taking, like taking that key and separating it from what you're encrypting. So by simply getting onto that machine and calling the same exact API calls in the correct sequence, we just get the operating system to do all the work for us. I can't actually demo this part because I don't have wireless on the VM. But just a quick, another quick example. This is a module that does the wireless LAN stuff I was talking about and it basically uses Railgun to open a handle to the wireless LAN API interface and then actually pulls a list of all the saved profiles on that interface. And then we just basically do some pointer manipulation magic to parse through all of that information. And again, the same thing as long as we're in the correct user context, the context of the user who originally saved those passwords, the operating system just returns those passwords in a decrypted format for us. So to sort of recap, Railgun basically lets you turn the machine into a weapon against itself. They provide everything you need to just destroy any, wow, sorry, I'm stuttering like crazy here. They provide you all the tools you need. All you have to do is basically redefine them so that you can call them from the Ruby side. And I'm sorry, I ran a little fast here, that's actually all I've got.