文件上传漏洞复现

文件上传漏洞复现笔记

预备知识

文件上传漏洞

  • WebShell:webshell就是以asp、php、jsp或者cgi等网页文件形式存在的一种命令执行环境,也可以将其称做为一种网页后门。黑客在入侵了一个网站后,通常会将asp或php后门文件与网站服务器WEB目录下正常的网页文件混在一起,然后就可以使用浏览器来访问asp或者php后门,得到一个命令执行环境,以达到控制网站服务器的目的。
  • 一句话木马:
    <?php @eval($_GET['cmd'];) ?>
    

以及许多类似的变种

  • 文件上传漏洞

文件上传漏洞是指由于程序员在对用户文件上传部分的控制不足或者处理缺陷,而导致的用户可以越过其本身权限向服务器上上传可执行的动态脚本文件。这里上传的文件可以是木马,病毒,恶意脚本或者WebShell等。这种攻击方式是最为直接和有效的,“文件上传”本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。

来源:https://www.jianshu.com/p/5ebba0482980

  • 文件上传漏洞的原因:
    • 没有对文件类型进行严格限制
    • 没有对上传文件或目录的权限进行严格限制

最简单的文件上传功能

upload.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>UPLOAD</title>
</head>
<body>

<form action="upload_file.php" method="post" enctype="multipart/form-data">
	<label for="file">文件名:</label>
	<input type="file" name="file" id="file"><br>
	<input type="submit" name="submit" value="提交">
</form>

</body>
</html>

upload_file.php

<html>
<head>
	<meta charset="utf-8">
	<title>上传文件</title>
</head>
<body>
<?php
if ($_FILES["file"]["error"] > 0)
{
	echo "错误:: " . $_FILES["file"]["error"] . "<br>";
}
else
{
	echo "上传文件名: " . $_FILES["file"]["name"] . "<br>";
	echo "文件类型: " . $_FILES["file"]["type"] . "<br>";
	echo "文件大小: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
	echo "文件临时存储的位置: " . $_FILES["file"]["tmp_name"] . "<br>";
	if (file_exists("upload/" . $_FILES["file"]["name"]))
	{
		echo $_FILES["file"]["name"] . " 文件已经存在。 ";
	}
	else
	{
		move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]);
		echo "文件存储在: " . "upload/" . $_FILES["file"]["name"];
	}
}
?>
</body>
</html>
  • 效果截图:
    效果截图
    image
  • PHP文件上传原理:PHP文件通过表单形式上传,上传后,服务器会暂存一个临时文件,并且会随机命名,防止文件名重复,之后再把临时文件保存到指定目录。

防御方法

  1. 前端限制:
    • 限制文件大小:通过隐藏的字段,可以设置文件最大上传大小,在服务端也可以检测,但是通过改包很容易绕过。
      <input type="hidden" name="MAX_FILE_SIZE" value="10000" />
      
    • 限制文件类型:
      <input type='file' name='myFile' accept='文件的MIME类型' />
      
    • MIME类型:MIME参考手册
  2. 后端限制
    • 限制文件大小:
      <html>
      <head>
      	<meta charset="utf-8">
      	<title>上传文件</title>
      </head>
      <body>
      <?php
      if ($_FILES["file"]["error"] > 0)
      {
      	echo "错误:: " . $_FILES["file"]["error"] . "<br>";
      }
      else
      {
      	if($_FILES["file"]["size"]/1024 < 0.02)
      	{
      		echo "上传文件名: " . $_FILES["file"]["name"] . "<br>";
      		echo "文件类型: " . $_FILES["file"]["type"] . "<br>";
      		echo "文件大小: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
      		echo "文件临时存储的位置: " . $_FILES["file"]["tmp_name"] . "<br>";
      		if (file_exists("upload/" . $_FILES["file"]["name"]))
      		{
      			echo $_FILES["file"]["name"] . " 文件已经存在。 ";
      		}
      		else
      		{
      			move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]);
      			echo "文件存储在: " . "upload/" . $_FILES["file"]["name"];
      		}
      	}
      	else
      	{
      		echo "<h1 style='color: rend;'>上传文件非法!</h1>";
      	}
      }
      ?>
      </body>
      </html>
      
      限制文件大小是十分有效的做法,通常限制越严格,被攻击的可能越小,但同样的,网站会严重牺牲用户体验。所以这种做法虽然被采取,但用处并不大。
    • 后缀名限制:
      $temp = explode(".", $_FILES["file"]["name"]);
      $extension = end($temp);
      // 后缀白名单
      $allowExts = array("gif","jpg","jpeg","png");
      if(($_FILES["file"]["size"]/1024 < 100) &&
      in_array($extension, $allowExts))
      {
          ...
      }
      else
      {
          ...
      }
      
    • 使用后缀名限制依然可能被绕过:
      • Apache服务器:可以借助文件包含漏洞来运行后缀名是图片后缀,但是内容是PHP代码的文件。如果网站的后缀过滤采用的是黑名单,并且过滤不严,那么后缀名pHp、PhP等可能能够绕过后台的过滤。
      • Nginx服务器:Nginx服务器的cgi.fix_pathinfo默认为1,使得其存在一个畸形解析的漏洞,我们上传一个文件a.jpg,然后以…/a.jpg/a.php,那么,服务器就会按php文件来解析a.jpg文件
        Nginx畸形解析
    • 通过文件头校验文件:
      • 文件头:

        文件头是位于文件开头的一段承担一定任务的数据,一般都在开头的部分。

        一般来说,文件头用于标识文件种类。

      • 常用的文件头:https://blog.csdn.net/bruce135lee/article/details/81077374

      • 绕过方法:伪造文件幻术,PHP会把php脚本标签之外的文字解析为纯文本,所以在标签之前加入伪造的幻数,即可绕过文件头检查。

    • 修改php文件执行权限:Apache服务器在文件上传目录下新建.htaccess文件,然后写入内容
      <Files ~ ".php">
          Order allow,deny
          Deny from all
      </Files>
      
    image
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值