危险的文件夹上传框

网址:http://www.cnblogs.com/index-html/p/dialog-phishing.html

文件对话框

文件上传对话框是一直以来就存在的网页控件。

到了 HTML5 时代,增加了更多的功能,例如支持文件多选。Chrome 甚至还支持「上传文件夹」这一私有特征:

<input type="file" webkitdirectory />

在给用户方便的同时,其安全隐患也逐渐出现。用户平时在下载时,理所当然的弹出的是保存对话框,因此常常不仔细看就做出了选择。

这极有可能被攻击者所利用。一些恶意网站在用户点击下载时,故意弹出一个上传对话框。只要用户一疏忽,就把选中的文件夹给上传了!

下载对话框

上传对话框

当然,仅仅依靠默认的上传,这种攻击方式仍有较大难度。因为整个文件夹可能非常大,上传需要很久的时间。

如果用户等了半天也没看见下载进度,或许就会刷新重试,甚至放弃了。

选择即授权

然而,HTML5 带来了一个新的规范 —— File API,允许脚本访问文件。

但由于沙箱限制,脚本无法访问任何一个本地文件,除非用户主动授权。如何授权?最常见的,就是「上传对话框」了。

事实上,如今的上传对话框,早已不是从前「选择哪个文件」的功能,而是「允许脚本访问哪个文件」的权限申请!只不过界面上没有提示罢了。

例如,一个传统的文件上传控件。当用户选中文件后,即可通过 File API 读取文件内容:

<input id="dialog" type="file" />
<script>
dialog.onchange = function(e){
var reader = new FileReader();
reader.onload = function(){
console.log(this.result);
};
reader.readAsText(this.files[0]);
};
</script>

或许你已注意到,File 位于files[]而不是file,这正是给文件夹预留的!

在 Chrome 里,上传控件只要加上 webkitdirectory 属性,就变成文件夹选择框。这时一旦用户选中某个文件夹,瞬间就赐予脚本访问整个文件夹的权限!

<input id="dialog" type="file" webkitdirectory />
<script>
dialog.onchange = function(e){
var files = this.files;
var table = {};

for(var i = 0;i < files.length;i++){
var f = files[i];
var dt = newDate(f.lastModified);

table[i] = {
path: f.webkitRelativePath,
size: f.size,
modified: dt.toLocaleString()
};
}

console.table(table);
};
</script>

演示:http://www.etherdream.com/funnyscript/dialog_phishing/demo1.html

于是,用户本想将文件保存在桌面上,结果却将桌面上的所有资料,被攻击者的脚本拿到!

优化上传

一旦脚本可主动访问,我们可以用更灵活的方式处理这些文件,无需再用传统落后的方式上传。我们可以直接在前端分析出「有价值」的文件,例如:

  • 备注文件、脚本、批处理、电子表格等,很可能存有一些敏感信息,而且体积小价值大,优先将其上传;
  • 图片则可通过 canvas 缩放,先传较小的缩略图。当接收端发现有意义时,再传输原文件。
  • 对于一些体积较大但意义不大的文件,则可以直接忽略。

由于 HTTP 上传是没有压缩的,因此在传输文本文件时效率很低。我们可以借助 Flash 内置的LZMA压缩算法,极大提升传输效率。如果不支持 Flash,也可以使用asm.js版的 LZMA 压缩器,配合Worker线程在后台压缩和传输。

同时,将多个小文件合并后再压缩,可进一步提高压缩率。再多开几个连接,上传速度即可大幅提升。

续点上传

不过即使再优化,仍有传不完的可能。因此,我们得将没传完的内容储存起来,当用户再次回来时,继续传输。

得益于 HTML5 的 Storage API,这不难实现。

事实上,当用户授权了某个文件夹时,我们首先要做的不是发送,而是读出文件夹内容,立即备份到 Storage 里。毕竟,文件的读取需要用户主动配合,机会是非常珍贵的;而 Storage 的访问则无需任何条件。

当备份完成后,再从 Storage 里一块一块的读取、发送、删除。这样,即使中途页面刷新或关闭了,下次回来时,仍能从 Storage 中继续。

考虑到每个域的 Storage 容量有限,我们可以使用iframe嵌入多个不同域的页面,然后通过postMessage进行数据的分发和汇总,这样就不受容量限制了。

将数据存放在 Storage 里还有另一个好处,即使用户永不回来,但数据仍持久保存着。只要以后一旦进入其他的站点,只要是我们可控的,仍有机会继续上传。(例如将用户引到我们布置了 XSS 的站点上)

延长上传

在之前《延长 XSS 生命期》 中介绍过,可以使用各种黑魔法来提升脚本有效期。

利用这个原理,即使当前页面关闭,其他关联的页面也能继续上传。事实上,除了文中提到的方法,如今还有一个新的 API —— SharedWorker,它可以让 Worker 共享于多个页面,只要有一个存在,线程就不会停止。可以让续点时丢失的数据更少。

视觉欺骗

由于上传控件有着独特的界面,怎样才能让用户不小心点到呢?万能的方法是点击劫持(Clickjacking)。

不过本场景无需这么麻烦,只需简单的调用控件的click方法就可以了。

<a href = "ed2k://|file|xxx.avi"id="download">高速下载</a>
<script>
var uploader =document.createElement(‘input‘);
uploader.type = ‘file‘;
uploader.webkitdirectory = true;

download.onclick = function(e){
uploader.click();// 弹出上传对话框
e.preventDefault();// 屏蔽下载对话框
};
</script>

