First pass of WMI support

Close but more to do.
This commit is contained in:
OJ
2014-01-16 13:47:46 +10:00
parent f3a13d89af
commit 69abffaff6
5 changed files with 184 additions and 4 deletions
@@ -5,6 +5,7 @@ require 'rex/post/meterpreter/extensions/extapi/window/window'
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/wmi/wmi'
module Rex
module Post
@@ -29,10 +30,11 @@ class Extapi < Extension
'name' => 'extapi',
'ext' => ObjectAliases.new(
{
'window' => Rex::Post::Meterpreter::Extensions::Extapi::Window::Window.new(client),
'service' => Rex::Post::Meterpreter::Extensions::Extapi::Service::Service.new(client),
'window' => Rex::Post::Meterpreter::Extensions::Extapi::Window::Window.new(client),
'service' => Rex::Post::Meterpreter::Extensions::Extapi::Service::Service.new(client),
'clipboard' => Rex::Post::Meterpreter::Extensions::Extapi::Clipboard::Clipboard.new(client),
'adsi' => Rex::Post::Meterpreter::Extensions::Extapi::Adsi::Adsi.new(client)
'adsi' => Rex::Post::Meterpreter::Extensions::Extapi::Adsi::Adsi.new(client),
'wmi' => Rex::Post::Meterpreter::Extensions::Extapi::Wmi::Wmi.new(client)
})
},
])
@@ -48,6 +48,13 @@ TLV_TYPE_EXT_ADSI_RESULT = TLV_META_TYPE_GROUP | (TLV_TYPE_E
TLV_TYPE_EXT_ADSI_MAXRESULTS = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 60)
TLV_TYPE_EXT_ADSI_PAGESIZE = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 61)
TLV_TYPE_EXT_WMI_DOMAIN = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 65)
TLV_TYPE_EXT_WMI_QUERY = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 66)
TLV_TYPE_EXT_WMI_FIELD = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 67)
TLV_TYPE_EXT_WMI_VALUE = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 68)
TLV_TYPE_EXT_WMI_FIELDS = TLV_META_TYPE_GROUP | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 69)
TLV_TYPE_EXT_WMI_VALUES = TLV_META_TYPE_GROUP | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 70)
end
end
end
@@ -0,0 +1,65 @@
# -*- coding: binary -*-
module Rex
module Post
module Meterpreter
module Extensions
module Extapi
module Wmi
###
#
# This meterpreter extension contains extended API functions for
# performing WMI queries.
#
###
class Wmi
def initialize(client)
@client = client
end
#
# Perform a generic wmi query against the target machine.
#
# @param query [String] The WMI query string.
# @param domain_name [String] Specify to target something other
# than 'cimv2'
#
# @returns [Hash] Array of field names with associated values.
#
def query(query, domain_name = nil)
request = Packet.create_request('extapi_wmi_query')
request.add_tlv(TLV_TYPE_EXT_WMI_DOMAIN, domain_name) unless domain_name.blank?
request.add_tlv(TLV_TYPE_EXT_WMI_QUERY, query)
response = client.send_request(request)
fields = []
fields_tlv = response.get_tlv(TLV_TYPE_EXT_WMI_FIELDS)
fields_tlv.each(TLV_TYPE_EXT_WMI_FIELD) { |f|
fields << f.value
}
values = []
response.each(TLV_TYPE_EXT_WMI_VALUES) { |r|
value = []
r.each(TLV_TYPE_EXT_WMI_VALUE) { |v|
value << v.value
}
values << value
}
return {
:fields => fields,
:values => values
}
end
attr_accessor :client
end
end; end; end; end; end; end
@@ -17,6 +17,7 @@ class Console::CommandDispatcher::Extapi
require 'rex/post/meterpreter/ui/console/command_dispatcher/extapi/service'
require 'rex/post/meterpreter/ui/console/command_dispatcher/extapi/clipboard'
require 'rex/post/meterpreter/ui/console/command_dispatcher/extapi/adsi'
require 'rex/post/meterpreter/ui/console/command_dispatcher/extapi/wmi'
Klass = Console::CommandDispatcher::Extapi
@@ -25,7 +26,8 @@ class Console::CommandDispatcher::Extapi
Klass::Window,
Klass::Service,
Klass::Clipboard,
Klass::Adsi
Klass::Adsi,
Klass::Wmi
]
include Console::CommandDispatcher
@@ -0,0 +1,104 @@
# -*- coding: binary -*-
require 'rex/post/meterpreter'
module Rex
module Post
module Meterpreter
module Ui
###
#
# Extended API WMI Querying interface.
#
###
class Console::CommandDispatcher::Extapi::Wmi
Klass = Console::CommandDispatcher::Extapi::Wmi
include Console::CommandDispatcher
# Zero indicates "no limit"
DEFAULT_MAX_RESULTS = 0
DEFAULT_PAGE_SIZE = 0
#
# List of supported commands.
#
def commands
{
"wmi_query" => "Perform a generic WMI query and return the results"
}
end
#
# Name for this dispatcher
#
def name
"Extapi: WMI Querying"
end
#
# Options for the wmi_query command.
#
@@wmi_query_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner" ],
"-d" => [ true, "Specify a domain (defaults to 'CIMV2')" ]
)
def wmi_query_usage
print(
"\nUsage: wmi_query <query string> [-d domain]\n\n" +
"Query the target and display the results.\n\n" +
@@wmi_query_opts.usage)
end
#
# Enumerate domain objects.
#
def cmd_wmi_query(*args)
args.unshift("-h") if args.length < 1
domain = nil
@@wmi_query_opts.parse(args) { |opt, idx, val|
case opt
when "-d"
domain = val
when "-h"
wmi_query_usage
return true
end
}
query = args.shift
objects = client.extapi.wmi.query(query, domain)
table = Rex::Ui::Text::Table.new(
'Header' => query,
'Indent' => 0,
'SortIndex' => 0,
'Columns' => objects[:fields]
)
objects[:values].each do |c|
table << c
end
print_line
print_line(table.to_s)
print_line("Total objects: #{objects[:results].length}")
print_line
return true
end
end
end
end
end
end