文件上传-绕过文件类型

发布于:2022-12-11 ⋅ 阅读:(752) ⋅ 点赞:(0)

        小伙伴们大家好!本期为大家带来的文件上传漏洞之绕过文件类型。

目录

原理

Content-Type

PHP代码如何获取上传文件的类型

实战演示

1、测试网站的功能是否正常

2、尝试上传webshell

3、使用连接工具连接webshell 

总结


原理

        当我们上传文件的时候,不仅前端要检验我们文件的后缀名,后端也会检测我们的文件类型。通常后端会获取到我们上传文件的type属性即我们用burpsuite抓包时经常看到的content-type,它的值与后端获取到的文件type属性是一样的。既然我们可以抓到包,我们就可以修改包,我们通过抓包将数据包中的content-type改成后端代码可以接受的即可,这样就顺利绕过了后端文件类型的检验。

Content-Type

一般是指网页中存在的 Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件。

例如我们上传php文件抓取数据包Content-Type的值为application/octet-stream,而上传png图片抓取数据包Content-Type的值为image/png。

PHP代码如何获取上传文件的类型

前端form表单提交文件数据的时候,后端PHP代码使用$_FILES['file']['type'](这里的中括号里的“file”是form表单提交文件的name值)来获取上传文件的类型。

例如有以下php代码:

<?php
header('Content-type:text/html;charset=utf-8');
echo "<form action='test.php' method='post' enctype=\"multipart/form-data\">";
echo "<label>请上传文件:</label>";
echo "<input type='file' name='file'/><br/>";
echo "<input type='submit' value='上传'>";
echo "</form>";

if (isset($_FILES['file'])) {
    echo $_FILES['file']['type'];
}

可以看出来显示了文件的类型。如果上传的是png图片的话则是image/png。

实战演示

我这里呢是自己写的php+html代码,使用phpstudy集成环境搭建的站点,如果小伙伴们也想搭建的话可以看我之前的一篇讲解MySQL基础+PHP操作MySQL的文章——这里有讲解搭建phpstudy的详细内容。

源码:

2.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件后缀绕过</title>
</head>
<body>
<script type="text/javascript">
    function selectFile(file) {
        var filename = file.value;
        var mime = filename.toLowerCase().substr(filename.lastIndexOf("."));
        if (mime != ".png") {
            alert("请选择png格式的照片上传");
            file.outerHTML = file.outerHTML
        }
    }
</script>
<center>
    <form action="file02.php" method="post" enctype="multipart/form-data">
        <label for="file">请上传png格式图片:</label>
        <input type="file" name="file" id="file" onchange="selectFile(this)"/><br/>
        <input type="submit" name="submit" value="上传" />
    </form>
</center>
</body>
</html>

file02.php

<?php
header('Content-type:text/html;charset=utf-8');
if ($_FILES["file"]["error"] > 0) {
    echo "Return Code:".$_FILES["file"]["error"]."<br/>";
} else {
    if ($_FILES['file']['type'] != "image/png"){
        echo "<center><br/>";
        exit("请上传png格式的文件");
        echo "</center>";
    }
    echo "<center><br/>";
    echo "upload: ".$_FILES["file"]["name"]."<br/>";
    echo "type: ".$_FILES["file"]["type"]."<br/>";
    echo "size: ".($_FILES["file"]["size"] / 1024)."KB<br/>";
    echo "Temp file: ".$_FILES["file"]["tmp_name"]."<br/>";
    if (file_exists("upload/".$_FILES["file"]["name"])) {
        echo $_FILES["file"]["name"]." already exists. ";
    } else {
        move_uploaded_file($_FILES["file"]["tmp_name"],"upload/".$_FILES["file"]["name"]);
        echo "Stored in: "."upload/".$_FILES["file"]["name"];
    }
    echo "</center>";
}

1、测试网站的功能是否正常

首先我们还是测试站点是否真正的能够实现文件上传功能,我们先来上传一个png图片试一下。

文件上传成功,我们访问以下看是否能够显示出图片。

文件上传成功并被存储,站点功能正常。

2、尝试上传webshell

这里我们尝试上传一个名为2.php的一句话木马webshell。

点击确定之后发现有前端验证,我们直接鼠标右键点击检查,找到前端验证的代码,并将其删除掉。

接下来再尝试上传2.php

开始上传。

上传之后发现返回了一句请上传png格式的文件。

代表后端可能验证了文件的类型。

我们抓包修改一下content-type再试一下。

 修改完Content-Type之后点击forward。返回浏览器看页面的响应情况。

这样我们就成功的将我们的webshell成功的上传到了站点。

3、使用连接工具连接webshell 

成功上传webshell之后,接下来我们就要使用webshell连接工具来连接我们的webshell后门。我这里使用的是中国蚁剑,大家使用其他的连接工具菜刀哥斯拉都一样的。

连接成功直接添加数据即可。

这样我们就成功的拿下了这个站点。 

总结

后端文件类型的检验主要就是后端代码获取文件的type属性,而数据包中的Content-Type值又是与之对应,所以我们只需抓取数据包,将数据包中的Content-Type值修改为后端可接收的类型接口绕过。

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到