Showing posts with label Metasploit. Show all posts
Showing posts with label Metasploit. Show all posts

Saturday, 24 March 2012

Security-Bsides Austin Texas

I am proud to say that my talk has been selected for B-Sides Austin TX this year.  Check out the Abstract below if you're interested.

Name: David Maloney, @thelightcosineTitle: Don't Pick the lock, steal the key
Length: 45 minutes
Abstract: You've got a problem. You're running a pentest and the only vulnerable box is some shmuck's desktop. Is it game over? wait, what is this WinSCP application on his machine? don't give up just yet. The wonderful world of fail that is password storage is about to save your butt. In this talk we will break down how Windows applications store their password. Where they store them, how they encrypt or obfuscate them, and how we can attack them. Then we will follow up with some real world examples from the Metasploit Framework, and show how you can turn one workstation into total network compromise in a very short ammount of time.

Saturday, 8 October 2011

Update to the Metasploit Exploit Port Wishlist

Here is the latest update to the document I have been creating. This is a list of exploits that are in exploit-db but not in Metasploit. This list is generated by referencing the Knowledge Base in QualysGuard. Its accuracy is not guaranteed, but it should serve as a good starting point for anyone interested in porting exploits to Metasploit.

Saturday, 30 July 2011

Metasploit: Dumping Microsoft SQL Server Hashes

New module just committed today: auxiliary/scanner/mssql/mssql_hashdump

This modules takes given credentials and a port and attempts to log into one or more MSSQL Servers. Once it has logged in it will check to make sure it has sysadmin permissions. Assuming it has the needed permissions it will then grab all of the Database Username and Hashes. While it is in there, it will also grab all the Database and Table names. It reports all of this back into the Database for later cracking. Support will be added in the future to the John the Ripper functions to include support for these database hashes. When it does, the database, table names, and instance names will also be sued to seed the JtR wordlists to enhance cracking efforts.



msf  auxiliary(mssql_hashdump) > info

       Name: MSSQL Password Hashdump
     Module: auxiliary/scanner/mssql/mssql_hashdump
    Version: 13435
    License: Metasploit Framework License (BSD)
       Rank: Normal

Provided by:
  TheLightCosine

Basic options:
  Name                 Current Setting          Required  Description
  ----                 ---------------          --------  -----------
  PASSWORD             reallybadpassword        no        The password for the specified username
  RHOSTS               192.168.1.1,192.168.1.2  yes       The target address range or CIDR identifier
  RPORT                1433                     yes       The target port
  THREADS              1                        yes       The number of concurrent threads
  USERNAME             sa                       no        The username to authenticate as
  USE_WINDOWS_AUTHENT  false                    yes       Use windows authentification

Description:
  This module extracts the usernames and encrypted password hashes
  from a MSSQL server and stores them for later cracking. This module
  also saves information about the server version and table names,
  which can be used to seed the wordlist.

msf  auxiliary(mssql_hashdump) >

Friday, 29 July 2011

Metasploit Development Environment In Ubuntu

I have spent some time today getting a new Metasploit Development Environment in place. With a lot of help from DarkOperator and egyp7 I think I have succeeded.

Step 1: Installing some Pre-Reqs

sudo aptitude install build-essential libssl-dev zlib1g zlib1g-dev subversion openssh-server screen bison flex jam exuberant-ctags libreadline-dev libxml2-dev libxslt-dev libpcap-dev libmysqlclient-dev libpq-dev curl git libsqlite3-dev
Step 2 Installing RVM

sudo bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
Edit your .bashrc file for each user that will be using RVM:
And add the following lines to the end of it:
# Load RVM source if [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then source "/usr/local/rvm/scripts/rvm" ; fi # Enable Tab Completion in RVM [[ -r /usr/local/rvm//scripts/completion ]] && source /usr/local/rvm/scripts/completion

Then from bash run: source /usr/local/rvm/scripts/rvm


Next we install some necessary packages for rvm:

rvm pkg install zlib
rvm pkg install openssl
rvm pkg install readline


Then we install the ruby versions we want


rvm install 1.9.2 --with-zlib-dir=$rvm_path/usr --with-openssl-dir=$rvm_path/usr --with-readline-path=$rvm_path/usr 



rvm 1.9.2 --default

