[一道蓝鲸安全打卡Web分析] 文件上传引发的二次注入
蓝鲸打卡的一个 web 文件上传引发二次注入的题解和思考
蓝鲸文件管理系统
源代码地址:http://www.whaledu.com/course/290/task/2848/show
首先在设置文件里把所有的输入都采用 addslashes() 函数进行转义
upload.php关键代码
将上传的文件通过pathinfo()函数分成三个部分,[dirname] [filename] [extension]
然后进行后缀名检查,拼接后进行addslashes转义,查询是否存在这个文件
if($file["error"] == UPLOAD_ERR_OK) {
$name = basename($file["name"]);
$path_parts = pathinfo($name);
if(!in_array($path_parts["extension"], array("gif", "jpg", "png", "zip", "txt"))) {
exit("error extension");
}
$path_parts["extension"] = "." . $path_parts["extension"];
$name = $path_parts["filename"] . $path_parts["extension"];
$path_parts['filename'] = addslashes($path_parts['filename']);
$sql = "select * from `file` where `filename`='{$path_parts['filename']}' and `extension`='{$path_parts['extension']}'";
$fetch = $db->query($sql);
if($fetch->num_rows>0) {
exit("file is exists");
}
将文件名和后缀名插入数据库,将文件移动到相应文件夹并返回路径
if(move_uploaded_file($file["tmp_name"], ROOT . UPLOAD_DIR . $name)) {
$sql = "insert into `file` ( `filename`, `view`, `extension`) values( '{$path_parts['filename']}', 0, '{$path_parts['extension']}')";
$re = $db->query($sql);
if(!$re) {
echo 'error';
print_r($db->error);
exit;
}
$url = "/" . UPLOAD_DIR . $name;
echo "Your file is upload, url:
<a href=\"{$url}\" target='_blank'>{$url}</a><br/>
<a href=\"/\">go back</a>";
} else {
exit("upload error");
}
rename.php关键代码
查询旧文件是否存在
if(isset($req['oldname']) && isset($req['newname'])) {
$result = $db->query("select * from `file` where `filename`='{$req['oldname']}'");
if ($result->num_rows>0) {
$result = $result->fetch_assoc();
}else{
exit("old file doesn't exists!");
}
更新filename,将oldname和newname重组,查询oldname是否存在,然后将文件的oldname更新为newname
if($result) {
$req['newname'] = basename($req['newname']);
$re = $db->query("update `file` set `filename`='{$req['newname']}', `oldname`='{$result['filename']}' where `fid`={$result['fid']}");
if(!$re) {
print_r($db->errorInfo());
exit;
}
$oldname = ROOT.UPLOAD_DIR . $result["filename"].$result["extension"];
$newname = ROOT.UPLOAD_DIR . $req["newname"].$result["extension"];
if(file_exists($oldname)) {
rename($oldname, $newname);
$url = "/" . $newname;
echo "Your file is rename, url:
<a href=\"{$url}\" target='_blank'>{$url}</a><br/>
<a href=\"/\">go back</a>";
}
else{echo $oldname." not exists.";}
}
解题思路
在upload的过程中,全程进行转义并检测后缀,无法对上传进行操作,但是在rename的时候,没有对newname进行控制,这就可能会造成update的二次注入。
假设我们上传的文件是 1.jpg,然后进行改名,这个时候就会触发数据库的update语句
update `file` set `filename`='newname', `oldname`='1' where `fid`=fid
很明显,这里的newname和oldname都是我们可以控制的。
考虑上传问题,假设 1.jpg 是一句话木马,要把 1.jpg 变成 1.php,由于filename和extension分开操作,然后再合并,所有这里希望extension为空,这样在rename时可以将 1.jpg 变成 1.php。
构造文件 ',extension='',filename='1.jpg.jpg,上传,进行rename为 1.php,发现结果为 1.php.jpg
解释:
文件 ',extension='',filename='1.jpg.jpg 上传后的数据库如下
注意,rename过程中进行查询时,查询的结果 result['fid'] = 1,result['extension'] = 'jpg'
然后进行update,这时执行了构造的SQL语句,数据库如下
注意这两行代码
$oldname = ROOT.UPLOAD_DIR . $result["filename"].$result["extension"];
$newname = ROOT.UPLOAD_DIR . $req["newname"].$result["extension"];
在这个过程中,oldname=',extension='',filename='1.jpg.jpg,newname=1.php.jpg,由于oldname存在,所以最后变成1.php.jpg
解决
构造文件 ',extension='',filename='1.jpg.jpg,上传,进行rename为 1.jpg,结果为 1.jpg.jpg
构造另外一个一句话木马文件1.jpg,上传,数据库如下
再进行rename,传入的oldname为 1.jpg,newname为 1.php
进行查询的结果为 result['fid'] = 1,result['extension'] = ''
在最后的过程中,oldname = 1.jpg,newname = 1.php,这样就把上传的 1.jpg 变成了 1.php
[一道蓝鲸安全打卡Web分析] 文件上传引发的二次注入的更多相关文章
- Web Uploader文件上传插件
http://www.jq22.com/jquery-info2665 插件描述:WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现 ...
- Web Uploader文件上传&&使用webupload有感(黄色部分)
引入资源 使用Web Uploader文件上传需要引入三种资源:JS, CSS, SWF. <!--引入CSS--> <link rel="stylesheet" ...
- JAVA Web 之 struts2文件上传下载演示(二)(转)
JAVA Web 之 struts2文件上传下载演示(二) 一.文件上传演示 详细查看本人的另一篇博客 http://titanseason.iteye.com/blog/1489397 二.文件下载 ...
- 七牛云存储的 Javascript Web 前端文件上传
因为我的个人网站 restran.net 已经启用,博客园的内容已经不再更新.请访问我的个人网站获取这篇文章的最新内容,七牛云存储的 Web 前端文件上传 七牛是不错的云存储产品,特别是有免费的配额可 ...
- [web安全原理分析]-文件上传漏洞基础
简介 前端JS过滤绕过 待更新... 文件名过滤绕过 待更新 Content-type过滤绕过 Content-Type用于定义网络文件的类型和网页编码,用来告诉文件接收方以什么形式.什么编码读取这个 ...
- SpringMVC源码分析--文件上传
SpringMVC提供了文件上传的功能,接下来我们就简单了解一下SpringMVC文件上传的开发及大致过程. 首先需要在springMVC的配置文件中配置文件上传解析器 <bean id=&qu ...
- java+web+大文件上传下载
文件上传是最古老的互联网操作之一,20多年来几乎没有怎么变化,还是操作麻烦.缺乏交互.用户体验差. 一.前端代码 英国程序员Remy Sharp总结了这些新的接口 ,本文在他的基础之上,讨论在前端采用 ...
- java web(四)文件上传与下载
一.文件上传原理 1.在TCP/IP中,最早出现的文件上传机制是FTP ,它是将文件由客户端发送到服务器的标准机制:但是在jsp使用过程中不能使用FTP方法上传文件,这是由jsp运行机制所决定. 通 ...
- 用VSCode开发一个asp.net core2.0+angular5项目(5): Angular5+asp.net core 2.0 web api文件上传
第一部分: http://www.cnblogs.com/cgzl/p/8478993.html 第二部分: http://www.cnblogs.com/cgzl/p/8481825.html 第三 ...
随机推荐
- BZOJ 压力 tarjan 点双联通分量+树上差分+圆方树
题意 如今,路由器和交换机构建起了互联网的骨架.处在互联网的骨干位置的核心路由器典型的要处理100Gbit/s的网络流量. 他们每天都生活在巨大的压力之下.小强建立了一个模型.这世界上有N个网络设备, ...
- SpringBoot 监控中心
1,SpringBoot 监控中心: 针对微服务服务监控,服务器内存内存变化(对内存,线程,日志管理),检测服务配置连接地址是否可用(模拟访问,懒加载),故意将mysql 数据源连接密码写错,启动就会 ...
- 模块 jieba结巴分词库 中文分词
jieba结巴分词库 jieba(结巴)是一个强大的分词库,完美支持中文分词,本文对其基本用法做一个简要总结. 安装jieba pip install jieba 简单用法 结巴分词分为三种模式:精确 ...
- 学习笔记-EL
仅作为学习过程中笔记作用,若有不正确的地方欢迎指正 目标 理解El的作用,熟练使用EL EL表达式与Jsp表达式对比来记 EL表达式的概念,作用,语法 Jsp作用主要是用来实现动态网页的,而动态网页中 ...
- 解决ASP.NET MVC返回的JsonResult 中 日期类型数据格式问题,和返回的属性名称转为“驼峰命名法”和循环引用问题
DateTime类型数据格式问题 问题 在使用ASP.NET MVC 在写项目的时候发现,返回给前端的JSON数据,日期类型是 Date(121454578784541) 的格式,需要前端来转换一下才 ...
- B. Kvass and the Fair Nut
B. Kvass and the Fair Nut time limit per test 1 second memory limit per test 256 megabytes input sta ...
- 深入解读ES6系列(三)
ES6字符串 哈喽小伙伴们,爱说'废'话的Z又回来了,欢迎来到Super IT曾的博客时间,上一节说了函数,解构赋值和数组的五大将,这一节我们继续我们知识的海洋,一起奋斗不秃头!不足的欢迎提问留言. ...
- iOS开发|从小公司到进大厂,我的进阶学习之旅!
iOS高级进发 OC源码下载地址 苹果开发文档 如何阅读苹果开发文档 GNUstep是GNU计划的项目之一,它将Cocoa的OC库重新开源实现了一遍 源码地址:http://www.gnustep.o ...
- Qt实现学生学籍管理系统(文件存储)
记录 19:53 2019-07-30 在小学期学c++做完课设后萌生了把写完的课设放在博客上的想法,于是,我第一篇博客诞生了. 22:32:19 2019-07-30 下棋 16:04:56 201 ...
- LeetCode | 169. 多数元素
给定一个大小为 n 的数组,找到其中的多数元素.多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素. 你可以假设数组是非空的,并且给定的数组总是存在多数元素. 示例 1: 输入: [3,2,3] ...