Land #2689, getenv

bug/bundler_fix sprint-D00
James Lee 2013-11-26 23:33:25 -06:00
commit 25b1ec5b75
No known key found for this signature in database
GPG Key ID: 2D6094C7CEA0A321
6 changed files with 351 additions and 199 deletions

View File

@ -78,6 +78,14 @@ define("TLV_TYPE_VALUE_DATA", TLV_META_TYPE_RAW | 1012);
define("TLV_TYPE_COMPUTER_NAME", TLV_META_TYPE_STRING | 1040);
define("TLV_TYPE_OS_NAME", TLV_META_TYPE_STRING | 1041);
define("TLV_TYPE_USER_NAME", TLV_META_TYPE_STRING | 1042);
define("TLV_TYPE_ARCHITECTURE", TLV_META_TYPE_STRING | 1043);
define("TLV_TYPE_LANG_SYSTEM", TLV_META_TYPE_STRING | 1044);
# Environment
define("TLV_TYPE_ENV_VARIABLE", TLV_META_TYPE_STRING | 1100);
define("TLV_TYPE_ENV_VALUE", TLV_META_TYPE_STRING | 1101);
define("TLV_TYPE_ENV_GROUP", TLV_META_TYPE_GROUP | 1102);
define("DELETE_KEY_FLAG_RECURSIVE", (1 << 0));
@ -573,6 +581,41 @@ function stdapi_sys_config_getuid($req, &$pkt) {
}
}
if (!function_exists('stdapi_sys_config_getenv')) {
register_command('stdapi_sys_config_getenv');
function stdapi_sys_config_getenv($req, &$pkt) {
my_print("doing getenv");
$variable_tlvs = packet_get_all_tlvs($req, TLV_TYPE_ENV_VARIABLE);
# If we decide some day to have sys.config.getenv return all env
# vars when given an empty search list, this is one way to do it.
#if (empty($variable_tlvs)) {
# # We don't have a var to look up, return all of 'em
# $variables = array_keys($_SERVER);
#} else {
# $variables = array();
# foreach ($variable_tlvs as $tlv) {
# array_push($variables, $tlv['value']);
# }
#}
foreach ($variable_tlvs as $name) {
$canonical_name = str_replace(array("$","%"), "", $name['value']);
$env = getenv($canonical_name);
if ($env !== FALSE) {
$grp = "";
$grp .= tlv_pack(create_tlv(TLV_TYPE_ENV_VARIABLE, $canonical_name));
$grp .= tlv_pack(create_tlv(TLV_TYPE_ENV_VALUE, $env));
packet_add_tlv($pkt, create_tlv(TLV_TYPE_ENV_GROUP, $grp));
}
}
return ERROR_SUCCESS;
}
}
# Unimplemented becuase it's unimplementable
#if (!function_exists('stdapi_sys_config_rev2self')) {
#register_command('stdapi_sys_config_rev2self');

View File