rvm install 1.9.1 --with-zlib-dir=$rvm_path/usr --with-openssl-dir=$rvm_path/usr --with-readline-path=$rvm_path/usr

rvm install 1.8.7 --with-zlib-dir=$rvm_path/usr --with-openssl-dir=$rvm_path/usr --with-readline-path=$rvm_path/usr


Then we install some needed Gems:


rvm gem install --no-rdoc --no-ri wirble pry pg nokogiri mysql sdoc msgpack hpricot sqlite3-ruby

Step 3: Adding DarkOperator's IRB customizations:

Create a file ~/.irbrc

The file should look like this:

puts "Loaded ~/.irbrc"
# Load Lobraries
require 'rubygems'
require 'wirble'
require 'irb/completion' 
# Enable Indentation in irb
IRB.conf[:AUTO_INDENT] = true 
# Enable Syntax Coloring 
Wirble.init
Wirble.colorize 
# get all the methods for an object that aren't basic methods from Object
class Object
def local_methods
(methods - Object.instance_methods).sort
end
end 


This customizes irb to give us syntax highlighting, tab completion, auto-indentation, and simple method enumeration.

Step 4: Installing Metasploit:

Step 5: Running Metasploit:
If you want to run msfconsole with the packaged Ruby, just run 'msfconsole' from bash.
Otherwise select your version like this: rvm 1.8.7
Then call msfconsole with the full path: /opt/metasploit/msf3/msfconsole


That's all there is to it. You are now ready to test your metasploit modules in various different versions of ruby all from the same box.

Once again, thanks to egypt and DarkOperator who provided a lot of this guidance to me.

Tuesday, 26 July 2011

Book Review: Metasploit a Penetration Tester's Guide

Earlier this month I picked up Metasploit: A Penetration Tester's Guide. I have, on multiple occasions, had the distinct pleasure to talk with two of the authours, Devon Kearns and Dave Kennedy. These two are shining examples of everything that is right with our industry. They are constantly giving back to the community at large and on an individual basis. They help others and share their knowledge and experience freely without any judgement. This book is just an extension of that behaviour. So enough about them, let's talk about the book.

The book seeks to give a complete overview of the Metasploit framework. This is a herculean task. They no doubt had to make hard decisions about what topics to cover as the most important. All things considered, I think they did an amazing job covering the most important facets. They start off with the basics of the framework: how it's laid out, auxiliary modules, scanners, exploits, getting shell, and what to do once you get a meterpreter session. Then we get to see some of the more advanced aspects, including writing custom fuzzers, developing exploits form scratch, and porting existing exploits into the framework. The book finishes up with a small example penetration test from start to finish. The only topic that they really seemed to skip was the Metasploit WMAP web scanning functionality. Although some Web Application topics were covered through the use of FastTrack.

The way the authours cover the subject matter is excellent. They show you each step, and call your attention to the most improtant parts along the way. It's as close as you can get to demonstration in a book, and it works very well in my opinion. They truly highlight what makes Metasploit great: it's flexibility. they show you how to modify existing modules or write your own. They show how you can use Metasploit in the actual exploit development process as well. Allowing you to birth new exploits completely in the Framework.

I have been using Metasploit since version 2, and I learned new things from this book. Whether it was small things like the SETG command, to some of the more advanced features I have never used before like msfpescan. Whether you are just starting to learn about Penetration Testing or you have been doing it from years, this book is a must read. Unless you are H.D. Moore you will be hard pressed not to get value from this book.

UPDATE: On a note of fairness, Metasploit Unleashed does cover WMAP functionality, even if it did not make it into the book.

Saturday, 23 July 2011

Metasploit: Windows User Profile Data

The Metasploit team as added one of my latest submissions. It is a Mixin for Post modules that allows you to enumerate the user profile information on a windows machine. A lot of the psot modules that I and others have written relied on static values for determining paths for things like the AppData folder. While this worked, it was hardcoded for the English language and didn't account for other possible changes to the system.

The new Msf::Post::Windows::UserProfiles mixin seeks to address this issue by using the registry. Two new Registry functions were added into every layer of Meterpreter: RegLoadKey() and RegUnloadKey(). These two functions, incidentally, should also work from a windows shell session.

