文件上传限制绕过技巧

简介

文件上传漏洞是web安全中经常利用到的一种漏洞形式。一些web应用程序中允许上传图片,文本或者其他资源到指定的位置,文件上传漏洞就是利用这些可以上传的地方将恶意代码植入到服务器中,再通过url去访问以执行代码。但在一些安全性较高的web应用中,往往会有各种上传限制和过滤,导致我们无法上传特定的文件。本文将就此展开讨论,通过本文的学习你将了解到Web应用中文件上传的处理和验证发送流程,以及我们该如何绕过这些验证。

客户端验证

客户端验证是一种发生在输入被实际发送至服务器之前进行的验证。这类验证大都都是通过JavaScript,VBScript或HTML5来完成的。虽然,这对于用户来说响应速度更快体验也更好。但对于恶意攻击者来说,这些验证似乎就显得略为低级。

客户端验证绕过

这种类型的绕过也非常简单,我们可以关闭浏览器上的JavaScript或是在浏览器发出请求之后,在被发送至服务器之前来篡改该HTTP请求即可。

示例:

1\. <script type="text/javascript">
2\. var _validFileExtensions = [".jpg", ".jpeg", ".bmp", ".gif", ".png"];
3\. function Validate(oForm) {
4\. var arrInputs = oForm.getElementsByTagName("input");
5\. for (var i = 0; i < arrInputs.length; i++) {
6\. var oInput = arrInputs[i];
7\. if (oInput.type == "file") {
8\. var sFileName = oInput.value;
9\. if (sFileName.length > 0) {
10\. var blnValid = false;
11\. for (var j = 0; j < _validFileExtensions.length; j++) {
12\. var sCurExtension = _validFileExtensions[j];
13\. if (sFileName.substr(sFileName.length - sCurExtension.length, sCurExtension.length).to
LowerCase() == sCurExtension.toLowerCase()) {
14\. blnValid = true;
15\. break;
16\. }
17\. }
18.
19\. if (!blnValid) {
20\. alert("Sorry, " + sFileName + " is invalid, allowed extensions are: " + _validFileExtension
s.join(", "));
21\. return false;
22\. }
23\. }
24\. }
25\. }
26.
27\. return true;
28\. }
29\. </script>

正如你所看到的,此JavaScript仅在请求被实际发送至服务器之前处理你的请求,以及检查你上传的文件扩展名是否为(jpg,jpeg,bmp,gif,png)。这样的话,我们就可以拦截该请求并篡改文件内容(恶意代码),然后将图片扩展名更改为可执行文件的扩展名(如php,asp)。

如上图所示,我们试图上传一个直接的PHP文件,JavaScript阻止了我们的文件上传请求。

我们可以通过浏览器来上传一个正常的图片格式来绕过该验证,然后拦截该请求再将其改回为php格式并将文件内容替换为我们的恶意代码,这样我们就能够成功上传我们的恶意php脚本了。

文件名验证

顾名思义,就是在文件被上传到服务端的时候,对于文件名的扩展名进行检查,如果不合法,则拒绝这次上传。检查扩展名是否合法有两种常用策略,即黑名单和白名单策略。

黑名单策略,即文件扩展名在黑名单中的为不合法。白名单策略,即文件扩展名不在白名单中的均为不合法。相对于黑名单,白名单策略更加安全的。通过限制上传类型为只有我们接受的类型,可以较好的保证安全,因为黑名单我们可以使用各种方法来进行注入和突破。

文件名绕过

我们可以通过上传一些平时不怎么用的容易被人忽视的文件扩展名,来绕过这种类型的验证。

绕过黑白名单策略:

黑名单绕过

通过上传不受欢迎的php扩展来绕过黑名单。例如:pht,phpt,phtml,php3,php4,php5,php6

白名单绕过

通过某种类型的技巧来绕过白名单,例如添加空字节注入(shell.php%00.gif),或使用双重扩展来上传文件(shell.jpg.php)。

此外,我们还可以尝试扩展名大小写来绕过,例如:pHp,Php,phP。

示例:

