diff --git a/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb b/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb index 35770e47f9..2dded94495 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb @@ -277,6 +277,22 @@ class Railgun def const(str) return constant_manager.parse(str) end + + # + # Return an array of windows constants names matching +winconst+ + # + + def const_reverse_lookup(winconst,filter_regex=nil) + return constant_manager.rev_lookup(winconst,filter_regex) + end + + # + # Returns an array of windows error code names for a given windows error code matching +err_code+ + # + + def error_lookup (err_code,filter_regex=/^ERROR_/) + return constant_manager.rev_lookup(err_code,filter_regex) + end # # The multi-call shorthand (["kernel32", "ExitProcess", [0]]) diff --git a/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb b/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb index 8d4fb7dab1..7f54dea079 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb @@ -70,6 +70,30 @@ class WinConstManager def is_parseable(s) return parse(s) != nil end + + # looks up a windows constant (integer or hex) and returns an array of matching winconstant names + # + # this function will NOT throw an exception but return "nil" if it can't find an error code + def rev_lookup(winconst, filter_regex=nil) + c = winconst.to_i # this is what we're gonna reverse lookup + arr = [] # results array + @consts.each_pair do |k,v| + arr << k if v == c + end + if filter_regex # this is how we're going to filter the results + # in case we get passed a string instead of a Regexp + filter_regex = Regexp.new(filter_regex) unless filter_regex.class == Regexp + # do the actual filtering + arr.select! do |item| + item if item =~ filter_regex + end + end + return arr + end + + def is_parseable(s) + return parse(s) != nil + end end end; end; end; end; end; end diff --git a/test/modules/post/test/railgun_reverse_lookups.rb b/test/modules/post/test/railgun_reverse_lookups.rb new file mode 100644 index 0000000000..513cebca38 --- /dev/null +++ b/test/modules/post/test/railgun_reverse_lookups.rb @@ -0,0 +1,58 @@ + +## +# $Id$ +## + +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# Framework web site for more information on licensing and terms of use. +# http://metasploit.com/framework/ +## + +require 'msf/core' +require 'rex' + +class Metasploit3 < Msf::Post + + def initialize(info={}) + super( update_info( info, + 'Name' => 'railgun_testing', + 'Description' => %q{ This module will test railgun code used in post modules}, + 'License' => MSF_LICENSE, + 'Author' => [ 'kernelsmith'], + 'Version' => '$Revision$', + 'Platform' => [ 'windows' ] + )) + register_options( + [ + OptInt.new("ERR_CODE" , [true, "Error code to reverse lookup", 0x420]), + OptInt.new("WIN_CONST", [true, "Windows constant to reverse lookup", 4]), + OptString.new("WCREGEX", [false,"Regexp to apply to constant rev lookup", "^SERVICE"]), + OptString.new("ECREGEX", [false,"Regexp to apply to error code lookup", "^ERROR_SERVICE_"]), + ], self.class) + + end + + def run + print_status("Running against session #{datastore["SESSION"]}") + print_status("Session type is #{session.type}") + + @rg = session.railgun + + print_status() + print_status("TESTING: const_reverse_lookup on #{datastore['WIN_CONST']} filtering by #{datastore['WCREGEX'].to_s}") + results = @rg.const_reverse_lookup(datastore['WIN_CONST'],datastore['WCREGEX']) + print_status("RESULTS: #{results.class} #{results.pretty_inspect}") + + print_status() + print_status("TESTING: error_lookup on #{datastore['ERR_CODE']} filtering by #{datastore['ECREGEX'].to_s}") + results = @rg.error_lookup(datastore['ERR_CODE'],datastore['ECREGEX']) + print_status("RESULTS: #{results.class} #{results.inspect}") + + print_status() + print_status("Testing Complete!") + end +end + +