The first step is to look in the Registry under HKLM/Software/Microsoft/WindowsNT/CurrentVersion/ProfileList
There are a series of subkeys here for the different SIDs that exist on the machine. When we look at each SID's subkey we will see a value called ProfileImagePath which is the user's root profile directory.


The first function in the mixin is read_profile_list(). This parses this key and all of it's subkeys. While it's doing that it reads through HKU to see which of these hives are already loaded and marks them appropriately.


This lets us know what users we should expect to see on the system, and where we can find their NTUSER.DAT file. If we look at the HKU key in our example, we see only the Administrator hive is currently loaded.


So, next the load_missing_hives() function takes all of the hives not currently loaded, and the paths to their registry hives, and loads each one that it can. Below we see the additional Hives loaded into HKU.


We then call parse_profiles(), which takes each hive and calls parse_profile() on it. This pulls the locations of directories like AppData, My Documents, Local Settingsd etc, and assembles it all. We can see the reg key under the user (HKU//Software/Microsoft/WindowsNT/CurrentVersion/Explorer/ShellFolders)



When we are done parsing this data, we may be done with the registry hives themselves, assuming we were only after filesystem data. Since we are done with the hives, we will want to unload them again to minimize our impact on the system. To do that we call unload_our_hives() This function unloads only the hives that we specifically loaded.

All of these functions are exposed in the mixin, meaning that module writers can use as much or as little of it as they want. However, if the module writer just wants to grab the profile directory data, they can just call grab_user_profiles() . This function will walk through the entire process for them, returning an array of hashes containing all of this data. Below we see an example/test module to demonstrate the UserProfile functionality.

-------------------------------------------

require 'msf/core'
require 'rex'
require 'msf/core/post/windows/user_profiles'


class Metasploit3 < Msf::Post
include Msf::Post::Windows::Registry
include Msf::Post::Windows::UserProfiles

def initialize(info={})
super( update_info( info,
'Name'          => 'Windows Load Reg Hive Test',
'Description'   => %q{ This module exists simply to test
the user profile enuemration mixin},
'License'       => MSF_LICENSE,
'Author'        => [ 'TheLightCosine '],
'Platform'      => [ 'windows' ],
'SessionTypes'  => [ 'meterpreter' ]
))

end

def run

grab_user_profiles().each do |user|
print_status("***Username: #{user['UserName']} SID: #{user['SID']}***")
print_status("Profile dir: #{user['ProfileDir']} LocalSettings dir: #{user['LocalSettings']}")
print_status("AppData: #{user['AppData']} LocalAppData: #{user['LocalAppData']}")
print_status("History: #{user['History']} Cookies: #{user['Cookies']} Favorites:  #{user['Favorites']} ")
print_status("MyDocs: #{user['MyDocs']} Desktop: #{user['Desktop']}")
end


end

end

-------------------------------

Here is what the output of running this test module would look like:

-------------------------------------------------------

meterpreter > run post/windows/gather/hive_test

[*] ***Username: Testuser1 SID: S-1-5-21-1462624396-1657036728-2537704546-1009***
[*] Profile dir: C:\Documents and Settings\Testuser1 LocalSettings dir: C:\Documents and Settings\Testuser1\Local Settings
[*] AppData: C:\Documents and Settings\Testuser1\Application Data LocalAppData: C:\Documents and Settings\Testuser1\Local Settings\Application Data
[*] History: C:\Documents and Settings\Testuser1\Local Settings\History Cookies: C:\Documents and Settings\Testuser1\Cookies Favorites:  C:\Documents and Settings\Testuser1\Favorites
[*] MyDocs: C:\Documents and Settings\Testuser1\My Documents Desktop: C:\Documents and Settings\Testuser1\Desktop
[*] ***Username: Testuser2 SID: S-1-5-21-1462624396-1657036728-2537704546-1010***
[*] Profile dir: C:\Documents and Settings\Testuser2 LocalSettings dir: C:\Documents and Settings\Testuser2\Local Settings
[*] AppData: C:\Documents and Settings\Testuser2\Application Data LocalAppData: C:\Documents and Settings\Testuser2\Local Settings\Application Data
[*] History: C:\Documents and Settings\Testuser2\Local Settings\History Cookies: C:\Documents and Settings\Testuser2\Cookies Favorites:  C:\Documents and Settings\Testuser2\Favorites
[*] MyDocs: C:\Documents and Settings\Testuser2\My Documents Desktop: C:\Documents and Settings\Testuser2\Desktop
[*] ***Username: Administrator SID: S-1-5-21-1462624396-1657036728-2537704546-500***
[*] Profile dir: C:\Documents and Settings\Administrator LocalSettings dir: C:\Documents and Settings\Administrator\Local Settings
[*] AppData: C:\Documents and Settings\Administrator\Application Data LocalAppData: C:\Documents and Settings\Administrator\Local Settings\Application Data
[*] History: C:\Documents and Settings\Administrator\Local Settings\History Cookies: C:\Documents and Settings\Administrator\Cookies Favorites:  C:\Documents and Settings\Administrator\Favorites
[*] MyDocs: C:\Documents and Settings\Administrator\My Documents Desktop: C:\Documents and Settings\Administrator\Desktop
-------------------------------------------------

My latest password extraction module for the SmartFTP client uses this new functionality. I have submitted a patch, that is still pending to implement this functionality across numerous other post modules. Using it to discover profile directories, and in some cases more thoroughly search the registry by loading missing userhives and then unloading them again when done. 

All told this should help make these modules able to function more completely on non-English language pack machines, as well as be more thorough in their searching for critical data in the system.

Tuesday, 12 July 2011

Take away the Tools

Indi303 recently had a post on twitter

Dear pentester: Throw away metasploit.... are u still a hacker? If you make excuses about why u are,but need it.. you aren't

It seems like a lot of people did not understand what he was saying, which rather proves the point I think.  He is not saying that Pen Tester should not use Metasploit, or that tools are bad. What he is saying here is that knowing how to use tools does not make you a good pentester. It makes you a script kiddie. We have been interviewing candidates for two new PenTest positions at my work, and I can tell you I feel this keenly.

During our in-person panel interview we ask a long series of questions designed to gauge depth. We ask a number of basic questions. These first sets of questions we are jsut looking for typical responses. These questions can range from simple things like: "how does traceroute actually work" or "What is ring0" to more complex questions like "How do you exploit Blind SQL Injection on Oracle" or "Name two places besides the saved return pointer that you could overwrite to control program execution". The results we have seen on these questions alone are somewhat disappointing and very mixed.

Then we get to where the wheels always seem to come off. This is where we ask the candidates to actually demonstrate the things they have claimed knowledge of. We ask things like "Write out an HTTP GET request on the whiteboard". Some of you are probably saying to yourselves "That is simple". I would agree, and yet no candidate has done it correctly yet. We draw out a URL with GET parameters and ask them "Rewrite this request with a blind SQL injection attack".

The fact is that when asked to demonstrate these skills and knowledge disciplines outside the context of any sort of tool or crutch. One of my colleagues across the wall, in Incident Response land, has suggested that I am being too harsh. That people who can only use tools still have some value. He is right, as far as it goes. what happens though, when you have secured the environment past the point where you can just run metasploit modules and pop boxes. When you need to find design flaws, or 0days to exploit systems. A click-monkey is of no real value there, except maybe fetching coffee.


none of this means you should throw your tools away. Metasploit is a valuable tool and a framework for pentesting.  Those of you who know me, of course know, that when i find something Metasploit doesn't do that I want it to, i try and add it.  So while I can operate without Metasploit, and have to often, i try and continually reduce those occurrence by submitting enhancements to Metasploit. In this way I am also giving back to the community. Something i would encourage EVERY pentester to do: If you see something Metasploit should do, but doesn't, write it and submit it!

Or at least open up a feature request on their Redmine interface.

Tuesday, 21 June 2011

Stealing CoreFTP Passwords with Metasploit

Well folks, I'm at it again. The next client to fall is the CoreFTP client. CoreFTP stores it's saved password in the Windows Registry.

They Can be found under HKEY_USERS\\Software\FTPWare\CoreFTP\Sites, with numbered keys for each saved site. The passwords are stored as ascii representations of their hex values(like most of the others we have seen). The ciphertext is encrypted using AES-128-ECB with a static key of "hdfzpysvpzimorhk".

So once again we rely on our ruby openssl implementations to do our decoding for us. First we pack the text from the registry:
               cipher =[encoded].pack("H*")
Then we set up our AES implementation:

                aes = OpenSSL::Cipher::Cipher.new("AES-128-ECB")
aes.padding = 0
aes.decrypt
aes.key = "hdfzpysvpzimorhk"
password= aes.update(cipher) + aes.final
return password

The  import thing to note here is the aes.padding property. This MUST be set to 0 or you will get bad decrypt errors. It took me quite a while to figure that out. The result, as usual, is an easily decrypted password. This once again highlights that static key encryption in a product like this is next to useless. Products that are going to save sensitive passwords should prompt a user to pick a master password, and sue that as an encryption key. This forever separates the encryption key from the software. It's the only real way to keep that data secure.

I submitted this module today, so it should hopefully get committed sometime in next couple of days. Keep your eyes peeled for post/windows/gather/enum_coreftp_passwords.rb

Sunday, 19 June 2011

SmartFTP Password Recovery with Metasploit - The details

So last night I briefly mentioned the new additions I submitted to Metasploit. It looks like they will get merged after the 3.7.2 Release. Metasploit is in a feature freeze at the moment for that release. I wanted to take the opportunity to discuss how the SmartFTP Password recovery module works. It might help other who want to write similar modules in the future.

The Module Can be seen from the Metasploit Website here:



So let's get the simple stuff out of the way first. We pull the OS information and the root System drive information from the Meterpreter stdapi. We then check the OS to see whether we need to be looking for "Documents and Settings" or "Users" off the system root. We then drop into the appropriate users directory and enumerate the individual user Directories. We build the Directory paths based off the combination of all of these factors.

The enum_subdirs function then takes each of these potential SmartFTP data folder paths. If the path does not exist, or we do not have permission to access it, it will throw an exception caught by the rescue statement and will move on to the next path. If it can access the path, then it will enumerate all of the items in that directory.  If the item ends in .xml then it is added to the list of XML files to be parsed. If it is not an XML file, it is assumed to be a directory and is recursively passed back to the enum_subdirs function. In the rare case that this item is not actually a directory, it should throw an exception which will still be caught by the rescue. Once everything has been recursively enumerated, we should have a list of xmlfiles in the session array @xmlfiles.

For each xml file in the array we then run get_xml.  In get_xml we first try to open the file for reading. If for any reason we cannot do that, we catch an exception  let the users know, and move on to the next file. If we can open it, then we read all of the data into memory and send it to the parse_xml function.  parse_xml uses the Metasploit rexml library to parse the XML. We pull the host, port, username, and encrypted password. If no encrypted password is found, we skip this item and move to the next one since there is no password to steal. Once we have the encrypted password we pass it to the real meat and potatoes, our decryption routine.

The first thing we do, is unpack this encoded data as a series of hex bytes. The string is in fact a series of bytes.  So if the encoded string is "9722972FC57CAE5A78DBD64E23968440C794" then it is actually \x97\x22\x97 etc.

So now let's take a moment to look at the new Railgun function definition I have added. These functions come from Advapi32.dll. This DLL is already defined in Railgun so we just have to add the functions to it's definition:


#Functions for Windows CryptoAPI
railgun.add_function('advapi32', 'CryptAcquireContextW', 'BOOL',[
['PDWORD', 'phProv', 'out'],
['PWCHAR', 'pszContainer', 'in'],
['PWCHAR', 'pszProvider', 'in'],
['DWORD', 'dwProvType', 'in'],
['DWORD', 'dwflags', 'in']])

railgun.add_function('advapi32', 'CryptCreateHash', 'BOOL',[
['LPVOID', 'hProv', 'in'],
['DWORD', 'Algid', 'in'],
['DWORD', 'hKey', 'in'],
['DWORD', 'dwFlags', 'in'],
['PDWORD', 'phHash', 'out']])

railgun.add_function('advapi32', 'CryptHashData', 'BOOL',[
['LPVOID', 'hHash', 'in'],
['PWCHAR', 'pbData', 'in'],
['DWORD', 'dwDataLen', 'in'],
['DWORD', 'dwFlags', 'in']])

railgun.add_function('advapi32', 'CryptDeriveKey', 'BOOL',[
['LPVOID', 'hProv', 'in'],
['DWORD', 'Algid', 'in'],
['LPVOID', 'hBaseData', 'in'],
['DWORD', 'dwFlags', 'in'],
['PDWORD', 'phKey', 'inout']])

railgun.add_function('advapi32', 'CryptDecrypt', 'BOOL',[
['LPVOID', 'hKey', 'in'],
['LPVOID', 'hHash', 'in'],
['BOOL', 'Final', 'in'],
['DWORD', 'dwFlags', 'in'],
['PBLOB', 'pbData', 'inout'],
['PDWORD', 'pdwDataLen', 'inout']])

railgun.add_function('advapi32', 'CryptDestroyHash', 'BOOL',[
['LPVOID', 'hHash', 'in']])

railgun.add_function('advapi32', 'CryptDestroyKey', 'BOOL',[
['LPVOID', 'hKey', 'in']])

railgun.add_function('advapi32', 'CryptReleaseContext', 'BOOL',[
['LPVOID', 'hProv', 'in'],
['DWORD', 'dwFlags', 'in']])

There is a lot going on here. So we'll take it a little slow.
For those who don't know, Railgun is a part of Meterpreter that allows a user to hook Windows libraries and access their functions. In this case we are hooking the Advapi32.dll to gain access to the Windows CryptoAPI(CAPI) functions.

CryptAcquireContextW is the Unicode version of the AcquireContext function. This creates the Cryptographic context we will be working in. The first parameter is a pointer to the provider object. the provider object is, in of itself, a pointer to a data structure that will be initialised by this function. So we pass it a pointer to a DWORD for the pointer to be placed in, and set it as an out parameter so the function will return the pointer information to us. We are not using the container object in this case, so we pass it nil. We then tell it what provider to use in this case it is the Microsoft Enhanced Cryptographic Provider. This is passed as a pointer to a string. We then pass it a value to tell it what type of provider to use. WinCrypt.h normally provides Constants for this, but since we don't have access to those constants we pass it the raw numerical value of that constant. In this case we are passing it the value for the RSA_FULL provider. Finally we pass it the appropriate flags. Like the provider type this expects a constant so we need to pass it a numerical value. We pass it CRYPT_VERIFY_CONTEXT(0xF0000000). For more details on the available flags I suggest you look at the MSDN Doc.

CryptCreateHash creates a hash object for us to user in much the same way that AcquireContext created a provider object. We pass it the provider object as the first parameter. Remembering that this object is a pointer to an abstracted in-memory data structure. Then we pass it the algorithm id for what kind of hash algorithm we will be using. Again, this is typically expecting a constant we don't have so we pass it a numerical value. If this hashing algorithm is expecting a key we pass it a key object. Since we are using md5 we pass it a 0 to tell it we are not using a key. We pass it a 0 for the flags. Finally we pass it a pointer to a place in memory for it to store the hash object. Just like the provider object, this is actually a pointer to a memory structure intialised by this function.

CryptHashData is what will actually create the hash for us and put it in the hash object. The first thing we do is pass it our hash object. We then pass it the data to be hashed. In this case we are hashing the string "SmartFTP". We then pass it the data length of 16, and again we pass it no flags with a 0. This is the first step to deriving our Encryption Key.

CryptDeriveKey is going to take our hash and derive an encryption key from it. We pass it our provider object, an integer value for our encryption algorithm(RC4), the Hash object, our flag, and a pointer to a key object. This key object works the same way as the hash and provider objects did before it. The function derives an RC4 key for us and puts it in the memory structure pointed to by our key object.

CryptDecrypt is where the magic finally happens. We pass it our key object as the first parameter. If the data was to be decrypted and hashed at the same time we would pass it a hash object. Since we do not want to hash the results we pass it a 0. The next parameter is whether this is the final section to be decrypted. We pass this a value as true. We pass no flags, and a pointer to the data to be decrypted. Finally  we pass it the length of the data to be decrypted.

The remaining three functions are eseentialy just garbage collection. They close out the memory structures we initalised along the way.

Some of the parameters in these function calls are still not set up in the most ideal fashion. One of the big tricks to remember is that in the end, a pointer is just a number. So even though ruby has no pointer, just treat them as a numbers and pass them back to LPVOIDS.  I will be smoothing out any wrinkles in these function defs soon, and adding the other CAPI functions that I didn't need for this particular module.

Once the decryption is complete. The module displays the results back to the console. It also reports the data back to the backend database. This means the credentials will be stored for the target machines. If you use MetaSploit Pro (which if you are a professional Penetration Tester, I cannot recommend it enough) this will be especially useful. If the remote machines are in your project scope, those credentials will show up in the host information, and can be used for further module usage.

So there you have it. I hope you find this detailed breakdown useful and/or informative. Stay tuned for further updates and developments. I am continuing on my goal of making it into the Metasploit.com Top contributors list, but I suspect I still have a ways to go.

Saturday, 18 June 2011

Windows Cryptography with Metasploit and SmartFTP Password Recovery

I have submitted two new additions to Metasploit tonight. The first is a series of function definitions for Railgun. These functions are some of the core Windows CryptoAPI functions. It is not a complete list yet. I only added the ones i needed to complete the other piece I'll tell you about in a minute. I will be working voer the next week to get all of the other CAPI functions defined within Metasploit Railgun. In addition to that, I will try to write a library that will server as an abstraction layer for these function calls. This library will wrap the Windows CAPI Functions as well as serve up alot of the same constants provided by the WinCrypt.h header file. I hope that this will make it easier for other module writers to make use of the windows CryptoAPI whenever they may need it in a Post Module.

The second bit of business is what actually spawned this work. I have submitted a module for Extracting/Recovering saved Passwords from the SmartFTP Client. Like the other modules I have submitted, it finds the passwords saved by users, decrypts them and reports them back to the backend database as well as to the display screen.

I want to take a moment to especially thank jduck and chao-mu who helped me talk through some things while I was working on this. As always the support of the community in the #metasploit IRC channel is amazing.

Thursday, 16 June 2011

Metasploit Activities

Well, i know i have been pretty quiet lately, so I thought i'd provide an update. I am very tempted to try and stake a claim on one of the Metasploit bounties , but I don't think I'm quite up to that challenge yet. Instead i will continue to work on some of my other Metasploit Projects:


  1. Build Railgun support for the Windows Crypto API(CAPI)
  2. Finish my SmartFTP password recovery module
  3. Build Meterperter NetStat support for Windows
  4. Some other things that have not solidifed yet.
I hope to get those first 3 items completely done in the next month or so. I want to have them completed and committed before Black Hat. It looks like i will be attending Black Hat courtesy of Rapid 7 this year, but only for the briefings. I unfortunately do not have the means at my disposal to stay for DefCon this year. I look forward to meeting some people in person.

Thursday, 2 June 2011

Stealing Passwords from mRemote

If you don't know mRemote is a tabbed remote connection manager for Windows. It can store and manage a number of different connections, chief among them RDP,VNC, and SSH. It is a popular tool among IT Support people who have to remote into a lot of machines.

When you save connections in mRemote it outputs all of that data into an XML report in your local AppData folder. The passwords are saved in an encrypted format, however this is trivial to circumvent. The passwords are encrypted with AES-128-CBC Rijndael Encryption, and then the IV is pre-pended to the encoded passwords and the whole thing is base64 encoded for output into the XML. The encryption key that is used is the md5 hash of the string "mR3m". So to decrypt these passwords we follow a simple process:

example password:  28kQ15DF4kdW34Mx2+fh+NWZODNSoSPek7ug+ILvyPE=

  1. Get the md5 hash of mR3m and convert it into byte values: \xc8\xa3\x9d\xe2\xa5\x47\x66\xa0\xda\x87\x5f\x79\xaa\xf1\xaa\x8c
  2. base64 decode the saved password data
  3. Take the first 16 bytes of the decoded data and set that as you Initialization vector(IV)
  4. Run AES-128-CBC Decryption feeding your Cipher Text(the remaining bytes from the decoded text), your IV (that first 16 bytes), and your key (\xc8\xa3\x9d\xe2\xa5\x47\x66\xa0\xda\x87\x5f\x79\xaa\xf1\xaa\x8c)
  5. You should get a decrypted password of: password1
Simple and easy, you are now ready to decrypt all of those delicious RDP,VNC, and SSH passwords. To make it all that much easier I have written a new Metasploit POST module that will find the XML files on a compromised machine and decrypt those passwords for you. I just submitted it to Redmine so it hasn't been added yet, but keep your eyes peeled. I suspect it will be in there soon.

Sunday, 1 May 2011

Metasploit Meterpreter Registry OpenKey and VNC PW Module

As you probably already know I've been doing some work with Metasploit post modules. This recent work has focused heavily on Registry functions. While doing this work I noticed a disturbing behavior. When Meterpreter checks to see if a key exists it was calling RegCreateKey instead of RegOpenKey.  RegCreateKey will attempt to create any and all keys in the supplied path that do not already exist. RegOpenKey, however, will not create the key if it doesn't already exist.

In Metasploit the registry.rb 'client-side' function is set up as a wrapper to the create_key function. Similarly the registry.c code for Meterpreter itself is set up this way. Calls to the OpenKey function were just passed on to the create_key function. I have now submitted a patch to correct this behaviour. The registry.rb function now sends a call via the meterpreter stdapi to the request_registry_open_key function. The request_registry_open_key function will appropriately call RegOpenKey instead. If/when this patch is accepted by the Metasploit team, it will make the Registry functions of Meterpreter much less invasive/noisy.


I have also gone ahead and submitted a patch for the enum_vnc_pw Post Module. The module as it currently stands will check the HKEY_Current_User keys for user-mode vnc passwords. However, this will only work if meterpreter is running udner the permissions of the user who is running the vnc server. I have added behaviour that will try to enumerate all userswith SIDs in HKEY_Users and then check each one that it can access, to see if it has stored VNC passwords. The get_reg function also had to be re-written to deal with possibile permissions issues if meterpreter does not have rights to access each users' registry. The best way to run this module will, of course be under SYSTEM priveleges as it will have access to every user. This will hopefully make the enum_vnc_pw module more effective at gathering it's data.

Wednesday, 27 April 2011

Stealing WinSCP Saved passwords

WinSCP is a popular SCP and SFTP client for Windows. Users of this tool have the option of storing 'sessions' along with saved passwords. There is an option within WinSCP to encrypt these password with a 'Master password'. This means the stored passwords will be AES256 encrypted. However, this option is NOT turned on by default. There are two ways these sessions will be stored by WinSCP.  The default behavior is to save them in the registry. They will be stored under HKEY_Current_User\Software\Martin Prikryl\WinSCP 2\Sessions.  The other option is to store them in an INI file, which will be located in the WinSCP install path.

When no master password is set, it is trivial to reverse the 'encryption' used on the stored passwords. It is a simple series of bitwise operations, using the username concatenated with the host name as sort of pseudo-key. To simplify the process of stealing these passwords I have created a Metasploit Post module /modules/post/windows/gather/enum-winscp_pwds.rb which was committed in the latest revision.

Once again, I am pleased to be contributing to the Metasploit project. I want to take a moment to especially thank egyp7, hdm, and jduck for their help and support. they put up with a lot of dumb questions while I was working on this module. it is only the third one I have created and the second to get committed. The Metasploit team is an amazing group of people to work with. They freely share their knowledge and experience and make Metasploit truly a community driven project, instead of just another piece of OSS. I look forward to continuing to contribute to the Metasploit project.

Tuesday, 12 April 2011

Updated Metasploit wishlist

A little while ago i posted my Metasploit Wishlist. i have pulled a new updated copy of this list, and added a Category field to help sort through it a little easier. I'll be spending some of my spare time going through this list and picking out things to port over. My first go around was a success and my first ported module:
http://metasploit.com/modules/auxiliary/dos/dhcp/isc_dhcpd_clientid

was committed. It may have been a little sloppy but i look forward to getting better as I go on. Mark my words, I'm going to get my name on that front page list.

Here's the new list

Thursday, 10 February 2011

Metasploit Framework Wishlist

Hello World!

I thought I would share something I have put together. I cross-referenced data about vulns inside http://www.exploit-db.com/ with data on whether those same vulnerabilities had a known exploit module inside the Metasploit Framework. Some of these vulnerabilities are probably quite old, and some of them not very relevant. That being said, if you are looking for some modules to contribute to the Metasploit project, this might be a good place to start.

A couple of caveats:

  1. I, in no way, represent Rapid 7 and the development team for Metasploit. I created this list for my own use to try and contribute, and am sharing the list in that spirit.
  2. The links from exploit-db create PoCs/Exploits that somebody worked hard on. If you port it to metasploit please remember to give credit to the original exploit author. They did all the hard work.