首先将项目搭建好,(phpstudy搭建很快很方便)注意数据库的搭建
用phpstorm打开,
判断框架
开始审计前,先看一下目录结构,判断是否使用框架开发,常见的框架如Thinkphp、Laravel、Yii等都有比较明显的特征
判断没有用框架,就先搞清楚目录结构、路由。
主要关注以下几个方面:
- 入口文件 index.php:根目录下的index.php是一个程序的入口,通常会包含整个程序的运行流程、包含的文件,所以通读一下index.php文件有助于我们了解整个程序的运行逻辑
- 安全过滤文件:安全过滤文件中会写函数对参数进行过滤,所以了解程序 过滤的漏洞,对于我们进行漏洞的利用至关重要。这类文件通常会在其他文件中包含,所以会在特定的目录,如上面的includes目录下。
- 函数集文件:函数集文件中会写一些公共的函数,方便其他文件对该函数进行调用,所以这类文件也会在其他文件中进行包含。这类文件通常存放在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 等,审计参数是否可控
全局搜索这些函数,