当php邂逅windows通用上传缺陷
早上逛乌云发现了PKAV大牛的一篇文章,针对php和windows文件上传的分析,思路很YD,果断转之与大家分享。
虽然此文可能有许多的限制条件,但是如果你认真阅读会发现,其实还是比较实用的。
另外一篇团长发的pdf中也涉及到了相关的文章,是国外的nosec发布的,英文的,感兴趣的同学在这里下载http://pan.baidu.com/s/1hqiQRbA
本案例采用的实例是:U-Mail邮件系统。
U-Mail邮件系统文件上传的地方代码是这样的:
<?php if(ACTION =="attach-upload"){ if($_FILES){ $file_name = $_FILES['Filedata']['name']; $file_type = $_FILES['Filedata']['type']; $file_size = $_FILES['Filedata']['size']; $file_source = $_FILES['Filedata']['tmp_name']; $file_suffix = getfilenamesuffix( $file_name ); $not_allow_ext = array( "php", "phps", "php3", "exe", "bat" ); if (in_array($file_suffix, $not_allow_ext )){ dump_json( array( "status" => 0, "message" => el( "不支持该扩展名文件上传", "" ) ) ); } $path_target = getusercachepath( ); do{ $file_id = makerandomname( ); $file_target = $path_target.$file_id.".".$file_suffix; } while ( file_exists( $file_target ) ); if ( move_uploaded_file( $file_source, $file_target )){ dump_json( array( "status" => 0, "message" => el( "写入文件出错,请与管理员联系!", "" ) ) ); } $_SESSION[SESSION_ID]['attach_cache'][] = array( "id" => $file_id, "name" => $file_name, "type" => "1", "path" => $file_target, "size" => $file_size ); dump_json( array( "status" => "1", "filename" => $file_name, "filesize" => $file_size, "file_id" => $file_id ) ); }else{ dump_json( array( "status" => "0", "message" => el( "无法找到需要上传的文件!", "" ) ) ); } }
我们注意到如下的代码
$not_allow_ext = array( "php", "phps", "php3", "exe", "bat" ); if (in_array($file_suffix, $not_allow_ext )){ dump_json( array( "status" => 0, "message" => el( "不支持该扩展名文件上传", "" ) ) ); }
非常明显,采用的是黑名单验证,虽然我们可以采用类似这样的文件后缀绕过程序的检测,如:bypass.phpX(这里的X代表空格%20或其他特殊字符{%80-%99}),但这完全不是今天我想要讲的内容。
今天,通过这个实例给大家讲解一种新型的文件上传方式,且听我细细道来..
#2 代码poc实现
为了在本地测试方便,我们对上述代码进行简化,如下
<?php //U-Mail demo ... if(isset($_POST['submit'])){ $filename = $_POST['filename']; $filename = preg_replace("/[^\w]/i", "", $filename); $upfile = $_FILES['file']['name']; $upfile = str_replace(';',"",$upfile); $upfile = preg_replace("/[^(\w|\:|\$|\.|\<|\>)]/i", "", $upfile); $tempfile = $_FILES['file']['tmp_name']; $ext = trim(get_extension($upfile)); // null if(in_array($ext,array('php','php3','php5'))){ die('Warning ! File type error..'); } if($ext == 'asp' or $ext == 'asa' or $ext == 'cer' or $ext == 'cdx' or $ext == 'aspx' or $ext == 'htaccess') $ext = 'file'; //$savefile = 'upload/'.$upfile; $savefile = 'upload/'.$filename.".".$ext; if(move_uploaded_file($tempfile,$savefile)){ die('Success upload..path :'.$savefile); }else{ die('Upload failed..'); } } function get_extension($file){ return strtolower(substr($file, strrpos($file, '.')+1)); } ?> <html> <body> <form method="post" action="upfile.php" enctype="multipart/form-data"> <input type="file" name="file" value=""/> <input type="hidden" name="filename" value="file"/> <input type="submit" name="submit" value="upload"/> </form> </body> </html>
对于上述代码,虽然是通过黑名单进行文件名检测,但通过目前已知的上传方法,是没有办法成功上传php文件的(不考虑程序的Bug),因此可以说这段文件上传的代码是"安全"的,
可是,我蓦然回首,在那个灯火阑珊的地方,php邂逅了Windows,美丽的爱情故事便由此产生了..
#3 细说故事
某天,二哥在群里丢了一个url连接,我简单看了下,关于利用系统特性进行文件上传的,兴趣马上就来了,就细细研究了下,于是有了这篇文章..
这几行英文的意思大致是,在php+window+iis环境下:
双引号(">") <==> 点号(".")'; 大于符号(">") <==> 问号("?")'; 小于符号("<") <==> 星号("*")';
有这么好玩的东西,那不就可以做太多的事了?但事实并不是这样,通过一系列的测试发现,该特性只能用于文件上传时覆盖已知的文件,于是这个特性便略显鸡肋..
原因有二:
1)上传文件的目录一般我们都不可控;
2)同时,一般文件上传的目录不可能存在我们想要的任何php文件,因此没办法覆盖;
后来,经过反反复复的思考,终于找到了可以完美利用的办法..
思路如下:
首先我们先利用特殊办法生成一个php文件,然后再利用这个特性将文件覆盖..
可问题又来了,怎样生成php文件呢?如果可以直接生成php文件的话,干嘛还要利用那什么特性?
别急,办法总是有的..
我们都知道在文件上传时,我们往往会考虑到文件名截断,如%00 等..
对!有的人可能还会用冒号(":")去截断,如:bypass.php:jpg
但是你知道吗?冒号截断产生的文件是空白的,里面并不会有任何的内容,呵呵 说到这里 明白了没有? 虽然生成的php文件里面没有内容,但是php文件总生成了吧,所以 我们可以结合上面所说的特性完美成功利用..
#4 冒号+特性成功利用
按照#3提供的思路,实现..
本地测试地址:http://www.secmap.cn/upfile.php 环境:Windows+IIS7.5
1)首先利用冒号生成我们将要覆盖的php文件,这里为:bypass.php,如图
2)利用上面的系统特性覆盖该文件
从上面已经知道"<" 就等于 "*",而"*"代码任意字符,于是乎.. 我们可以这样修改上传的文件名,如下:
------WebKitFormBoundaryaaRARrn2LBvpvcwK Content-Disposition: form-data; name="file"; filename="bypass.<<<" Content-Type: image/jpeg //注意!文件名为:bypass.<<<
点击go..,即可成功覆盖bypass.php文件,如图
对比上面的两个图,bypass.php被我们成功的写入了内容..
#5 特性二
首先来看看微软MSDN上面的一段话,如图
注意红色圈起来的英文
The default data stream has no name. That is, the fully qualified name for the default stream for a file called "sample.txt" is "sample.txt::$DATA" since "sample.txt" is the name of the file and "$DATA" is the stream type.
看不去不错哟,试试吧..
同样,我们可以这样修改上传的文件名,如下:
------WebKitFormBoundaryaaRARrn2LBvpvcwK Content-Disposition: form-data; name="file"; filename='DataStreamTest.php::$DATA' Content-Type: image/jpeg //注意!文件名为:DataStreamTest.php::$DATA
点击GO,奇迹出现了..
访问之...
#6 漏洞证明
U-Mail,具体利用方法,同上述的方法一样,为了简单快捷的话,可直接抓包修改文件名为:
shell.php::$DATA 即可成功上传,这里不再演示,附shell
当php邂逅windows通用上传缺陷的更多相关文章
- 当php懈垢windows通用上传缺陷
转自独自等待博客 早上逛乌云发现了PKAV大牛的一篇文章,针对php和windows文件上传的分析,思路很YD,果断转之与大家分享. 虽然此文可能有许多的限制条件,但是如果你认真阅读会发现,其实还是比 ...
- php懈垢windows通用上传缺陷
#1 实例介绍本案例采用的实例是:U-Mail邮件系统.U-Mail邮件系统文件上传的地方代码是这样的: code 区域 <?php if(ACTION =="attach-uploa ...
- pkav之当php懈垢windows通用上传缺陷
$pkav->publish{当php懈垢windows}剑心@xsser抛弃了我,但我却不能抛弃乌云..php懈垢windows,就像男人邂逅女人,早晚都会出问题的..感谢二哥@gainove ...
- Windows如何上传代码到Github
1.首先得安装git客户端 进入官网:https://git-scm.com/ ,点击右侧下载windows版本的软件包,然后双击安装就可以了. 安装完成之后,在开始菜单可以看到,此时,在想上传的文件 ...
- windows下上传shell脚本不能运行—将dos模式修改为unix 文件格式
windows下上传shell脚本至linux,其格式将为dos.dos模式的shell脚本将不能再linux下正确运行,需要修改文件模式为unix. 1 查看文件模式方法 linux服务器上,用vi ...
- C# 通用上传文件类
1.Upfile.aspx: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="U ...
- Git在windows下上传文件至github流程
github是开发者分享的一个平台,这里不多说,想要上传文件至github需要有一个开发者账号,还需要在windows下安装好了git. 做好准备工作之后,接下来操作 一:登录github,创建项目 ...
- 解决PHP在Windows IIS 上传的图片无法访问的问题
最近在做一个网站项目遇到了一个很奇怪的问题,现记录下来希望可以帮助到其他的朋友 问题描述: 最近公司刚刚在香港购买了一个Windows Server 2008 服务器用于将一个客户的N个php网站 ...
- 某p2p存在通用上传漏洞
google链接查找: inurl:shouyi.asp inurl:itemlist_xq.asp?id= 很多存在Fckeditor上传链接: FCKeditor/editor/filemanag ...
随机推荐
- Android 一些关于 Activity 的技巧
锁定 Activity 运行时的屏幕方向 Android 内置了方向感应器的支持.在 G1 中,Android 会根据 G1 所处的方向自动在竖屏和横屏间切换.但是有时我们的应用程序仅能在横屏 / 竖 ...
- [luogu3157][bzoj3295][CQOI2011]动态逆序对【cdq分治+树状数组】
题目描述 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序 ...
- 「ZJOI2016」旅行者 解题报告
「ZJOI2016」旅行者 对网格图进行分治. 每次从中间选一列,然后枚举每个这一列的格子作为起点跑最短路,进入子矩形时把询问划分一下,有点类似整体二分 至于复杂度么,我不会阿 Code: #incl ...
- luogu1484 种树 (优先队列)
我每次都想选那个最大的.或者是它旁边的两个一起选,如果这两个一起选会大于那个最大的的话 那我就先把那个最大的选了,再提供一个反悔的选项(类似于网络流的思路?),就是我可以再把种的树换成它旁边那两个,也 ...
- 深挖JDK动态代理(二):JDK动态生成后的字节码分析
接上一篇文章深挖JDK动态代理(一)我们来分析一下JDK生成动态的代理类究竟是个什么东西 1. 将生成的代理类编程一个class文件,通过以下方法 public static void transCl ...
- ACM-ICPC 2018 焦作赛区网络预赛 G. Give Candies (打表找规律+快速幂)
题目链接:https://nanti.jisuanke.com/t/31716 题目大意:有n个孩子和n个糖果,现在让n个孩子排成一列,一个一个发糖果,每个孩子随机挑选x个糖果给他,x>=1,直 ...
- js,jquery 获取滚动条高度和位置, 元素距顶部距离
一,获取滚动条高度和位置 jQuery 获取览器显示区域的高度: $(window).height(); 获取浏览器显示区域的宽度:$(window).width(); 获取页面的文档高度:$(do ...
- iview表单验证下拉框不通过问题
iview表单验证的步骤: 第一步:给 Form 设置属性 rules :rules 第二步:同时给需要验证的每个 FormItem 设置属性 prop 指向对应字段即可 prop=”“ 第三步:注意 ...
- 【POJ2226】Muddy Fields
题目大意:给定一个 N*M 的图,图中有一些格子不能被任何东西覆盖,现有一些宽度为 1,长度任意的骨牌覆盖这些可以被覆盖的格子,骨牌之间可以重叠,求将所有可以被覆盖的格子覆盖所需的最小骨牌数是多少. ...
- tfs 2013 利用 web deploy 完成asp.net站点自动发布
课题起因: 目前我们团队使用visual studio 2013开发asp.net项目, 使用tfs2013 做源码管理, 每天早上手动发布项目文件包,复制到测试服务器的站点文件夹下覆盖老文件,用此方 ...