php之文件操作代码审计

1 PHP文件操作函数

1.1 PHP文件操作函数

  • 文件包含 include/require/include_once/require_once

  • 文件读取 file_get_contents/fread/readfile/file

  • 文件写入 file_put_contents/fwrite/mkdir/fputs

  • 文件删除 unlink/rmdir

  • 文件上传 move_uploaded_file/copy/rename

1.2 文件上传流程

  • 检查文件大小、后缀、类型

  • 检查文件内容(如图片头)

  • 提取文件后缀

  • 生成新文件名

  • 将上传临时文件拷贝到新文件名位置

1.3 文件上传逻辑常见错误

  • 只检查文件类型不检查文件后缀

  • 文件后缀黑名单导致遗漏

  • 使用原始文件名,导致\0截断等漏洞

2 taocms靶场

2.1 taocms后台任意文件上传

1.点击上传弹出一个小的弹窗

2 参数有file和upload但是fil和upload设置文件


3 查看源码发现

发现几乎将php文件上传限制了

4 在新建空白3.php文件

5 在3.php文件插入一句话木马

6 查看3.php文件所在位置以及访问文件

发现新建文件哪里代码没有做限制

2.2 tomccms任意文件删除

1 先新建1.php文件

2 抓取删除3.php的数据包

3 删除的3.php文件修改为1.php

表示删除上成功

4 查看file.php文件以及参数del的代码模块

/**  
 * 删除文件或目录  
 */  
function del(){  
    // 获取当前对象的realpath属性作为路径  
    $path = $this->realpath;  
  
    // 检查路径是否可写,如果不是,则显示无删除权限的消息  
    if (!is_writable($path)) {  
        Base::showmessage('无删除权限');  
        return; // 添加返回语句,避免后续代码继续执行  
    }  
  
    // 检查路径是否为一个目录  
    if (is_dir($path)) {  
        // 如果目录内的文件(包括.和..)数量大于2,则目录非空,不能删除  
        if (count(scandir($path)) > 2) {  
            Base::showmessage('目录非空,不能删除');  
            return; // 添加返回语句,避免后续代码继续执行  
        }  
        // 删除目录  
        rmdir($path);  
    } else {  
        // 如果路径不是一个目录,则尝试删除文件  
        unlink($path);  
    }  
  
    // 获取删除项的路径信息  
    $info = pathinfo($this->path); // 注意:这里使用了$this->path而不是$path,可能是一个错误  
  
    // 显示删除成功的消息,并跳转到文件管理列表页面  
    Base::showmessage('删除成功', 'admin.php?action=file&ctrl=lists&path=' . $info['dirname']);  
}

代码分析

