function stdapi_net_socket_tcp_shutdown($req, &$pkt)
 {
     my_print("doing stdapi_net_socket_tcp_shutdown");
     $cid_tlv = packet_get_tlv($req, TLV_TYPE_CHANNEL_ID);
     $c = get_channel_by_id($cid_tlv['value']);
     if ($c && $c['type'] == 'socket') {
         @socket_shutdown($c[0], $how);
         $ret = ERROR_SUCCESS;
     } else {
         $ret = ERROR_FAILURE;
     }
     return $ret;
 }
function read($resource, $len = null)
{
    global $udp_host_map;
    # Max packet length is magic.  If we're reading a pipe that has data but
    # isn't going to generate any more without some input, then reading less
    # than all bytes in the buffer or 8192 bytes, the next read will never
    # return.
    if (is_null($len)) {
        $len = 8192;
    }
    #my_print(sprintf("Reading from $resource which is a %s", get_rtype($resource)));
    $buff = '';
    switch (get_rtype($resource)) {
        case 'socket':
            if (array_key_exists((int) $resource, $udp_host_map)) {
                my_print("Reading UDP socket");
                list($host, $port) = $udp_host_map[(int) $resource];
                socket_recvfrom($resource, $buff, $len, PHP_BINARY_READ, $host, $port);
            } else {
                my_print("Reading TCP socket");
                $buff .= socket_read($resource, $len, PHP_BINARY_READ);
            }
            break;
        case 'stream':
            global $msgsock;
            # Calling select here should ensure that we never try to read from a socket
            # or pipe that doesn't currently have data.  If that ever happens, the
            # whole php process will block waiting for data that may never come.
            # Unfortunately, selecting on pipes created with proc_open on Windows
            # always returns immediately.  Basically, shell interaction in Windows
            # is hosed until this gets figured out.  See https://dev.metasploit.com/redmine/issues/2232
            $r = array($resource);
            my_print("Calling select to see if there's data on {$resource}");
            while (true) {
                $cnt = stream_select($r, $w = NULL, $e = NULL, 0);
                # Stream is not ready to read, have to live with what we've gotten
                # so far
                if ($cnt === 0) {
                    break;
                }
                # if stream_select returned false, something is wrong with the
                # socket or the syscall was interrupted or something.
                if ($cnt === false or feof($resource)) {
                    my_print("Checking for failed read...");
                    if (empty($buff)) {
                        my_print("----  EOF ON {$resource}  ----");
                        $buff = false;
                    }
                    break;
                }
                $md = stream_get_meta_data($resource);
                dump_array($md);
                if ($md['unread_bytes'] > 0) {
                    $buff .= fread($resource, $md['unread_bytes']);
                    break;
                } else {
                    #$len = 1;
                    $tmp = fread($resource, $len);
                    $buff .= $tmp;
                    if (strlen($tmp) < $len) {
                        break;
                    }
                }
                if ($resource != $msgsock) {
                    my_print("buff: '{$buff}'");
                }
                $r = array($resource);
            }
            my_print(sprintf("Done with the big read loop on {$resource}, got %d bytes", strlen($buff)));
            break;
        default:
            # then this is possibly a closed channel resource, see if we have any
            # data from previous reads
            $cid = get_channel_id_from_resource($resource);
            $c = get_channel_by_id($cid);
            if ($c and $c['data']) {
                $buff = substr($c['data'], 0, $len);
                $c['data'] = substr($c['data'], $len);
                my_print("Aha!  got some leftovers");
            } else {
                my_print("Wtf don't know how to read from resource {$resource}, c: {$c}");
                if (is_array($c)) {
                    dump_array($c);
                }
                break;
            }
    }
    my_print(sprintf("Read %d bytes", strlen($buff)));
    return $buff;
}
Esempio n. 3
0
function channel_read($chan_id, $len)
{
    $c = get_channel_by_id($chan_id);
    if ($c && is_resource($c[1])) {
        return read($c[1], $len);
    } else {
        return false;
    }
}