演示:http://www.etherdream.com/funnyscript/dialog_phishing/demo2.html

我们屏蔽超链接的默认行为,用上传控件的点击事件取而代之,即可召唤出「文件夹授权」对话框了!

同时,为了不让眼亮的人发现对话框上的破绽,我们使用一些第三方的下载方式,例如电驴、迅雷等等,让人们误以为就是这样的。

当然,这只是一个小例子。只要页面做的真实,下载内容引人入胜,用户自然就会中招。

后记

本以为 webkitdirectory 的这个私有属性很快就会放弃,至少是更强的安全提示。不过至少现在也没更新,因此上网时还是要多加留心,看清楚了再做决定。

当然,这篇只是最早的「交互欺骗」探索。事实上,深入挖掘会发现可利用点远不仅此。

如今的浏览器在视觉、音频上的体验已经非常完善,攻击者甚至可以在网页里,高度模拟一个本地应用的交互效果。让用户误以为是浏览器之外的程序弹出的界面,从而进行钓鱼。

时间: 2024-08-28 23:59:38

危险的文件夹上传框的相关文章

Web大文件(夹)上传(断点续传)控件-Xproer.HttpUploader6

版权所有 2009-2017荆门泽优软件有限公司 保留所有权利 官方网站:http://www.ncmem.com/ 产品首页:http://www.ncmem.com/webapp/up6.2/index.asp 在线演示:http://www.ncmem.com/products/up6.3/index.htm 产品介绍:http://www.cnblogs.com/xproer/archive/2012/10/26/2741264.html 升级日志:http://www.cnblogs.

js文件夹上传

文件夹上传:从前端到后端 文件上传是 Web 开发肯定会碰到的问题,而文件夹上传则更加难缠.网上关于文件夹上传的资料多集中在前端,缺少对于后端的关注,然后讲某个后端框架文件上传的文章又不会涉及文件夹.今天研究了一下这个问题,在此记录. 先说两个问题: 是否所有后端框架都支持文件夹上传? 是否所有浏览器都支持文件夹上传? 第一个问题:YES,第二个问题:NO 只要后端框架对于表单的支持是完整的,那么必然支持文件夹上传.至于浏览器,截至目前,只有 Chrome 支持. 如果需要其它的浏览器支持则需要

文件夹上传插件webupload插件

在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 先说下要求: PC端全平台支持,要求支持Windows,Mac,Linux 支持所有浏览器. 支持文件批量上传 支持文件夹上传,且要求在服务端保留层级结构.文件夹数量要求支持到10W. 支持大文件断点续传,要求刷新浏览器,重启浏览器,重启电脑后仍然能够继续上传.文件大小要求能够支持到50个G. 支持自动加载本地文件,要求能够自动加载指定的本地文件. 支持文件批量下载,要求不要在服

vue文件夹上传组件选哪个好?

一. 功能性需求与非功能性需求 要求操作便利,一次选择多个文件和文件夹进行上传:支持PC端全平台操作系统,Windows,Linux,Mac 支持文件和文件夹的批量下载,断点续传.刷新页面后继续传输.关闭浏览器后保留进度信息. 支持文件夹批量上传下载,服务器端保留文件夹层级结构,服务器端文件夹层级结构与本地相同. 支持大文件批量上传(20G)和下载,同时需要保证上传期间用户电脑不出现卡死等体验:支持文件夹上传,文件夹中的文件数量达到1万个以上,且包含层级结构. 支持断点续传,关闭浏览器或刷新浏览

java web 实现文件夹上传(保留目录结构)

javaweb上传文件 上传文件的jsp中的部分 上传文件同样可以使用form表单向后端发请求,也可以使用 ajax向后端发请求 1.通过form表单向后端发送请求 <form id="postForm" action="${pageContext.request.contextPath}/UploadServlet" method="post" enctype="multipart/form-data"> <

web文件夹上传下载方案

第一点:Java代码实现文件上传 FormFile file = manform.getFile(); String newfileName = null; String newpathname = null; String fileAddre = "/numUp"; try { InputStream stream = file.getInputStream();// 把文件读入 String filePath = request.getRealPath(fileAddre);//取

asp.net Web 项目的文件/文件夹上传下载

以ASP.NET Core WebAPI 作后端 API ,用 Vue 构建前端页面,用 Axios 从前端访问后端 API ,包括文件的上传和下载. 准备文件上传的API #region 文件上传  可以带参数 [HttpPost("upload")] public JsonResult uploadProject(IFormFile file, string userId) { if (file != null) { var fileDir = "D:\\aaa"

.net Web 项目的文件/文件夹上传下载

以ASP.NET Core WebAPI 作后端 API ,用 Vue 构建前端页面,用 Axios 从前端访问后端 API ,包括文件的上传和下载. 准备文件上传的API #region 文件上传  可以带参数 [HttpPost("upload")] public JsonResult uploadProject(IFormFile file, string userId) { if (file != null) { var fileDir = "D:\\aaa"

GitHub把自己整个文件夹上传

我已经有了自己github,但是我怎么对我的项目进行上传呢,普通的上传只有上传单一的文件 这不我去下载了Git 然后开始使用Git Bash Git要求每台电脑都要有自己的用户名(User Name)和邮箱(Email) 所以我就自己设置下 git config --global user.name "your name" git config --global user.email "your email" 建立和上传SSH Key 找到你这台电脑的管理员账户 文