added 'reg' command to meterpreter

git-svn-id: file:///home/svn/incoming/trunk@3047 4d416f70-5f16-0410-b530-b9f4589650da
unstable
Matt Miller 2005-11-18 01:12:45 +00:00
parent cbbce06ee0
commit 011f4411f2
3 changed files with 201 additions and 0 deletions

View File

@ -203,6 +203,56 @@ class Registry
return values
end
#
# Return the key value associated with the supplied string. This is useful
# for converting HKLM as a string into its actual integer representation.
#
def self.key2str(key)
if (key == 'HKLM' or key == 'HKEY_LOCAL_MACHINE')
return HKEY_LOCAL_MACHINE
elsif (key == 'HKCU' or key == 'HKEY_CURRENT_USER')
return HKEY_CURRENT_USER
elsif (key == 'HKU' or key == 'HKEY_USERS')
return HKEY_USERS
elsif (key == 'HKCR' or key == 'HKEY_CLASSES_ROOT')
return HKEY_CLASSES_ROOT
elsif (key == 'HKEY_CURRENT_CONFIG')
return HKEY_CURRENT_CONFIG
elsif (key == 'HKEY_PERFORMANCE_DATA')
return HKEY_PERFORMANCE_DATA
elsif (key == 'HKEY_DYN_DATA')
return HKEY_DYN_DATA
else
raise ArgumentError, "Unknown key: #{key}"
end
end
#
# Returns the integer value associated with the supplied registry value
# type (like REG_SZ).
#
def self.type2str(type)
return REG_SZ if (type == 'REG_SZ')
return REG_DWORD if (type == 'REG_DWORD')
return REG_BINARY if (type == 'REG_BINARY')
return REG_EXPAND_SZ if (type == 'REG_EXPAND_SZ')
return REG_NONE if (type == 'REG_NONE')
return nil
end
#
# Split the supplied full registry key into its root key and base key. For
# instance, passing HKLM\Software\Dog will return [ HKEY_LOCAL_MACHINE,
# 'Software\Dog' ]
#
def self.splitkey(str)
if (str =~ /^(.+?)\\(.*)$/)
[ key2str($1), $2 ]
else
raise ArgumentError, "Invalid key: #{key}"
end
end
end
end; end; end; end; end; end

View File

@ -128,6 +128,13 @@ class RegistryKey
return self.client.sys.registry.query_value(self.hkey, name)
end
#
# Delete the supplied registry value.
#
def delete_value(name)
return self.client.sys.registry.delete_value(self.hkey, name)
end
##
#
# Serializers

View File

@ -16,6 +16,9 @@ class Console::CommandDispatcher::Stdapi::Sys
include Console::CommandDispatcher
#
# Options used by the 'execute' command.
#
@@execute_opts = Rex::Parser::Arguments.new(
"-a" => [ true, "The arguments to pass to the command." ],
"-c" => [ false, "Channelized I/O (required for interaction)." ],
@ -26,6 +29,16 @@ class Console::CommandDispatcher::Stdapi::Sys
"-m" => [ false, "Execute from memory." ],
"-d" => [ true, "The 'dummy' executable to launch when using -m." ])
#
# Options used by the 'reg' command.
#
@@reg_opts = Rex::Parser::Arguments.new(
"-d" => [ true, "The data to store in the registry value." ],
"-h" => [ true, "Help menu." ],
"-k" => [ true, "The registry key path (E.g. HKLM\Software\Foo)." ],
"-t" => [ true, "The registry value type (E.g. REG_SZ)." ],
"-v" => [ true, "The registry value name (E.g. Stuff)." ])
#
# List of supported commands.
#
@ -37,6 +50,7 @@ class Console::CommandDispatcher::Stdapi::Sys
"kill" => "Terminate a process",
"ps" => "List running processes",
"reboot" => "Reboots the remote computer",
"reg" => "Modify and interact with the remote registry",
"sysinfo" => "Gets information about the remote system, such as OS",
"shutdown" => "Shuts down the remote computer",
}
@ -183,6 +197,136 @@ class Console::CommandDispatcher::Stdapi::Sys
client.sys.power.reboot
end
#
# Modifies and otherwise interacts with the registry on the remote computer
# by allowing the client to enumerate, open, modify, and delete registry
# keys and values.
#
def cmd_reg(*args)
# Extract the command, if any
cmd = args.shift
if (args.length == 0)
args.unshift("-h")
end
# Initiailze vars
key = nil
value = nil
data = nil
@@reg_opts.parse(args) { |opt, idx, val|
case opt
when "-h"
print_line(
"Usage: reg [command] [options]\n\n" +
"Interact with the target machine's registry.\n" +
@@reg_opts.usage +
"Commands:\n\n" +
"\tenumkey Enumerate the supplied registry key [-k <key>]\n" +
"\tcreatekey Create the supplied registry key [-k <key>]\n" +
"\tdeletekey Delete the supplied registry key [-k <key>]\n" +
"\tsetval Set a registry value [-k <key> -v <val> -d <data>]\n" +
"\tdeleteval Delete the supplied registry value [-k <key> -v <val>]\n\n")
return false
when "-k"
key = val
when "-v"
value = val
when "-d"
data = val
end
}
# All commands require a key.
if (key == nil)
print_error("You must specify a key path (-k)")
return false
end
# Split the key into its parts
root_key, base_key = client.sys.registry.splitkey(key)
begin
# Rock it
case cmd
when "enumkey"
open_key = client.sys.registry.open_key(root_key, base_key)
print_line(
"Enumerating: #{key}\n")
keys = open_key.enum_key
vals = open_key.enum_value
if (keys.length > 0)
print_line(" Keys (#{keys.length}):\n")
keys.each { |subkey|
print_line("\t#{subkey}")
}
print_line
end
if (vals.length > 0)
print_line(" Values (#{vals.length}):\n")
vals.each { |val|
print_line("\t#{val.name}")
}
print_line
end
if (vals.length == 0 and keys.length == 0)
print_line("No children.")
end
when "createkey"
open_key = client.sys.registry.create_key(root_key, base_key)
print_line("Successfully created key: #{key}")
when "deletekey"
client.sys.registry.delete_key(root_key, base_key)
print_line("Successfully deleted key: #{key}")
when "setval"
if (value == nil or data == nil)
print_error("You must specify both a value name and data (-v, -d).")
return false
end
type = "REG_SZ" if (type == nil)
open_key = client.sys.registry.open_key(root_key, base_key, KEY_WRITE)
open_key.set_value(value, client.sys.registry.type2str(type), data)
print_line("Successful set #{value}.")
when "deleteval"
if (value == nil)
print_error("You must specify a value name (-v).")
return false
end
open_key = client.sys.registry.open_key(root_key, base_key, KEY_WRITE)
open_key.delete_value(value)
print_line("Successfully deleted #{value}.")
else
print_error("Invalid command supplied: #{cmd}")
end
ensure
open_key.close if (open_key)
end
end
#
# Displays information about the remote system.
#