
After many (many) months of procrastination, I’ve finally put the first couple of pieces together for an idea I’ve had going round in my head since the beginning of the year. What finally made me get things rolling ? well, it’s a number of things really. I managed to sit and chat with Carlos “Darkoperator” Perez before his talk at Defcon, and his enthusiasm for Metasploit and what the project was trying to achieve really made me want to be a bigger part of that. Still, I’m rambling and not getting to the point. So what is this idea I had, and why is it important enough to write about it.
To most people who read my blog, this isn’t going to be something that effects your everyday life, but you have to remember that not everybody using Metasploit comes from the US/UK. There’s a whole world of people out their using Metasploit on machines that are installed in different languages. Most people wouldn’t think twice about it. After all it’s just the system language, why would that have an effect on anything we want to exploit. Well here’s the problem. Different language versions of Windows have a range of differences that might break, or limit your use of Metasploit. That’s bad right ? Nobody wants to have to say they could exploit an unpatched system just because it’s running an Italian version of Windows 2003.
Coming from the UK, and speaking English, I never considered this could be a problem. That is, until I started preparing for a class on Metasploit last year. None of the testing I was doing on my Windows 2003 VM was working, even though I’d not patched it against MS08-067, I couldn’t exploit the box. It was just crashing, every time. Sure 1 or 2 crashes can happen, but every time without fail. Something was wrong. Why was this happening ? Because the memory offsets are different between the language versions of Windows. It’s not only that… when looking through the payloads the adduser.rb
payload defaults to a hard-coded net localgroup command, which although it’ll work on 75% of systems (lots of languages use the Administrators group after all) there were specific languages that would just fail (German being one of them).
After looking a little further I came up with a few other scripts (mostly meterpreter POST exploitation scripts) that used hard-coded group names, service names, and screen scraping to do their magic (and yes, some of them are real magic). They served the purpose and they did the job great, but not for me.
So where to start. First off I took at at the MS08-067 exploit. I wanted to get a feel for how the exploits were written in Ruby (a new language for me) and wanted to see if I could replicate the exploit and get it working on a German version of Windows 2003 (language support for Windows XP is much better owing to the widespread use of it, and ease of finding testers). After some testing with msfpscan I found some alternative memory addresses that worked for the German version of 2003 sp1/sp2 (without NX enabled). After playing about a little more I even managed to find addresses that worked for both the English and the German versions. That however was the easy part. Finding the NO-NX memory addresses was pretty simple (child’s play for most probably). The challenge of the NX exploits is something I need to work more on. My Fu is weak in that area.
This last weekend I finally had some time to sit down and concentrate on understanding the way that the adduser.rb payload works. Once you look at the code things are pretty straight forward. I’m surprised more people don’t read the code, as it’s pretty simple once you get started. I guess some people are scared of coding. After some thoughts on how to proceed, I came to the realization that whatever I did should be language neutral, after all whats the point in me adding in 5 language options into the payload and letting the user pick the one they want. That’s not much of a move towards being language neutral is it. I also realized that the command for finding the language (and the name of the local Administrators group) needs to run on the client-side. After all, it needs to work with msfpayload and that runs a command completely on the client. For maximum effect it needs to adapt to the language used on the fly.
After spending some time mulling over the possible solutions, I zoned in on the use of WMIC to output the information. I know this is going to cut-off Windows NT/2000 systems, but this was the most elegant solution available. With a little help from trust Google (and Ed Skoudis) and a lot of trial and error, I managed to output the information I needed in a format that was usable based on the common local Administrators group SID number. The good thing about this solution is that it will not only be language neutral, but will also allow me to still add a user to the Administrators group even if the crafty Admin has renamed it to something else. After all the SID remains the same (S-1-5-32-544). The wmic command for people who want to play is .:
wmic group where sid=”S-1-5-32-544″ get name
The adduser_wmic.rb payload is still in testing, but for those that want to take a look, you can grab a copy here. Just let me know if you encounter any problems. I know there are currently some issues with the windows/adduser/bind_tcp payload, but once these are fixed in the SVN, I’ll resume testing with the wmic version.
Hopefully I’ll be working more in this project in the coming months (maybe even talk about it briefly at a conference). Let me know if you want to help with testing, as I could always use testers with access to Windows systems of different languages.