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.