baijiacms--php代码审计

首先将项目搭建好,(phpstudy搭建很快很方便)注意数据库的搭建

用phpstorm打开,

判断框架

开始审计前,先看一下目录结构,判断是否使用框架开发,常见的框架如Thinkphp、Laravel、Yii等都有比较明显的特征

判断没有用框架,就先搞清楚目录结构、路由。

主要关注以下几个方面:

  1. 入口文件 index.php:根目录下的index.php是一个程序的入口,通常会包含整个程序的运行流程、包含的文件,所以通读一下index.php文件有助于我们了解整个程序的运行逻辑
  2. 安全过滤文件:安全过滤文件中会写函数对参数进行过滤,所以了解程序 过滤的漏洞,对于我们进行漏洞的利用至关重要。这类文件通常会在其他文件中包含,所以会在特定的目录,如上面的includes目录下。
  3. 函数集文件:函数集文件中会写一些公共的函数,方便其他文件对该函数进行调用,所以这类文件也会在其他文件中进行包含。这类文件通常存放在common或function等文件夹中

首先对入口文件index.php进行分析

首先检查/config/install.link文件是否存在,如果不存在就重定向到install.php进行安装

然后查看是否定义SYSTEM_ACT,然后通过条件判断来确定 $mod 的值,然后跟进 $mod 的值

然后根据是否传入参数do和act确定参数的值

最后包含一个文件 includes/baijiacms.php

出去看看install.php

检查/config/install.link文件是否存在,如果存在就重定向到index.php,然后就给mod赋值,传入参数act和do,同样也是包含文件 includes/baijiacms.php

不一样的一点是多了一个 $CLASS_LOADER="driver" 看名称是配置了一个类加载器

安全过滤分析

跟进到includes/baicaicms.php中查看,

首先检查是否定义了 SYSTEM_ACT或者LOCK_TO_INSTALL 如果没有定义就退出,然后定义了WEB_ROOT 大致意思就是把baicaicms作为web的根目录

然后检查WEB_ROOT目录下是否有 /config/version.php和/config/debug.php,如果有就包含进来

然后还定义了一堆其他的常量,就不详细解析了

我们看到接下来定义了一个函数 irequestsplite

这个函数中调用了htmlspecialchars 可以把将某些特殊字符转换为HTML实体,以避免这些字符被解释为HTML标记

irequestsplite()主要的作用是把特殊字符转换为HTML实体,然后把&(实体引用)全部替换成&

然后就是包含了一堆文件进来

路由分析

全局搜索一下router 发现文件中没有定义,使用的是默认路由

这种情况下我们可以在url中 结合url中的参数和文件目录及文件名进行理解

传入参数是mod act do 和beid 其中mod、act和do我们之前都见过,将这三个变量接收的参数在网站目录的文件中寻找,

比如我现在这个

public-mobile-login

发现这里有登录校验等等,翻到index.php看看,包含了一个page函数

进来看看这个函数

即 SYSTEM_ROOT下的 mobile/tempplate/mobile/index.php

找到之后发现也是我们跳转到的首页,那么前三个参数的意思 act应该是目录名,mod代表下一级目录名,do代表文件名

登录后台页面,看看url 发现是mod=site、act=manager、do=store、op=display 和beid=1 多了一个参数,我们先按照之前的去找找对应的文件

发现怎么不对啊,路径不应该是/web/store吗,在url中我们试着把mod改成web

同样也是跳转到了这个界面

至此了解了网站路由,且所有接收参数都是system目录下的文件中,所以我们可以重点看该目录下的文件。

代码审计

之前看过一个大佬的思路,这里就直接搬运一把

  • 从功能点进行审计,通过浏览网页,寻找可能存在漏洞的功能点,然后找到相应的源码进行分析
  • 从代码方向进行审计,通过全局搜索危险函数,审计相关函数的参数是否可控,来审计是否存在漏洞

sql注入审计

主要注意执行sql语句的地方参数是否用户可控,是否使用了预编译