@ -152,7 +152,9 @@ TLV_TYPE_GATEWAY_STRING = TLV_META_TYPE_STRING | 1442
TLV_TYPE_ROUTE_METRIC = TLV_META_TYPE_UINT | 1443
TLV_TYPE_ADDR_TYPE = TLV_META_TYPE_UINT | 1444
##
# Socket
##
TLV_TYPE_PEER_HOST = TLV_META_TYPE_STRING | 1500
TLV_TYPE_PEER_PORT = TLV_META_TYPE_UINT | 1501
TLV_TYPE_LOCAL_HOST = TLV_META_TYPE_STRING | 1502
@ -161,7 +163,9 @@ TLV_TYPE_CONNECT_RETRIES = TLV_META_TYPE_UINT | 1504
TLV_TYPE_SHUTDOWN_HOW = TLV_META_TYPE_UINT | 1530
##
# Registry
##
TLV_TYPE_HKEY = TLV_META_TYPE_UINT | 1000
TLV_TYPE_ROOT_KEY = TLV_TYPE_HKEY
TLV_TYPE_BASE_KEY = TLV_META_TYPE_STRING | 1001
@ -172,15 +176,26 @@ TLV_TYPE_VALUE_TYPE = TLV_META_TYPE_UINT | 1011
TLV_TYPE_VALUE_DATA = TLV_META_TYPE_RAW | 1012
TLV_TYPE_TARGET_HOST = TLV_META_TYPE_STRING | 1013
##
# Config
##
TLV_TYPE_COMPUTER_NAME = TLV_META_TYPE_STRING | 1040
TLV_TYPE_OS_NAME = TLV_META_TYPE_STRING | 1041
TLV_TYPE_USER_NAME = TLV_META_TYPE_STRING | 1042
TLV_TYPE_ARCHITECTURE = TLV_META_TYPE_STRING | 1043
##
# Environment
##
TLV_TYPE_ENV_VARIABLE = TLV_META_TYPE_STRING | 1100
TLV_TYPE_ENV_VALUE = TLV_META_TYPE_STRING | 1101
TLV_TYPE_ENV_GROUP = TLV_META_TYPE_GROUP | 1102
DELETE_KEY_FLAG_RECURSIVE = (1 << 0)
##
# Process
##
TLV_TYPE_BASE_ADDRESS = TLV_META_TYPE_UINT | 2000
TLV_TYPE_ALLOCATION_TYPE = TLV_META_TYPE_UINT | 2001
TLV_TYPE_PROTECTION = TLV_META_TYPE_UINT | 2002
@ -367,6 +382,18 @@ def stdapi_sys_config_getuid(request, response):
response += tlv_pack(TLV_TYPE_USER_NAME, getpass.getuser())
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_sys_config_getenv(request, response):
for env_var in packet_enum_tlvs(request, TLV_TYPE_ENV_VARIABLE):
pgroup = ''
env_var = env_var['value'].translate(None, '%$')
env_val = os.environ.get(env_var)
if env_val:
pgroup += tlv_pack(TLV_TYPE_ENV_VARIABLE, env_var)
pgroup += tlv_pack(TLV_TYPE_ENV_VALUE, env_val)
response += tlv_pack(TLV_TYPE_ENV_GROUP, pgroup)
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_sys_config_sysinfo(request, response):
uname_info = platform.uname()

View File