this−>realpath的来源:如果‘this->realpath`的值来自用户输入或不可信的源,并且没有进行适当的验证和清理,那么攻击者可能会尝试删除不应该被删除的文件或目录。 this−>path与path:在函数内部,您使用了$this->realpath作为$path,但在显示成功消息时使用了$this->path。这可能会导致显示错误的路径信息或引发未定义行为(如果$this->path没有被正确设置)。 URL跳转:在显示成功消息时,您直接使用了$info['dirname']作为URL参数的一部分。如果$info['dirname']可以被用户控制或伪造,那么攻击者可能会被重定向到不希望的页面或执行未授权的操作。但是,这通常不被视为“任意文件删除漏洞”,而是URL重定向或注入的问题。 任意文件删除漏洞:要构成任意文件删除漏洞,攻击者需要能够控制$this->realpath的值,以便指定要删除的文件或目录。如果$this->realpath的值直接来自用户输入,并且没有进行验证和过滤,那么这就是一个漏洞。

5 在data文件下新建一个名为install8.lock

6 将删除文件修改为我们要删除的文件

那么确定村子啊任意文件删除漏洞

3 beecms靶场

3.1 beecms靶任意文件删除

1 使用seay的全局搜索unlink

2 点击查看第一个

代码分析

我们能不构建任意的vlaued的值

成为任意文件删除漏洞

3 漏洞复现

在upload文件下的新建1.php文件

在data文件下的新建install9.lock文件

burp抓包并删除upload文件下的1.php

查看upload文件夹下没有1.php

尝试删除instal9.lock文件

查看data文件下已经没有install9.lock

3.2 beecms意外的sql注入

1 审计第二个漏洞


2 对代码分析

// 删除栏目  
// 检查动作是否为删除(del)  
elseif($action=='del'){  
    // 检查当前用户是否有删除栏目的权限  
    if(!check_purview('cate_del')){  
        // 如果没有权限,则输出错误消息并终止执行  
        msg('<span style="color:red">操作失败,你的权限不足!</span>');  
    }  
  
    // 获取要删除的栏目ID,并进行整型转换,防止SQL注入  
    $id=intval($_GET['id']);  
  
    // 判断该栏目下是否有内容  
    // 如果有内容,则不允许直接删除栏目,需先删除内容  
    $has_content=$GLOBALS['mysql']->fetch_rows("select id from ".DB_PRE."maintb where category=".$id);  
    if($has_content){  
        // 如果有内容,则输出错误消息并终止执行  
        msg('<span style="color:red">请先删除该栏目下的内容</span>');  
    }  
  
    // 递归删除子栏目(函数未在此段代码中给出)  
    del_cate_child($id,$lang);  
  
    // 删除当前栏目的所有子栏目(指定父ID)  
    $GLOBALS['mysql']->query('delete from '.DB_PRE.'category where cate_parent='.$id." and lang='".$lang."'");  
  
    // 删除当前栏目  
    $GLOBALS['mysql']->query('delete from '.DB_PRE.'category where id='.$id." and lang='".$lang."'");  
  
    // 检查缓存文件是否存在,如果存在则删除  
    if(file_exists(DATA_PATH.'cache_cate/cache_category'.$parent.'_'.$lang.'.php')){  
        unlink(DATA_PATH.'cache_cate/cache_category'.$parent.'_'.$lang.'.php');  
    }  
  
    // 重新缓存父栏目信息(函数未在此段代码中给出)  
    $GLOBALS['cache']->cache_category($parent,$lang);  
  
    // 重新缓存所有子栏目信息(函数未在此段代码中给出)  
    $GLOBALS['cache']->cache_category_child(0,$lang);  

此代码基本上没有错误

3 删除文件查看网络请求

4 对照代码分析

// 删除栏目  
// 检查动作是否为删除(del)  
elseif($action=='del'){  
    // 检查当前用户是否有删除栏目的权限  
    if(!check_purview('cate_del')){  
        // 如果没有权限,则输出错误消息并终止执行  
        msg('<span style="color:red">操作失败,你的权限不足!</span>');  
    }  
  
    // 获取要删除的栏目ID,并进行整型转换,防止SQL注入  
    $id=intval($_GET['id']);  
  
    // 判断该栏目下是否有内容  
    // 如果有内容,则不允许直接删除栏目,需先删除内容  
    $has_content=$GLOBALS['mysql']->fetch_rows("select id from ".DB_PRE."maintb where category=".$id);  
    if($has_content){  
        // 如果有内容,则输出错误消息并终止执行  
        msg('<span style="color:red">请先删除该栏目下的内容</span>');  
    }  
  
    // 递归删除子栏目(函数未在此段代码中给出)  
    del_cate_child($id,$lang);  
  
    // 删除当前栏目的所有子栏目(指定父ID)  
    $GLOBALS['mysql']->query('delete from '.DB_PRE.'category where cate_parent='.$id." and lang='".$lang."'");  
  
    // 删除当前栏目  
    $GLOBALS['mysql']->query('delete from '.DB_PRE.'category where id='.$id." and lang='".$lang."'");  
  
    // 检查缓存文件是否存在,如果存在则删除  
    if(file_exists(DATA_PATH.'cache_cate/cache_category'.$parent.'_'.$lang.'.php')){ 
    删除文件并命令为 cache_category_0_cn.php
    那么删除文件的  cache_category/../../cn.php直接返回到上一级目录
        unlink(DATA_PATH.'cache_cate/cache_category'.$parent.'_'.$lang.'.php');  
    }  
  
    // 重新缓存父栏目信息(函数未在此段代码中给出)  
    $GLOBALS['cache']->cache_category($parent,$lang);  
  
    // 重新缓存所有子栏目信息(函数未在此段代码中给出)  
    $GLOBALS['cache']->cache_category_child(0,$lang);

5 抓包尝试

现在data文件夹新建一个instal8.lock

抓包尝试

发现报sql错误,那么猜测是否存在SQL注入漏洞

6 根据报错信息查找内容

发现parent参数没有进行过滤那么存在sql注入

7 构建payload进行攻击

1%20or%20updatexml(1,concat(0x3e,database()),1)--+

爆出了数据库名称

3.3 beecms文件上传代码审计

1 在seay软件使用全局搜索move_uploaded_file参数

2 进入第一个进入漏洞详细并用在idea上进行代码分析


发现判断格式只有图片的格式可以进行任意文件上传

3 漏洞复现

burp抓包

修改
Content-Type: application/octet-stream
修改为
Content-Type: image/jpeg

并发送

重新查看图片

查看图片链接

4 进入第三个漏洞汇报

代码分析


发现只允许图片格式上传

payload发现

抓包复现

查看文件

3.4 beecms文件包含漏洞

1 在seay上使用全局搜索include($

2 在admin_channel.php文件第449行上找到导入字段存在文件包漏洞

3 在游览器上访问admin_channel.php地址

4 根据参数说明,编写路径

  • 21
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值