可以全局搜索select等sql语句关键词,然后定位到具体的语句,查看里面有没有拼接的变量;也可以浏览网页,找具有查询功能的地方,定位到文件参数,审计是x`否存在漏洞

首先这里就有一个搜索的按钮,我们尝试一下,抓包,发现传入的参数是sname

先根据url定位到\system\manager\class\web\store.php

在代码中搜索sname看看

这里构造了一个sql搜索语句,单引号闭合,没有对传入的参数进行过滤处理。只看这里的话是存在sql注入的

但是我们要知道,在看全局过滤的时候htmlspecialchars对单引号双引号进行转义,所以这里不存在漏洞

文件上传/文件写入漏洞

审计文件上传漏洞主要需要关注是否对文件类型、文件大小、上传路径、文件名等进行了限制

有的项目会将文件下载上传功能封装到一个自定义函数中,所以可以全局搜索upload、file的函数,看看是否有自定义的函数

也可以直接搜索move\_uploaded\_file、file\_put\_contents函数,判断参数是否可控。

全局搜索move\_uploaded\_file,发现两处调用

第一处是检查是excel.php中否后缀是xlsx文件,然后上传

第二处是common.inc.php

自定义了函数file_move其中使用了move_upload_file,

跟进看看哪里调用了file_move,在file_save中调用了file_move,file_save有四个使用,逐个看看

第一处引用是自己自定义的file_upload函数

函数对上传的类型和大小做了过滤,是白名单上传

function file_upload($file, $type = 'image') {
    if(empty($file)) {
        return error(-1, '没有上传内容');
    }
    $limit=5000;
    $extention = pathinfo($file['name'], PATHINFO_EXTENSION);
    $extention=strtolower($extention);
    if(empty($type)||$type=='image')
    {
    $extentions=array('gif', 'jpg', 'jpeg', 'png');
    }
    if($type=='music')
    {
    $extentions=array('mp3','wma','wav','amr','mp4');
    }
        if($type=='other')
    {
    $extentions=array('gif', 'jpg', 'jpeg', 'png','mp3','wma','wav','amr','mp4','doc');
    }
    if(!in_array(strtolower($extention), $extentions)) {
        return error(-1, '不允许上传此类文件');
    }
    if($limit * 1024 < filesize($file['tmp_name'])) {
        return error(-1, "上传的文件超过大小限制,请上传小于 ".$limit."k 的文件");
    }

    $path = '/attachment/';
    $extpath="{$extention}/" . date('Y/m/');

        mkdirs(WEB_ROOT . $path . $extpath);
        do {
            $filename = random(15) . ".{$extention}";
        } while(is_file(SYSTEM_WEBROOT . $path . $extpath. $filename));

    $file_full_path = WEB_ROOT . $path . $extpath. $filename;
    $file_relative_path=$extpath. $filename;
    return file_save($file['tmp_name'],$filename,$extention,$file_full_path,$file_relative_path);
}

在这里就不一一展开审计了

最终发现fetch_net_file_upload这里没有对参数进行检查处理,直接把传入的url进行上传重命名

有一处使用到了这个函数,我们找找

system\public\class\web\file.php

在url中输入看看

baijiacms-master/index.php?mod=site&act=public&do=file&op=fetch

我们需要加上参数,构造一个payload

baijiacms-master/index.php?mod=site&act=public&do=file&op=fetch&url=C:\Users\Sun YC\Desktop\phpinfo.php //这里的url最好是用vps远程下载的地址

访问这个url

成功

任意文件删除漏洞

审计任意文件删除漏洞,需要注意是否存在 ../ 、. 、..\ 等跨目录的字符过滤,是否配置了路径等

文件删除主要搜索 unlink、rmdir函数,unlink用于删除文件,rmdir用于删除文件夹

搜索unlink看看,一个一个审计

任意文件删除一

首先用is\_dir判断传入的参数是否是一个目录,如果是,并且不是/cache/目录,就调用rmdir删除目录;如果不是,则调用unink删除文件,

找找这个函数的使用地方,在database.php中

对传进来的参数进行base64解码,

我们在www目录下上传一个payload,就利用刚刚的吧

我们需要删除baijiacms-master/attachment/php/2024/01/acPc7hiaAnl0mIK.php

根目录是baijiacms-master ,所以应该删除的是 ../../attachment/php/2024/01/acPc7hiaAnl0mIK.php

baijiacms-master/index.php?mod=web&act=manager&do=database&op=delete&id=Li4vLi4vYXR0YWNobWVudC9waHAvMjAyNC8wMS9hY1BjN2hpYUFubDBtSUsucGhw

贻笑大方了家人们,这里太不认真了,代码中先判断是否是一个文件夹,所以是不能删除文件的,先看看删除文件夹可不可以,在根目录下创建一个test文件夹

baijiacms-master/index.php?mod=web&act=manager&do=database&op=delete&id=Li4vLi4vdGVzdA==

成功删除,我们再来看看如果文件夹里有文件能否删除

Li4vLi4vYXR0YWNobWVudC9waHAvMjAyNC8wMQ==

成功了,之前上传的文件没有了,那么我们可以利用文件上传漏洞把主页中判断的install.link删除掉,然后重新安装

文件删除漏洞二

在includes\baijiacms\common.inc.php目录下,有file_delete

前面的if是判断文件的环境

我现在不知道system_isnetattach代表的是什么意思,全局搜索一下,发现这应该是上传的方式 ,根据代码来看,如果是本地的文件可以利用这个漏洞删除

查找用到file_delete的地方

system/eshop/core/mobile/util/uploader.php 很简单没有做任何过滤

我们来验证一下,在根目录中上传一个shell.php

构造payload,这里函数的目录是在 /attachment/

发现少一个参数,我们定位不到这个目录,那么我们找找

看到这里多了一个m参数,并且是eshop

baijiacms-master/index.php?mod=mobile&act=uploader&m=eshop&do=util&op=remove&file=../shell.php

删除成功

命令执行漏洞

命令执行可以全局搜索一切可以执行命令的函数,如exec、passthru、proc\_open、shell\_exec、system、pcntl\_exec、popen 等,审计参数是否可控

全局搜索这些函数,

相关推荐
小技与小术2 分钟前
数据结构之树与二叉树
开发语言·数据结构·python
hccee23 分钟前
C# IO文件操作
开发语言·c#
hummhumm28 分钟前
第 25 章 - Golang 项目结构
java·开发语言·前端·后端·python·elasticsearch·golang
J老熊38 分钟前
JavaFX:简介、使用场景、常见问题及对比其他框架分析
java·开发语言·后端·面试·系统架构·软件工程
zmd-zk1 小时前
flink学习(2)——wordcount案例
大数据·开发语言·学习·flink
好奇的菜鸟1 小时前
Go语言中的引用类型:指针与传递机制
开发语言·后端·golang
Alive~o.01 小时前
Go语言进阶&依赖管理
开发语言·后端·golang
花海少爷1 小时前
第十章 JavaScript的应用课后习题
开发语言·javascript·ecmascript
手握风云-1 小时前
数据结构(Java版)第二期:包装类和泛型
java·开发语言·数据结构
喵叔哟1 小时前
重构代码中引入外部方法和引入本地扩展的区别
java·开发语言·重构