早些年,提到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:文件上传漏洞的更多相关文章
-
SpringMVC:学习笔记(8)——文件上传
SpringMVC--文件上传 说明: 文件上传的途径 文件上传主要有两种方式: 1.使用Apache Commons FileUpload元件. 2.利用Servlet3.0及其更高版本的内置支持. ...
-
Django:学习笔记(8)——文件上传
Django:学习笔记(8)——文件上传 文件上传前端处理 本模块使用到的前端Ajax库为Axio,其地址为GitHub官网. 关于文件上传 上传文件就是把客户端的文件发送给服务器端. 在常见情况(不 ...
-
springmvc学习笔记--支持文件上传和阿里云OSS API简介
前言: Web开发中图片上传的功能很常见, 本篇博客来讲述下springmvc如何实现图片上传的功能. 主要讲述依赖包引入, 配置项, 本地存储和云存储方案(阿里云的OSS服务). 铺垫: 文件上传是 ...
-
Javaweb学习笔记10—文件上传与下载
今天来讲javaweb的第10阶段学习.文件的上传与下载,今天主要说的是这个功能的实现,不用说了,听名字就是外行人也知道肯定很重要啦. 老规矩,首先先用一张思维导图来展现今天的博客内容. ...
-
Struts2学习笔记(十一)——文件上传
1.单文件上传 单文件上传步骤: 1)创建上传jsp页面 文件上传的表单提交方式必须是POST方式,编码类型:enctype="multipart/form-data",默认是 a ...
-
go web 第二天 学习笔记之文件上传
package main import ( "crypto/md5" "fmt" "html/template" "io" ...
-
SpringMVC学习笔记八:文件上传及多个文件上传
SpringMVC实现文件上传需要加入jar包,commons-fileupload-1.3.1.jar,commons-io-2.2.jar 项目目录树: pom.xml加入需要的包 <pro ...
-
Laravel 学习笔记之文件上传
自定义添加磁盘——upload 位置:config/filesystems.php 'disks' => [ 'local' => [ 'driver' => 'local', 'r ...
-
java学习笔记 (6) —— 文件上传
1.新建upload.jsp <%@ page language="java" import="java.util.*" pageEncoding=&qu ...
-
django学习笔记 多文件上传
习惯了flask 再用django 还是不太习惯 好麻烦 配置文件也忒多了 不过还是要学的 之前只能一个一个文件长传,这次试试多个文件 不适用django的forms创建表单 直接在html中使用 ...
随机推荐
-
sqlserver2008 函数1
SQL2008 表达式:是常量.变量.列或函数等与运算符的任意组合. 1. 字符串函数 函数 名称 参数 示例 说明 ascii(字符串表达式) select ascii('abc') 返回 97 返 ...
-
FZU2232 炉石传说 最大匹配
思路:正好是二分图,自己敌人,符合条件的随从二人组建边,最大匹配为n是符合要求 #include <cstdio> #include <cstring> #include &l ...
-
JQuery实战总结一 可编辑的表格
JQuery视频看完了,总结学习,记得在牛腩视频中的修改新闻类别的时候也使用了这样的可编辑的表格,使用到 了ajax控制界面不再刷新,轻松解决了类别的名称的修改的问题,直接提交到数据库,这样的方式比起 ...
-
python爬虫入门(三)XPATH和BeautifulSoup4
XML和XPATH 用正则处理HTML文档很麻烦,我们可以先将 HTML文件 转换成 XML文档,然后用 XPath 查找 HTML 节点或元素. XML 指可扩展标记语言(EXtensible Ma ...
-
PageRank算法初探
1. PageRank的由来和发展历史 0x1:源自搜索引擎的需求 Google早已成为全球最成功的互联网搜索引擎,在Google出现之前,曾出现过许多通用或专业领域搜索引擎.Google最终能击败所 ...
-
[ASP.NET] ASP.NET Identity 中 ClaimsIdentity 解析
各位好 : ) 最近筆者在嘗試改用ASP.NET Identity做為新系統的認證方式,發現到網路上給的資訊,不是很完整,所以做為一個工程屍,為了避免大家遇到一樣的問題.特地將一些有趣的地方記錄下來 ...
-
[笔试题]黑板上写下50个数字,选两个黑板上数字a和b,在黑板写|b-a|,剩下的数字?
在黑板上写下50个数字:1至50.在接下来的49轮操作中,每次做如下操作:选取两个黑板上的数字a和b,擦去,在黑板上写|b-a|.请问最后一次动作之后剩下的数字可能是什么?为什么?(不用写代码,不写原 ...
-
Android多个Module统一配置相同jar或库的版本号
Android Studio多个Module依赖相同的库时对版本号进行统一配置 在Android项目中,一个项目经常会依赖其他的一个甚至多个库文件,在这种依赖的时候最常见的一个错误就是 jar包版本不 ...
-
R中K-Means、Clara、C-Means三种聚类的评估
R中cluster中包含多种聚类算法,下面通过某个数据集,进行三种聚类算法的评估 # ============================ # 评估聚类 # # ================= ...
-
PAT天梯赛L3-015 球队食物链
读题可以知道是DFS,注意一点,题目说的是赢过,所以str[i][j]=‘W',那么g[i][j]=1,str[i][j]='L',g[j][i]=1 然后就常规搜索即可,还有一点就是剪枝,如果没有可 ...