文件包含
什么是文件包含
文件包含,为了更好地使用代码的重用性,引入了文件包含函数,可以通过文件包含函数将文件包含进来,直接使用包含文件的代码。
文件包含漏洞成因
在包含文件时候,为了灵活包含文件,将被包含文件设置为变量,通过动态变量来引入需要包含的文件时,用户可以对变量的值可控而服务器端未对变量值进行合理地校验或者校验被绕过,这样就导致了文件包含漏洞。通常文件包含漏洞出现在PHP语言中。
PHP文件包含的函数
- include( ) 当使用该函数包含文件时,只有代码执行到 include()函数时才将文件包含 进来,发生错误时之给出一个警告,继续向下执行。
- include_once( ) 功能与 Include()相同,区别在于当重复调用同一文件时,程序只调用一次
- require( ) require()与 include()的区别在于 require()执行如果发生错误,函数会输出 错误信息,并终止脚本的运行。
- require_once( ) 功能与 require()相同,区别在于当重复调用同一文件时,程序只调用一次。
敏感文件
Linux/Unix系统
/etc/passwd // 账户信息
/etc/shadow // 账户密码文件
/usr/local/app/apache2/conf/httpd.conf // Apache2默认配置文件
/usr/local/app/apache2/conf/extra/httpd-vhost.conf // 虚拟网站配置
/usr/local/app/php5/lib/php.ini // PHP相关配置
/etc/httpd/conf/httpd.conf // Apache配置文件
/etc/my.conf // mysql 配置文件
文件包含漏洞分类
本地文件包含漏洞
本地文件包含漏洞
当包含的文件在服务器本地时,就形成了本地文件包含。
比如:
<?php
$file = $_GET['file'];
include($file);
.....
get一个参数file
,来控制包含的$file的值 假如有一个file.txt
<?php
phpinfo();
?>
如果限制包含文件的后缀:
<?php
$file = $_GET['file'] . '.php';
echo $file;
include($file);
就无法找到要包含的文件 此时,可以使用%00
截断,不过需要有前提条件: 1). PHP版本 < 5.3 (不包括5.3) ; 2). PHPmagic_quotes_gpc = off
; 3).PHP对所接收的参数,如以上代码的$_GET['file']
未使用addslashes
函数
远程文件包含漏洞
远程文件包含漏洞
当包含的文件在远程服务器上时,就形成了远程文件包含。
远程文件包含的注意点:
1.需要php.ini中
allow_url_include = on
以及allow_url_fopen=on
2.所包含远程服务器的文件后缀不能与目标服务器语言相同。(比如目标服务器是php脚本语言解析的,那么包含的远程服务器文件后缀不能是
php
)
主要解释下第2点: 比如远程服务器文件yuancheng.php
,内容为:
<?php
phpinfo();
?>
再来看下目标服务器的信息 执行远程包含: 原因:因为目标服务器包含的代码并不是:
<?php phpinfo();?>
而是远程服务器执行完这段代码的源代码 因此,正确远程包含文件漏洞利用如下: 首先确保配置文件allow_url_fopen = On
以及allow_url_include = On
其次,修改文件后缀,只要不是php就行,比如后缀为.txt,然后再来包含。
文件包含漏洞之伪协议
1.data:text/plain 或 data:text/plain;base64 2.php://input 3.php://filter 4.file:// 5.zip://
data:text/plain
直接在对应URL参数内输出:data:text/plain,
需要执行的php代码
如果过滤了php,可以结合base64绕过
data:text/plain;base64,PD9waHAgc3lzdGVtKCJubCBmbGEqIik7Pz4=
php://input
php://input
可以访问请求的原始数据的只读流, 将post请求中的数据作为PHP代码执行
post内容可以直接写shell
<?php fputs(fopen('info.php','w'),'<?php phpinfo();?>')?>
php://filter
php://filter
该伪协议可以读取php文件代码以base64编码输出,比如说我们想读取一个php文件但是不想让它正常php执行代码后的结果,我们想要这个php文件的代码的时候就可以使用这个伪协议。
1、是格式 2、是可选参数,有read和write,字面意思就是读和写 3、是过滤器。主要有四种:字符串过滤器,转换过滤器,压缩过滤器,加密过滤器。filter里可以用一或多个过滤器(中间用|隔开),这也为解题提供了多种方法,灵活运用过滤器是解题的关键。这里的过滤器是把文件flag.php里的代码转换(convert)为base64编码(encode) 4、是必选参数,后面写你要处理的文件名读取源码:
?file=php://filter/read=convert.base64-encode/resource=flag.php //读取源码
?file=php://filter/read=string.toupper/resource=flag.php //大写转换
file://
file://
用于访问本地文件系统,且不受allow_url_fopen与allow_url_include的影响。
使用方法:file://文件绝对路径 file://C:/Windows/system.ini
zip://
zip://
可以访问压缩文件中的文件。但是需要绝对路径。
使用方法: zip://[压缩包绝对路径]%23(#和url规则冲突,所以用%23代替)[压缩文件内的文件名]
在本地创建一个文件2.php,并且压缩成2.zip压缩包,然后包含压缩包里面的文件:
日志文件include
- 原理:对网站进行访问时,日志文件会记录相关信息(请求头中的信息)
- 前提:知道日志文件所在,并能进行包含(通常在 ?file=/var/log/nginx/access.log)
- 步骤:
- 先访问网站在请求头中写入一句话(一般写在user-agent中)
- 然后通过post去尝试执行
- 执行成功后通过蚁剑连接得到shell
- 或者知道flag存在位置直接执行system命令