早些年,提到Web渗透,或者搜索一些黑客教程

基本都会看到文件上传漏洞。

它是一个很经典的漏洞

但它本质其实不是一个漏洞,而是网站本身的上传文件功能

不过如果我们上传了Webshell,那么就成为了文件上传漏洞

打开我们的靶机Metasploitable:

这里就是我们可以测试文件上传的地方

我们先在低安全级别的情况下测试

首先我们上传一个正常的图片文件;

在目录中输入这行路径,就可以直接访问这个图片

如果我们上传的是有恶意的文件呢?

比如php一句话

成功执行

我们来分析下低安全级别的源代码:

 <?php
if (isset($_POST['Upload'])) { $target_path = DVWA_WEB_PAGE_TO_ROOT."hackable/uploads/";
$target_path = $target_path . basename( $_FILES['uploaded']['name']); if(!move_uploaded_file($_FILES['uploaded']['tmp_name'], $target_path)) { echo '<pre>';
echo 'Your image was not uploaded.';
echo '</pre>'; } else { echo '<pre>';
echo $target_path . ' succesfully uploaded!';
echo '</pre>'; } }
?>

为了配合分析,我用Burp把上传文件的Request复制下来

除了基本的HTTP头,需要注意的就是下面这部分内容

代码首先判断点击了Upload之后,找到DVWA根目录,然后重新定义新的路径

从请求获得文件名1.php赋值,如果目标文件不存在,显示失败,否则显示成功

代码缺陷:

(1)没有对文件类型进行过滤,本意接受上传图片,实际却可以上传php

(2)对文件大小限制为100K其实没有用。由于是客户端进行限制的,利用截断,我们可以轻易修改文件大小限制

进一步利用:找到Kali自带的webshell

修改IP:

上传这个文件之后

利用nc监听,轻易得到shell:

结论:低安全级别的文件上传做得很差,可以轻易利用漏洞

接下来看看中安全级别

上传png文件成功,但是上传php文件失败

想要找到失败原因,需要查看源代码:

 <?php
if (isset($_POST['Upload'])) { $target_path = DVWA_WEB_PAGE_TO_ROOT."hackable/uploads/";
$target_path = $target_path . basename($_FILES['uploaded']['name']);
$uploaded_name = $_FILES['uploaded']['name'];
$uploaded_type = $_FILES['uploaded']['type'];
$uploaded_size = $_FILES['uploaded']['size']; if (($uploaded_type == "image/jpeg") && ($uploaded_size < 100000)){ if(!move_uploaded_file($_FILES['uploaded']['tmp_name'], $target_path)) { echo '<pre>';
echo 'Your image was not uploaded.';
echo '</pre>'; } else { echo '<pre>';
echo $target_path . ' succesfully uploaded!';
echo '</pre>'; }
}
else{
echo '<pre>Your image was not uploaded.</pre>';
}
}
?>

可以从代码中分析得出结论:这里需要验证type、name和size三个变量才能成功上传

而且要求type必须是image/jpeg,所以哪怕是png格式的图片也无法上传

绕过:

既然要验证type,name,size那么我就修改

由于size和name符合要求,那么我就修改type为image/jpeg:使用Burp截断

修改后上传,成功!

进一步可以上传木马等等

总结:中等安全等级的文件上传也可以轻易饶过,不过需要截断工具

但其实已经可以防止最低级的脚本小子

接下来看看高级安全等级:

源代码

 <?php
if (isset($_POST['Upload'])) { $target_path = DVWA_WEB_PAGE_TO_ROOT."hackable/uploads/";
$target_path = $target_path . basename($_FILES['uploaded']['name']);
$uploaded_name = $_FILES['uploaded']['name'];
$uploaded_ext = substr($uploaded_name, strrpos($uploaded_name, '.') + 1);
$uploaded_size = $_FILES['uploaded']['size']; if (($uploaded_ext == "jpg" || $uploaded_ext == "JPG" || $uploaded_ext == "jpeg" || $uploaded_ext == "JPEG") && ($uploaded_size < 100000)){ if(!move_uploaded_file($_FILES['uploaded']['tmp_name'], $target_path)) { echo '<pre>';
echo 'Your image was not uploaded.';
echo '</pre>'; } else { echo '<pre>';
echo $target_path . ' succesfully uploaded!';
echo '</pre>'; }
} else{ echo '<pre>';
echo 'Your image was not uploaded.';
echo '</pre>'; }
} ?>

分析可以看出:

这里对扩展名进行了过滤,所以上传1.php会失败,修改类型也会失败

而我们如果把1.php修改成1.php.jpg

上传成功!
也可以成功被利用

总结:高安全级别也不安全

怎么更安全呢?

一般文件前一部分字节表明这个文件的类型,我们可以来验证这一部分内容

因为哪怕修改了扩展名也无法修改这里的文件类型,我们可以用mimetype命令来验证

所以,这种方式更安全

那么有没有办法绕过这种更安全的方式呢?

有,保留表明文件类型的字节,修改文件实际内容

比如这里,我们不改变第一行,只改变后边的内容

但是想要使用会报错,因为服务器端没有用php去解释这个文件

所以我们把1.png修改为1.php.png,再发送过去,服务器端就会去解释了

然后就可以像上面一样利用了

那么,文件上传漏洞是无法被解决了吗?

不是

安全有效的解决办法:

