[UUCTF 2022 新生赛]ez_upload

今天做这到题的时候,做半天没有做出来,然后看其它人写的博客。大部分文章写的是利用apache解析漏洞,虽然解出了这题道,但是根本没有看出和Apache解析漏洞有关。

先看题目

只有一个上传功能。

上传一个图片试试,发现文件名字并没有改变

随便修改一下后缀名为abc,看看它是黑名单还是白名单

发现上传失败,再修改一个MIME信息

上传成功!!!!

所以大概可以猜测它是黑名单加上MIME信息检测

在将后缀名改为 1.abc. 试试

发现最后成功上传,且还是为 "1.abc.  ",到这里可以判断为linux操作系统。

因为window操作系统会自动删除文件后缀的点和空格

知道了它为linux操作系统,且为黑名单加上MIME信息过滤

黑名单过滤且操作系统为linux绕过方法有哪些

1.  .hatccess解析绕过(Apache服务特性)

2.   .user.ini绕过(服务器特性)

3.   逻辑漏洞(与程序员写的代码有关)

4.    Apache解析漏洞

1.上传  .htaccess文件试试,发现被过滤了

2.上传 .user.ini文件试试

上传成功!!!

a. .user.ini是php的一种配置文件,众所周知php.ini是php的配置文件,它可以做到显示报错,导入扩展,文件解析,web站点路径等等设置自 PHP 5.3.0 起,PHP 支持基于每个目录的 .htaccess 风格的 INI 文件。此类文件仅被 CGI/FastCGI SAPI 处理。此功能使得 PECL 的 htscanner 扩展作废。如果使用 Apache,则用 .htaccess 文件有同样效果。 官方解释: 除了主 php.ini 之外,PHP 还会在每个目录下扫描 INI 文件,从被执行的 PHP 文件所在目录开始一直上升到 web 根目录($_SERVER[‘DOCUMENT_ROOT’] 所指定的)。如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。 这些模式决定着一个 PHP 的指令在何时何地,是否能够被设定。手册中的每个指令都有其所属的模式。例如有些指令可以在 PHP 脚本中用 ini_set() 来设定,而有些则只能在 php.ini 或 httpd.conf 中。

大致原理就是上传一个配置文件,配置文件中的意思就是让每一个php文件都包含一个你指定的文件(可以是任意后缀),被包含的文件都会用PHP执行。

所以只有上传一个  .user.ini文件,文件内容为:

auto_prepend_file=1.png

(这段代码的意思为所有PHP文件都要包含1.png这个文件)

接着上传一个含一句话木马的1.png文件

最后再访问该目录下的任意的php文件(一般题目会在该目录下设置一个PHP文件)

使用  .user.ini绕过还要什么条件

a.可以上传 ini文件,且上传之后文件不被修改,必须为 .user.ini文件名

b.对应服务器脚本语言为php

c.服务器有可执行脚本语言php

d.服务器使用CGI/FastCGi模式

接着我们只要上传一个a.png文件,且找到upload目录下的一个PHP文件就能实现绕过。

但是很快发现upload目录并没有PHP文件,用扫描工具也扫不到,所以这个方法不管用。

3.接着猜猜看看有没有什么逻辑漏洞

一般出现在文件上传的逻辑漏洞有哪些。

如果会删除非法后缀名:

a.只删除一次,那可以通过构造绕过 。绕过方法如   1.pphphp

如果不删除非法后缀名:

a.以第一个点为分割符,取第一个点之后作为文件后缀名。绕过方法: 1.png.php

可能还有其它的,但是目前我只知道这些

接着修改一下文件后缀名为 1.png.php上传试试

上传成功!!!

使用蚁剑连接一下

成功连接!!!

最后在跟目录下找到flag。

最后我们看一下原代码

<?php
//echo $_FILES['file']['name'];echo '<br>';
//echo $_FILES['file']['type'];echo '<br>';
$flag1=true;
$flag2=true;
$file_name=$_FILES['file']['name'];
$file_type=$_FILES['file']['type'];
$allow_file_type=['image/jpeg','image/png'];
$allowedExts = array("php", "php3", "php5", "phtml","htaccess");
$ext=substr($file_name,strpos($file_name,".")+1);
if(!in_array(strtolower($file_type),$allow_file_type)){
    $flag1=false;
    die("你好坏哦,不理你了");
}
if(in_array(strtolower($ext),$allowedExts)){
    $flag2=false;
    die("你好坏哦,不理你了");
}
if($flag1&&$flag2){
    if (file_exists("upload/" . $_FILES["file"]["name"]))
    {
        echo $_FILES["file"]["name"] . " 文件已经存在。 ";
    }
    else
    {
        // 如果 upload 目录不存在该文件则将文件上传到 upload 目录下
        move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]);
        echo "文件存储在: " . "upload/" . $_FILES["file"]["name"];
    }
}
else{
    echo "Hacker,你好坏哟";
}

最后发现他却检查的MIME信息,且为黑名单过滤。

但是看一下产生逻辑的这行代码

$ext=substr($file_name,strpos($file_name,".")+1);

这段代码首先使用strpos()函数找到文件名中的点号位置,然后使用substr()函数从点号位置的下一个字符开始截取字符串,并把他当成文件名的扩展名。

这段代码获取的是第一个逗号,而并不是第一个逗号,所有产生了漏洞。

如果要修改应该改为

  $file_ext = strrchr($file_name, '.');

$file_ext = strrchr($file_name, '.');是一行PHP代码,用于获取文件名中的扩展名。它使用了PHP内置函数strrchr()来查找文件名中最后一个.字符,并返回该字符及其后面的所有字符,即文件的扩展名。
 

  • 21
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值