文件上传漏洞 --- php邂逅windows通用上传缺陷

文章详细介绍了在PHP5.2.17和IIS环境下,通过冒号加特性以及数据流两种方式绕过后端代码审计,实现文件上传的漏洞利用。首先,利用冒号加特性可以创建一个空的PHP文件,然后通过‘.*’匹配特性覆盖已有文件。其次,利用文件的数据流默认名称(如:filename::$DATA)也能达到类似效果。这两种方法都成功绕过了文件类型的限制,使得恶意文件得以上传并解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

后端源码

前端源码

后端代码审计

方式一绕过原理 --- 冒号加特性

验证及结果

方式二绕过原理 --- 数据流

验证及结果


环境需求

php5.2.17+IIS环境,可以下载phpstuday2018来满足环境的要求。

后端源码

<?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>

后端代码审计

首先是post获取到的是name属性为filename的标签,而为filename属性的标签的值为file ,由于前端可以修改这个值,因此对这个值进行下面的正则过滤;

对name为filename且用户可以修改该值进行了过滤,将非a-z、A-Z、0-9、下划线的字符替换为空;

获取上传文件的文件名;

如果文件类型后的存在";",将其替换成空;

对文件类型将非a-z、A-Z、0-9、下划线、:、$、.、<、>的字符替换为空;

获取文件的临时文件名;

去除文件首尾的空格并且获取文件的后缀名;

判断文件后缀名是否是"php","php3","php5",如果是的话,直接程序结束;

判断文件类型是否是"asp"、"asa"、"cer"、"cdx"、"aspx"、"htaccess";

定义文件上传的路径;

通过move函数将临时文件进行覆盖到用户定义好的路径。

解这道题我们就得先了解下系统特性对文件上传的知识点了

这几行英文的意思大致是在,php+windows+iis环境下:

双引号("“") <==> 点号(".");

大于符号(">") <==> 问号("?");

小于符号("<") <==> 星号("*");

通过一系列的测试发现,该特性只能用于文件上传时覆盖已知的文件,于是这个特性便略显得鸡肋

经过反复的寻找资料,终于不负有心人,找到了解决方案

思路如下:

首先我们先利用特殊办法生成一个php文件,然后再利用这个特性将文件覆盖。

可是问题来了,怎样生成php文件呢?如果可以直接生成php文件的话,干嘛还要利用那什么特性;

我们都知道,在文件上传时,我们往往会考虑到文件名截断,如%00等

对!有的人可能还会用冒号":"去截断,如bypass.php:jpg

但是存在一个问题,冒号截断产生的文件是空白的,里面并不会有任何的内容,此时应该明白了吧。虽然生成的php文件里面没有内容,但是php文件总生成了吧。上面不是说到,系统那种特性有点鸡肋,但是刚好用到现在。这不就完美的利用。

方式一绕过原理 --- 冒号加特性

首先通过冒号(":")进行截断,此时已经将xxx.php文件上传上去了,只不过是此时的php文件是空白的,里面没有任何内容。而在通过xxx.<<<的方式来匹配之前上传的xxx.php文件进行覆盖,为什么xxx.<<<可以匹配到xxx.php文件呢?原因上面已经说到过,在php+windows+iis的系统特性下,存在小于符号("<")等于星号("*"),而星号("*")在通配符中代表着可以匹配任意字符,此时通过三个小于号("<<<")则能满足匹配到php这个后缀。因此第二次上传通过xxx.<<<来匹配第一次已经上传的xxx.php来进行文件的覆盖,此时完成了绕过。有人就会说那xxx.<<<这种方式的后缀名,不会被过滤掉吗?在判断文件后缀的过滤中是放行小于号("<")的,因此xxx.<<<是可以上传的。

验证及结果

抓包后未修改

 

第一次使用冒号(":")进行截断,使得php文件上传上去,此时的文件是空文件

 此时查看上传文件,文件是成功上传但是是空文件

第二次根据特性使用小于号("<<<")来匹配已经传上去的php后缀名文件,将其覆盖掉

 查看上传文件,此时文件中已经有内容,代表成功将其覆盖掉了

最后在做一次验证,我们可以看到php文件成功上传且得到解析

 

方式二绕过原理 --- 数据流

特性二

我们来看看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.

 

验证及结果

 

给文件的后缀添加数据流

 

查看文件上传

 

可以看到文件成功上传,且php文件也得到解析

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力学IT的小徐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值