本环境采用phpstudy一键搭建
环境搭建
为其创建一个新网站,注意要和目录名字对应
创建一个数据库
访问域名安装
填写基本信息,和数据库要对应上
就好了
漏洞出处
代码审计
前置条件
开启以下功能,功能特征为开启image_compress_openscale字段,
这是关键检验字段,后面可以清楚了解到。这里操作为访问该页面打开图片压缩比例
在源码里面可以看到“图片压缩比例”,对应以上字段
看看源码
切入点
对于命令执行,在代码中可能会出现类似“exec(),shell_exe(),cmd(),system()”的函数,我们在源码中搜索有没有使用到差不多的
还有的部分我暂时省略,这个就有点像了
理解函数
是一个叫file_save()的函数调用到的,看名字和文件保存的沾点关系,我没有把函数完整截出
- 以下是对这段 PHP 代码的分析:
- 一、函数功能
- 这个名为
file_save
的函数主要用于保存上传的文件,并根据配置进行一些额外的操作,如文件移动、图像压缩以及可选的网络存储(通过 FTP 或对象存储服务)。 - 二、参数说明
$file_tmp_name
:上传文件的临时文件名。$filename
:文件名。$extention
:文件扩展名。$file_full_path
:文件的完整路径。$file_relative_path
:文件的相对路径。$allownet
:一个布尔值,决定是否允许进行网络存储。如果为true
,并且系统配置允许,将文件上传到网络存储位置。- 三、主要代码流程
- 首先获取全局系统设置
$settings
。 - 使用
file_move
函数将上传的临时文件移动到指定的完整路径$file_full_path
。如果移动失败,返回错误信息。 - 如果系统设置中开启了图像压缩(通过检查
$settings['image_compress_openscale']
),根据配置的压缩比例$scal
进行图像压缩操作,使用system
函数调用convert
命令对图像进行处理。 - 如果
$allownet
为true
并且系统配置允许网络存储(检查$settings['system_isnetattach']
),根据不同的存储方式(FTP 或对象存储服务)进行文件上传:- 如果
$settings['system_isnetattach']
为 1,使用 FTP 进行文件上传。引入lib_ftp.php
文件,创建baijiacms_ftp
对象,连接 FTP 服务器,然后上传文件。如果上传过程中出现错误,返回错误信息。 - 如果
$settings['system_isnetattach']
为 2,使用对象存储服务进行文件上传。引入lib_oss.php
文件,创建baijiacms_oss
对象,然后上传文件。如果上传过程中出现错误,返回错误信息。
- 如果
- 最后,创建一个包含文件路径、文件名、扩展名和上传成功标志的数组
$result
并返回。
主要信息就是,如果想调用系统命令,就必须得含有image_compress_openscale
字段,字段开启方式在上面提到了。
system函数调用需要两个参数(第二个可选),第一个是命令,第二个是路径,这里的命令已经固定成convert,后面拼接的是参数,我们可控点就在后面的$file_full_path,将该变量后面拼接一段命令,达到命令执行目的。因为这里$file_full_path变量从传参来就没有改变,那么就直接追踪哪里调用了该函数就好了
接着查找调用该函数的位置,有仨在一个文件内,一个单独的,那仨是函数嵌套函数,追踪起来要更难一点,先看看单独的
setting.php中出现,没有完整截出
- 以下是对这段 PHP 代码的分析:
- 一、功能概述
- 这段代码主要用于处理微信相关设置的保存操作。它允许用户提交微信的名称、令牌、加密密钥、应用 ID、应用密钥等信息,并且可以上传一个文本文件作为微信验证文件。如果提交成功,会保存这些设置并显示成功消息,刷新页面。如果系统中还没有设置微信令牌,则标记为首次设置。
- 二、代码流程
- 获取微信相关的全局设置
$settings
。 - 如果是表单提交(通过
checksubmit()
判断):- 创建一个包含微信设置的数组
$cfg
,从表单中获取微信名称、令牌、加密密钥、应用 ID、应用密钥、分享地址和禁止访问的设置。 - 如果有上传的文件(
$_FILES['weixin_verify_file']['tmp_name']
不为空):- 获取上传文件的扩展名。
- 如果扩展名是
txt
:- 确定验证文件的保存路径。
- 使用
file_save
函数保存上传的文件,并根据情况复制文件到特定路径。 - 将文件名保存到
$cfg['weixin_hasverify']
。
- 如果不是
txt
扩展名,显示错误消息。
- 设置微信访问令牌为空字符串。
- 使用
refreshSetting
函数保存微信设置,并显示保存成功消息,然后刷新页面。
- 创建一个包含微信设置的数组
- 如果全局设置中没有微信令牌,则标记
$isfirst
为true
,表示首次设置。 - 最后包含名为
setting
的页面。
$file_full_path原来是网络路径web_root加上file表单中的name字段拼接而来的,网络路径是已经定义好的,于是查file表单从哪儿来的
是FILES表单中的weixin_verify_file字段演变来的,FILES是我们的文件上传后生成的表单信息,说明此函数对应网站界面存在文件上传,且有验证只允许txt
此文件内没找到weixin_verify_file,于是搜索
在前端代码中找到,是文件上传后的name值,根据以上信息可以将weixin_verify_file理解为这是上传后的部分文件信息,里面有文件名等相关内容。那这就是祖宗,前面提到目的是要控制文件路径file_full_path,file_full_path由file表单name字段控制,file被FILES的weixin_verify_file吃,文件路径最后肯定是精确定位到某个文件(因为这是我们上传一个txt产生的信息,他只允许txt),那么我们对上传的文件名控制下,传下去就可以拼接成命令执行
根据项目逻辑寻找页面
因为setting.php并没有调用其他函数了,尝试找到该页面。根据该cms逻辑找到如何才能访问到该页面?
首先在默认页面看url的参数
在源码找到名字一样的文件,可以看到manager的store.php中,get请求参数op等于display,对应url。beid应该和里面调用的某个函数有关,这里不管
举一反三得出
成功找到
选择txt上传
在平时遇到命令执行漏洞时候,有的情况会在url上添加&表示“还有一件事~”,反正就是后面可以添加变量什么的。以前打靶场的时候抓包添加&后面就跟着命令看能不能执行了。
这里是因为路径还在system函数中,添加&只有三种情况,参数或者命令或者文件名,但后面又添加了一个&,导致服务器以为是命令,就把他执行了
这里将文件命名为&whoami&.txt,上传上去
在源码中添加一条输出命令,用于查看命令是否执行
点击提交,爆出来了
debug一下
name果然是上传的文件名
传给file,基本上就是把weixin_verify_file给file了
整个文件路径
Comments NOTHING