1\. if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
2\. && $imageFileType != "gif" ) {
3\. echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";

以上代码将会阻止除jpg,jpeg,gif,png扩展名以外的,所有其它文件类型上传。在本例中我们将尝试绕过该检查,并在Web服务器上传一个php文件。

黑名单绕过

正如你所看到的,将php文件的后缀更改为.php5(Apache服务器会将其视为php文件执行)后,就可以成功绕过该上传验证。

白名单绕过

如上图所示,我们使用了双重扩展名(shell.jpg.php)来绕过验证。

Content-Type验证

Content-Type(内容类型),一般是指网页中存在的Content-Type,用于定义网络文件的类型和网页的编码,决定文件接收方将以什么形式、什么编码读取这个文件。例如,一些图像文件上传通过检查文件的内容类型是否为图像类型来验证上传的图像。

Content-Type绕过

该类型的绕过也非常简单,只需将“Content-Type”的参数类型更改为“image/ *”即可,例如“image/png”, “image/jpeg”, “image/gif”。

示例:

1\. <?php
2.
3\. $mimetype = mime_content_type($_FILES['file']['tmp_name']);
4\. if(in_array($mimetype, array('image/jpeg', 'image/gif', 'image/png'))) {
5\. move_uploaded_file($_FILES['file']['tmp_name'], '/uploads/' . $_FILES['file']['name']);
6\. echo 'OK';
7.
8\. } else {
9\. echo 'Upload a real image';
10\. }

以上代码会检查Content-Type header中的MIME类型,仅接受类型为image/jpeg, image/gif, image/png的文件上传。我们只需只需将“Content-Type”的参数类型更改为其可接受的类型即可绕过。

CONTENT-LENGTH验证

Content-Length验证是指服务器会对上传的文件内容长度进行检查,超出限制大小的文件将不允许被上传。虽然这种类型的验证不是很受欢迎,但在一些应用的文件上传中也时常能碰到。

CONTENT-LENGTH绕过

针对这种类型的验证,我们可以通过上传一些非常短的恶意代码来绕过。上传文件的大小取决于,Web服务器上的最大长度限制。我们可以使用不同大小的文件来fuzzing上传程序,从而计算出它的限制范围。

示例:

1\. if ($_FILES["fileToUpload"]["size"] > 30) {
2\. echo "Sorry, your file is too large.";
3\. }

以上代码将限制大小超过30字节的文件上传。我们可以通过上传一个30字节以内大小的恶意payload文件来绕过它。

参考来源

http://www.securityidiots.com/Web-Pentest/hacking-website-by-shell-uploading.html http://www.net-informations.com/faq/asp/validation.htm https://www.owasp.org/index.php/Unrestricted_File_Upload http://www.sitepoint.com/mime-types-complete-list/ https://www.w3schools.com/php/php_file_upload.asp https://stackoverflow.com/

*参考来源:exploit-db,FB小编 secist 编译,转载请注明来自FreeBuf.COM

原文发布于微信公众号 - FreeBuf(freebuf)

原文发表时间:2018-08-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏原创

个推推送iOS版 常见问题详解

1、提交了.p12文件后多久可以测试? 提交后10分钟左右才可以测试,并不是立即生效的。 2、应用在后台时接收不到消息,即APNS消息接收不到? 1.    先...

390110
来自专栏北京马哥教育

批量管理自动化运维100台小规模服务器

---- 目录 1.脚本背景介绍 2.脚本技术需求分析 2.1 SSH免登陆认证 2.2 Expect实现key分发 2.2 PSSH家族命...

2.6K150
来自专栏漏斗社区

你们尽管绕dogByPass,绕不过算我输!

0x00 背景 这周学弟学妹经常提问到如何绕过安全防护软件的检测,那么本篇就以dog为例子带大家走一遍dogByPass的一条龙服务流程,本篇仅提供思路,后续可...

42180
来自专栏编程之旅

在Mac上使用ssh-key免密码登录服务器

从很早之前开始,在搭建测试服务器的时候,就不停的谷歌怎么免密登录服务器,每次配置好免密登录后,到搭建新的服务器时,又忘记了具体的命令,所以决定把这个方法记下来,...

1.8K40
来自专栏有困难要上,没有困难创造困难也要上!

Redis实现类似同步方法调用的功能(一)

379110
来自专栏向治洪

在Windows下搭建Gitlab服务器

一.GitLab简介 GitLab 是一个用于仓库管理系统的开源项目。使用Git作为代码管理工具,并在此基础上搭建起来的web服务。 可通过Web界面进行访问...

2.3K100
来自专栏Objective-C

iOS-将项目上传到 Git.OSChina 上,创建自己的私有项目

34660
来自专栏谈补锅

ASP和ASP.NET发送邮件笔记

    这两天因公司网站邮件发不出去,然后研究了在asp网站发送邮件和在asp.net网站发送邮件的代码,把碰到的问题这里记录一下。

23030
来自专栏云计算教程系列

如何在Ubuntu 16.04上使用Stunnel加密流量到Redis

Redis是一个开源键值数据存储,使用内存存储模型和可选的磁盘写入来实现持久性。它具有事务,发布/订阅消息传递模式以及其他功能之间的自动故障转移功能。Redis...

38240
来自专栏IT可乐

邮件实现详解(二)------手工体验smtp和pop3协议

  上篇博客我们简单介绍了电子邮件的发送和接收过程,对参与其中的邮件服务器,邮件客户端软件,邮件传输协议也有简单的介绍。我们知道电子邮件需要在邮件客户端和邮件服...

460100

扫码关注云+社区

领取腾讯云代金券