当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

时间: 2024-10-31 06:07:33

当php邂逅windows通用上传缺陷的相关文章

当php懈垢windows通用上传缺陷

转自独自等待博客 早上逛乌云发现了PKAV大牛的一篇文章,针对php和windows文件上传的分析,思路很YD,果断转之与大家分享. 虽然此文可能有许多的限制条件,但是如果你认真阅读会发现,其实还是比较实用的. 另外一篇团长发的pdf中也涉及到了相关的文章,是国外的nosec发布的,英文的,感兴趣的同学在这里下载 点我下载 #1 实例介绍 本案例采用的实例是:U-Mail邮件系统. U-Mail邮件系统文件上传的地方代码是这样的: <?php if(ACTION =="attach-upl

pkav之当php懈垢windows通用上传缺陷

$pkav->publish{当php懈垢windows}剑心@xsser抛弃了我,但我却不能抛弃乌云..php懈垢windows,就像男人邂逅女人,早晚都会出问题的..感谢二哥@gainoverTips:本文讲述一种新型的文件上传方式(几个特性导致的漏洞),并给出相应的实例.. 详细说明: #1 实例介绍 本案例采用的实例是:U-Mail邮件系统. U-Mail邮件系统文件上传的地方代码是这样的: code 区域 <?php if(ACTION =="attach-upload&q

通用上传Servlet

java判断文件类型参考: http://blog.csdn.net/shixing_11/article/details/5708145 目前使用的项目结构是:spring+springmvc+mybatis. 文件上传需要考虑两个地方: 1. 文件上传的安全性,脚本等文件是可以通过更改文件的后缀来提交的,这也是大多数网站通过上传渗入的方式. 2. 对非保存的文件删除,上传的文件,如果操作人没有进行保存或其他操作,需要清除文件. 本上传使用的包: commons-fileupload java

Application Uploader-教你在Windows下上传iOS APP到苹果应用商店

现如今出现了很多跨平台移动开发工具,很多开发者选择了这些快速开发APP的平台,因此有些开发者可能没有配备Mac电脑,在上传iOS APP时会受到阻碍. 那能不能实现在Windows下上架苹果应用呢? 下面用到一个工具Application Uploader即可实现在Windows系统下,直接提交IPA到App Store. 苹果应用打包IPA过程中需要用到证书,Appuploader可以帮助我们创建iOS证书和p12文件,创建过程非常简单,只需输入证书名称,创建邮箱等信息即可创建证书.而且证书不

C# 通用上传文件类

1.Upfile.aspx: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Upfile.aspx.cs" Inherits="Inc_Upfile" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.or

linux——windows:上传、下载命令——rz,sz

一般来说,linux服务器大多是通过ssh客户端来进行远程的登陆和管理的,使用ssh登陆linux主机以后,如何能够快速的和本地机器进行文件的交互呢,也就是上传和下载文件到服务器和本地:   与ssh有关的两个命令可以提供很方便的操作:   sz:将选定的文件发送(send)到本地机器   rz:运行该命令会弹出一个文件选择窗口,从本地选择文件上传到服务器(receive) rz,sz是便是Linux/Unix同Windows进行ZModem文件传输的命令行工具 windows端需要支持ZMod

解决PHP在Windows IIS 上传的图片无法访问的问题

最近在做一个网站项目遇到了一个很奇怪的问题,现记录下来希望可以帮助到其他的朋友 问题描述: 最近公司刚刚在香港购买了一个Windows Server 2008 服务器用于将一个客户的N个php网站进行统一管理 该服务器上有三个网站,一个是THINKPHP开发的小型电子竞技网站,一个使用WORDPRESS开发的企业网站,一个使用ECSHOP开发的商城商城 由于前二天家中有事所以请假回去了一个礼拜(走之前三个网站都已经部署到该服务器但测试是在其他服务器上进行的并没有发现什么问题) 在请假回来后客户反

解决windows文件上传到unix后 产生^M的问题

在aix6.1 上部署的发现 通过ftp从windows上传到aix上的文件 用vi打开后发现 每行后都多了^M 网上寻找解决方案 cd 到文件夹所在目录 vi filename 然后输入 :%s/^M$//g 注意 此处命令中的M 是通过键入"CTRL-V CTRL-M"生成的! 该命令的意思是 "去掉所有行末的M"

windows与windows之间上传下载文件的命令

1.下载 可以从http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html下载pscp,并将其放入windows的system32 文件夹下,这样在dos命令窗口中就能直接调用使用了. 2.使用 进入cmd命令窗口 从windows上传文件到linux:pscp(空格)文件在windows上的地址(空格)服务器用户名@服务器ip:上传到服务器的地址 例: 说明:windows下的ChromeSetup.exe文件上传到了ruib