文件包含漏洞学习总结(结尾有实例)

什么是文件包含(漏洞)?

程序开发人员一般会把重复使用的函数写到单个文件中,需要使用某个函数时直接调用此文件,而无需再次编写,这种文件调用的过程一般被称为文件包含。

而此时如果没有对文件来源进行严格审查,就会导致任意文件读取或者任意命令执行,php中与文件包含的有关的函数为 include()require()include_once()require_once()它们的区别如下

include():只有代码执行到该函数时才会包含文件进来,发生错误时只给出一个警告并继续向下执行。
include_once():和include()功能相同,区别在于当重复调用同一文件时,程序只调用一次。
require():只要程序执行就包含文件进来,发生错误时会输出错误结果并终止运行。
require_once():和require()功能相同,区别在于当重复调用同一文件时,程序只调用一次。

文件包含(漏洞)分为本地包含和远程包含,想要远程包含时需要在php.ini配置文件中将allow_url_fopen设置为On(开启状态)

文件包含(漏洞)读文件

下面以DVWA文件包含模块进行举例,首先查看一下,low级别的源代码

<?php

// The page we wish to display
$file = $_GET[ 'page' ];

?> 

我们发现代码中没有对接收的page参数做任何处理,所以参数page是不可控的,这样就会造成任意文件读取和任意命令执行。先看一下原始的URL

http://www.test.com/DVWA-master/vulnerabilities/fi/?page=include.php

我们将include.php替换成不存在的来看一下,我们发现报错了,并且报出了绝对路径。如下图

接下来咱们构造如下URL,发现读取到了配置文件php.ini

http://www.test.com/DVWA-master/vulnerabilities/fi/?page=D:\phpstudy_pro\WWW\www.test.com\DVWA-master\php.ini

如下图

接下来咱们看一下中级别的源代码

<?php

// The page we wish to display
$file = $_GET[ 'page' ];

// Input validation
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", "..\"" ), "", $file );

?> 

 

 发现中级别的使用的str_replace函数,将http://  https://  ../ ..\  都替换为空格,也就是相当于删除了,但是这种安全措施,很容易绕过,你不是删除吗,那我双写,比如,可以将前面内容构造成htthttp://p://,这个函数将中间的http://删除,剩下的内容重新构成http://,这样就绕过了,执行了构造的恶意链接。

../和..\同样的道理,这是用这样的方式,如下图,咱们依然读取了php.ini配置文件。

下面咱们看一下高级别的源代码

<?php

// The page we wish to display
$file = $_GET[ 'page' ];

// Input validation
if( !fnmatch( "file*", $file ) && $file != "include.php" ) {
    // This isn't the page we want!
    echo "ERROR: File not found!";
    exit;
}

?> 

 

 发现高级别的源代码用了fnmatch函数,对page参数进行检查,如果包含的文件后缀,不是include.php,那就要求page参数的开头必须是file,服务器才会去包含相应的文件。这样咱们还是有方法绕过,可以使用file协议绕过。

再看一下最高级别的核心源代码

<?php

// The page we wish to display
$file = $_GET[ 'page' ];

// Only allow include.php or file{1..3}.php
if( $file != "include.php" && $file != "file1.php" && $file != "file2.php" && $file != "file3.php" ) {
    // This isn't the page we want!
    echo "ERROR: File not found!";
    exit;
}

?> 

最高级别的只允许包含上面三个文件,杜绝了文件包含漏洞。

包含日志文件

而有些时候,当发现本地包含漏洞,普通方法咱们都试过了发现无法利用,这时候可以换一种思路,可以利用日志文件来进行入侵。这里以Apache举例,Apache服务器运行后会生成两个日志文件,这两个文件是access.log(访问日志)和error.log(错误日志),apache的日志文件记录下我们的操作,并且写到访问日志文件access.log之中,这时候咱们直接在参数后加上咱们的恶意代码,页面报错,这个错误信息就会记录到access.log中,里面包含了恶意代码,这时候只要知道日志的路径,就可以使用菜刀链接,直接getwebshell。

PHP内置协议

  PHP带有很多内置URL风格的封装协议,可用于类似fopen()、copy()、file_exists()和filesize()的文件系统函数。有想要了解的小伙伴可以去PHP官网,官网地址http://www.php.net/manual/zh/wrappers.php。这里列出了一些

File://         /*访问本地文件系统*/
htt[p://      /*访问HTTP(s)网址*/
ftp://          /*访问FTP(s)URLS*/
php://         /*访问各个输入/输出流(I/o streams)
zlib://          /*压缩流*/
data://        /*数据(RFC2397)*/
ssh2://        /*Secure Shell 2*/
expect://     /*处理交互式的流*/

 

实例

说明:通过本地包含直接getwebshell,直接控制整个网站权限。大体思路:构造错误页面,里面包含恶意代码,利用thinkphp的错误日志功能,直接菜刀连接。

实战环境是,易酷cms2.5 源码下载地址 https://dl.pconline.com.cn/download/1492133.html

我已经下载源码,本地搭建好了,直接开始,搭建好的页面显示如图

接下来构造错误页面,如下图

接下来,在url的后面结合thinkphp的模板语法构造一句话为:{~eval($_POST[-7])},结果如下图,发现咱们的一句话木马已经插入到错误日志中

可以找到/temp/logs/目录下找到这个文件,咱们确定一下看看错误日志里到底有没有咱们的木马,发现确实存在

然后菜刀连接,成功getwebshell

 

 

 

 

posted @ 2020-04-26 21:12  小艾搞安全  阅读(1366)  评论(0编辑  收藏  举报