文件上传-文件头绕过getimagesize()

        小伙伴们大家好!本期为大家带来的是文件上传漏洞之文件头绕过getimagesize()。

目录

getimagesize()

GIF89a

绕过原理

实战演示

1、尝试上传webshell

2、使用连接工具连接webshell

总结


getimagesize()

        getimagesize() 函数用于获取图像大小及相关信息,成功返回一个数组,失败则返回 FALSE 并产生一条 E_WARNING 级的错误信息。

        getimagesize() 函数将测定任何 GIF,JPG,PNG,SWF,SWC,PSD,TIFF,BMP,IFF,JP2,JPX,JB2,JPC,XBM 或 WBMP 图像文件的大小并返回图像的尺寸以及文件类型及图片高度与宽度。

GIF89a

“GIF89a”经常作为“Graphics Interchange Format number 89A”的缩写来使用,中文表示:“图形交换格式编号89A”

一个GIF89a图形文件就是一个根据图形交换格式(GIF)89a版(1989年7 月发行)进行格式化之后的图形。

绕过原理

        绕过getimagesize()其实很简单,我们只需要在文件内容的起始位置加上一个GIF89a即可,这样我们的文件就会被认为是一个图片,php的getimagesize()函数也检测不出来我们构造的这个“虚假”的图片是无效的。

实战演示

我这里是自己写了两段代码,用phpstudy2018集成环境搭建的一个小靶场。phpstudy集成环境的搭建在我之前的文章PhpStudy环境搭建+MySQL基础+PHP操作数据库有讲解,供大家参考。

源码:

4.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="file04.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>

file04.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" || !getimagesize($_FILES['file']['tmp_name'])){
        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、尝试上传webshell

我们直接尝试上传带有一句话木马的webshell后门。

 发现有前端验证,我们直接鼠标点击右键检查,将前端验证的代码删除掉。

 点击上传!

上传失败,提示我们请上传png格式的文件,可能后端存在对文件类型的检验。

那我们就抓包改一下Content-Type试一下。

点击forward发送,回到浏览器查看页面响应情况。

发现依旧提示我们上传png格式的图片,猜测后端可能使用了getimagesize()函数来检查文件图片大小的信息。

这样我们再抓包将文件内容的开头加上GIF89a试一下。

之后点击Forward发送,再次回到浏览器查看响应。

OK,webshell上传成功。

2、使用连接工具连接webshell

webshell上传成功之后,接下来我们就使用webshell连接工具来连接我们成功上传的后门shell。

我这里使用的是中国蚁剑,大家使用其他的连接工具如菜刀、冰蝎等工具效果都是一样的。

测试成功之后,我们添加数据。

成功拿下站点!

总结

其实绕过getimagesize()函数的主要就是GIF89a的功能,由于GIF89a的加入,让getimageszie()函数也以为我们上传的webshell文件是图片,这样就轻松绕过了getimagesize()函数。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要在HTML页面中实现文件上传,需要使用HTML表单和服务器端脚本。以下是一个简单的示例: HTML代码: ``` <form action="upload.php" method="post" enctype="multipart/form-data"> <input type="file" name="fileToUpload" id="fileToUpload"> <input type="submit" value="上传文件" name="submit"> </form> ``` 解释: - `action` 属性指定表单数据提交到的服务器端脚本的URL。 - `method` 属性指定HTTP请求的方法。在文件上传中,必须使用POST方法。 - `enctype` 属性指定表单数据编码的类型。在文件上传中,必须使用 `multipart/form-data`。 在表单中包含一个 `input` 元素,类型为 `file`,它允许用户选择一个文件进行上传。文件选择后,表单提交时,文件将作为表单数据的一部分发送到服务器。文件数据可通过服务器端脚本进行处理。 服务器端脚本(示例中为PHP): ``` <?php $target_dir = "uploads/"; // 上传文件保存的目录 $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]); // 上传文件的完整路径 $uploadOk = 1; $imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION)); // 获取上传文件的扩展名 // 检查文件是否为真正的文件类型 if(isset($_POST["submit"])) { $check = getimagesize($_FILES["fileToUpload"]["tmp_name"]); if($check !== false) { echo "文件是一个" . $check["mime"] . "类型的文件。"; $uploadOk = 1; } else { echo "文件不是一个图片文件。"; $uploadOk = 0; } } // 检查文件是否已经存在 if (file_exists($target_file)) { echo "文件已经存在。"; $uploadOk = 0; } // 检查文件大小 if ($_FILES["fileToUpload"]["size"] > 500000) { echo "文件太大。"; $uploadOk = 0; } // 允许上传的文件类型 if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg" && $imageFileType != "gif" ) { echo "只允许上传 JPG, JPEG, PNG 和 GIF 文件。"; $uploadOk = 0; } // 检查上传过程中是否发生了错误 if ($uploadOk == 0) { echo "文件没有成功上传。"; // 如果一切正常,将文件从临时目录移动到目标目录 } else { if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) { echo "文件". basename( $_FILES["fileToUpload"]["name"]). "已经成功上传。"; } else { echo "上传过程中发生了错误。"; } } ?> ``` 解释: - `basename($_FILES["fileToUpload"]["name"])` 获取上传文件文件名。 - `strtolower(pathinfo($target_file,PATHINFO_EXTENSION))` 获取上传文件的扩展名。 - `move_uploaded_file()` 函数将上传的文件从临时目录移动到目标目录。 - 代码中的其他部分用于验证上传文件的大小、类型和是否已经存在。 以上是一个简单的文件上传示例,可以根据自己的需求进行修改和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你们de4月天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值