@ -680,6 +680,30 @@ function tlv_pack($tlv) {
return $ret;
}
function tlv_unpack($raw_tlv) {
$tlv = unpack("Nlen/Ntype", substr($raw_tlv, 0, 8));
$type = $tlv['type'];
my_print("len: {$tlv['len']}, type: {$tlv['type']}");
if (($type & TLV_META_TYPE_STRING) == TLV_META_TYPE_STRING) {
$tlv = unpack("Nlen/Ntype/a*value", substr($raw_tlv, 0, $tlv['len']));
}
elseif (($type & TLV_META_TYPE_UINT) == TLV_META_TYPE_UINT) {
$tlv = unpack("Nlen/Ntype/Nvalue", substr($raw_tlv, 0, $tlv['len']));
}
elseif (($type & TLV_META_TYPE_BOOL) == TLV_META_TYPE_BOOL) {
$tlv = unpack("Nlen/Ntype/cvalue", substr($raw_tlv, 0, $tlv['len']));
}
elseif (($type & TLV_META_TYPE_RAW) == TLV_META_TYPE_RAW) {
$tlv = unpack("Nlen/Ntype", $raw_tlv);
$tlv['value'] = substr($raw_tlv, 8, $tlv['len']-8);
}
else {
my_print("Wtf type is this? $type");
$tlv = null;
}
return $tlv;
}
function packet_add_tlv(&$pkt, $tlv) {
$pkt .= tlv_pack($tlv);
}
@ -689,27 +713,10 @@ function packet_get_tlv($pkt, $type) {
# Start at offset 8 to skip past the packet header
$offset = 8;
while ($offset < strlen($pkt)) {
$tlv = unpack("Nlen/Ntype", substr($pkt, $offset, 8));
$tlv = tlv_unpack(substr($pkt, $offset));
#my_print("len: {$tlv['len']}, type: {$tlv['type']}");
if ($type == ($tlv['type'] & ~TLV_META_TYPE_COMPRESSED)) {
#my_print("Found one at offset $offset");
if (($type & TLV_META_TYPE_STRING) == TLV_META_TYPE_STRING) {
$tlv = unpack("Nlen/Ntype/a*value", substr($pkt, $offset, $tlv['len']));
}
elseif (($type & TLV_META_TYPE_UINT) == TLV_META_TYPE_UINT) {
$tlv = unpack("Nlen/Ntype/Nvalue", substr($pkt, $offset, $tlv['len']));
}
elseif (($type & TLV_META_TYPE_BOOL) == TLV_META_TYPE_BOOL) {
$tlv = unpack("Nlen/Ntype/cvalue", substr($pkt, $offset, $tlv['len']));
}
elseif (($type & TLV_META_TYPE_RAW) == TLV_META_TYPE_RAW) {
$tlv = unpack("Nlen/Ntype", substr($pkt, $offset, 8));
$tlv['value'] = substr($pkt, $offset+8, $tlv['len']-8);
}
else {
my_print("Wtf type is this? $type");
$tlv = null;
}
return $tlv;
}
$offset += $tlv['len'];
@ -719,6 +726,27 @@ function packet_get_tlv($pkt, $type) {
}
function packet_get_all_tlvs($pkt, $type) {
my_print("Looking for all tlvs of type $type");
# Start at offset 8 to skip past the packet header
$offset = 8;
$all = array();
while ($offset < strlen($pkt)) {
$tlv = tlv_unpack(substr($pkt, $offset));
if ($tlv == NULL) {
break;
}
my_print("len: {$tlv['len']}, type: {$tlv['type']}");
if (empty($type) || $type == ($tlv['type'] & ~TLV_META_TYPE_COMPRESSED)) {
my_print("Found one at offset $offset");
array_push($all, $tlv);
}
$offset += $tlv['len'];
}
return $all;
}
##
# Functions for genericizing the stream/socket conundrum
##

View File

@ -33,6 +33,29 @@ class Config
return client.unicode_filter_encode( response.get_tlv_value(TLV_TYPE_USER_NAME) )
end
#
# Returns a hash of requested environment variables, along with their values.
# If a requested value doesn't exist in the response, then the value wasn't found.
#
def getenv(var_names)
request = Packet.create_request('stdapi_sys_config_getenv')
var_names.each do |v|
request.add_tlv(TLV_TYPE_ENV_VARIABLE, v)
end
response = client.send_request(request)
result = {}
response.each(TLV_TYPE_ENV_GROUP) do |env|
var_name = env.get_tlv_value(TLV_TYPE_ENV_VARIABLE)
var_value = env.get_tlv_value(TLV_TYPE_ENV_VALUE)
result[var_name] = var_value
end
return result
end
#
# Returns a hash of information about the remote computer.
#

View File

@ -117,6 +117,11 @@ TLV_TYPE_USER_NAME = TLV_META_TYPE_STRING | 1042
TLV_TYPE_ARCHITECTURE = TLV_META_TYPE_STRING | 1043
TLV_TYPE_LANG_SYSTEM = TLV_META_TYPE_STRING | 1044
# Environment
TLV_TYPE_ENV_VARIABLE = TLV_META_TYPE_STRING | 1100
TLV_TYPE_ENV_VALUE = TLV_META_TYPE_STRING | 1101
TLV_TYPE_ENV_GROUP = TLV_META_TYPE_GROUP | 1102
DELETE_KEY_FLAG_RECURSIVE = (1 << 0)
# Process

View File

@ -88,6 +88,7 @@ class Console::CommandDispatcher::Stdapi::Sys
"getpid" => "Get the current process identifier",
"getprivs" => "Attempt to enable all privileges available to the current process",
"getuid" => "Get the user that the server is running as",
"getenv" => "Get one or more environment variable values",
"kill" => "Terminate a process",
"ps" => "List running processes",
"reboot" => "Reboots the remote computer",
@ -106,6 +107,7 @@ class Console::CommandDispatcher::Stdapi::Sys
"getpid" => [ "stdapi_sys_process_getpid" ],
"getprivs" => [ "stdapi_sys_config_getprivs" ],
"getuid" => [ "stdapi_sys_config_getuid" ],
"getenv" => [ "stdapi_sys_config_getenv" ],
"kill" => [ "stdapi_sys_process_kill" ],
"ps" => [ "stdapi_sys_process_get_processes" ],
"reboot" => [ "stdapi_sys_power_exitwindows" ],
@ -277,6 +279,30 @@ class Console::CommandDispatcher::Stdapi::Sys
print_line("Server username: #{client.sys.config.getuid}")
end
def cmd_getenv(*args)
vars = client.sys.config.getenv(args)
if vars.length == 0
print_error("None of the specified environment variables were found/set.")
else
table = Rex::Ui::Text::Table.new(
'Header' => 'Environment Variables',
'Indent' => 0,
'SortIndex' => 1,
'Columns' => [
'Variable', 'Value'
]
)
vars.each do |var, val|
table << [ var, val ]
end
print_line
print_line(table.to_s)
end
end
#
# Clears the event log
#