目录权限限制,不给执行权限

sudo chmod a-x uploads/

对保存上传文件的文件夹进行权限限制

Kali学习笔记38:文件上传漏洞的更多相关文章

  1. SpringMVC:学习笔记(8)——文件上传

    SpringMVC--文件上传 说明: 文件上传的途径 文件上传主要有两种方式: 1.使用Apache Commons FileUpload元件. 2.利用Servlet3.0及其更高版本的内置支持. ...

  2. Django:学习笔记(8)——文件上传

    Django:学习笔记(8)——文件上传 文件上传前端处理 本模块使用到的前端Ajax库为Axio,其地址为GitHub官网. 关于文件上传 上传文件就是把客户端的文件发送给服务器端. 在常见情况(不 ...

  3. springmvc学习笔记--支持文件上传和阿里云OSS API简介

    前言: Web开发中图片上传的功能很常见, 本篇博客来讲述下springmvc如何实现图片上传的功能. 主要讲述依赖包引入, 配置项, 本地存储和云存储方案(阿里云的OSS服务). 铺垫: 文件上传是 ...

  4. Javaweb学习笔记10—文件上传与下载

    今天来讲javaweb的第10阶段学习.文件的上传与下载,今天主要说的是这个功能的实现,不用说了,听名字就是外行人也知道肯定很重要啦. 老规矩,首先先用一张思维导图来展现今天的博客内容.       ...

  5. Struts2学习笔记(十一)——文件上传

    1.单文件上传 单文件上传步骤: 1)创建上传jsp页面 文件上传的表单提交方式必须是POST方式,编码类型:enctype="multipart/form-data",默认是 a ...

  6. go web 第二天 学习笔记之文件上传

    package main import ( "crypto/md5" "fmt" "html/template" "io" ...

  7. SpringMVC学习笔记八:文件上传及多个文件上传

    SpringMVC实现文件上传需要加入jar包,commons-fileupload-1.3.1.jar,commons-io-2.2.jar 项目目录树: pom.xml加入需要的包 <pro ...

  8. Laravel 学习笔记之文件上传

    自定义添加磁盘——upload 位置:config/filesystems.php 'disks' => [ 'local' => [ 'driver' => 'local', 'r ...

  9. java学习笔记 (6) —— 文件上传

    1.新建upload.jsp <%@ page language="java" import="java.util.*" pageEncoding=&qu ...

  10. django学习笔记 多文件上传

    习惯了flask 再用django 还是不太习惯  好麻烦 配置文件也忒多了 不过还是要学的 之前只能一个一个文件长传,这次试试多个文件 不适用django的forms创建表单 直接在html中使用 ...

随机推荐

  1. java多线程管理 concurrent包用法详解

        我们都知道,在JDK1.5之前,Java中要进行业务并发时,通常需要有程序员独立完成代码实现,当然也有一些开源的框架提供了这些功能,但是这些依然没有JDK自带的功能使用起来方便.而当针对高质量 ...

  2. python中的列表及numpy数组排序

    一.列表排序  # python中对列表排序有sort.sorted两种方法,其中sort是列表内置方法,其帮助文档如下:In [1]: help(sorted) Help on built-in f ...

  3. python 解方程 和 python 距离公式实现

    解方程参考:https://zhuanlan.zhihu.com/p/24893371 缺点太慢,最后还是自己算了 距离公式参考:https://www.cnblogs.com/denny402/p/ ...

  4. Object.defineProperty(obj,prop,descriptor)使用

    初步实现了数据自动映射到html中,动态修改对象数据也很自动更新到html.提供addProps方法-添加新增属性并初始化自动监听代码如下: 1.abserve.js:包含数据监听实现.类似jquer ...

  5. ASCII, Unicode, UTF-8, 8进制, 16进制等各种编码学习理解笔记

    字符编码的发展历史 Unicode和UTF-8有何区别? 在这个问题下的于洋的最高票回答中,比较完整地介绍了字符编码的发展历史,为了便于记忆,再次简要概括一番. 一个字节:最初一个字节的标准是混乱的, ...

  6. Python Day 7

    阅读目录 内容回顾: 数据类型相互转换: 字符编码: ##内容回顾 #1.深浅拷贝 ls = [1, 'a', [10]] 值拷贝:直接赋值 ls1 = ls, ls中的任何值发生改变,ls1中的值都 ...

  7. LCD调试

    (1) 液晶显示模式 并行:MCU接口.RGB接口.Vysnc接口 串行:SPI接口.MDDI接口 (2) 屏幕颜色 实质上即为色阶的概念.色阶是表示手机液晶显示屏亮度强弱的指数标准,也就是通常所说的 ...

  8. python操作Redis安装、支持存储类型、普通连接、连接池

    一.python操作redis安装和支持存储类型 安装redis模块 pip3 install redis 二.Python操作Redis之普通连接 redis-py提供两个类Redis和Strict ...

  9. python for data analysis 2nd 读书笔记(一)

    第一章相对简单,也么有什么需要记录的内容,主要用到的工具的简介及环境配置,粗略的过一下就行了.下面我们开始第二章的学习 CHAPTER 22.2Python Language Basics, IPyt ...

  10. CUDA 计算线程索引的一般公式

    CUDA thread index: int blockId = blockIdx.z * (gridDim.x*gridDim.y)                    + blockIdx.y ...