PhocaCommander ≤ 6.1.3 — 已认证管理员可在 Web 根目录之外操作文件
PhocaCommander 的文件操作处理器从攻击者可控的 base64 编码参数(pathfrom、pathwhere)构造源路径和目标路径,且未进行任何路径包含验证。已认证的管理员可以删除、复制和移动 Web 服务器进程可访问的文件系统中的任意文件。
已在实验室中确认:可以删除 /tmp/(Web 根目录之外)中的文件,并将 /etc/passwd 复制到 PhocaCommander 文件管理器中——从而可通过内置编辑器读取其内容。删除、复制、移动这三种操作共享同一条未经验证的代码路径。
| 组件 | 受影响版本 | 测试环境 | 修复版本 |
|---|---|---|---|
| PhocaCommander | 1.0.0 – 6.1.3 | Joomla 5.4.7 + PhocaCommander 6.1.3 (PHP 8.2 / Apache) | 6.1.4 |
所需认证: 管理员(会话 + CSRF 令牌)
文件: administrator/components/com_phocacommander/views/phocacommanderactiona/view.json.php
该操作视图将 pathfrom 和 pathwhere 从 base64 解码后,在未进行任何包含检查的情况下直接拼接到 JPATH_ROOT 上。这些未经验证的路径随后被用于全部三种文件操作:
VIEW.JSON.PHP — 易受攻击的路径构造
// Both parameters decoded from base64 — no containment check
$pathFrom = JPATH_ROOT . '/' . base64_decode($this->t['pathfrom']) . '/';
$pathWhere = JPATH_ROOT . '/' . base64_decode($this->t['pathwhere']) . '/';
// Delete — removes any file reachable by www-data
$srcValue = $pathFrom . $v;
if (PhocaCommanderHelper::fileExists($srcValue)) {
File::delete($srcValue);
}
// Copy / Move — arbitrary cross-directory file operations
File::copy($pathFrom . $v, $pathWhere . $v);
File::move($pathFrom . $v, $pathWhere . $v);
PhocaCommanderHelper::fileExists() 使用 is_file(Path::clean($file))。Path::clean() 会规范化斜杠,但不会去除 ../ 序列,因此任一参数中的遍历序列都会在未经检查的情况下解析为任意的文件系统路径。
在 /tmp/poc.txt 位置创建一个属于 www-data 的测试文件,以确认目标在删除操作之前存在。

通过管理员登录页面进行认证。获取 Joomla 表单令牌——它以隐藏输入字段的形式出现在任何管理员页面上。

解码后的参数:
pathfrom=Li4vLi4vLi4vdG1w → ../../..tmp → /tmp/selfiles[0]=file|cG9jLnR4dA== → 文件名 poc.txt请求 / 响应


重用场景 1 的管理员会话,或重新认证以获取新的 CSRF 令牌。
解码后的参数:
pathfrom=Li4vLi4vLi4vLi4vZXRj → ../../../../etc → /etc/pathwhere=cGhvY2EtZmlsZXM= → phoca-files → /var/www/html/phoca-files/selfiles[0]=file|cGFzc3dk → 文件名 passwd请求 / 响应

/etc/passwd 现在已存在于 Web 根目录内的 phoca-files/passwd,属主为 www-data。

在管理员面板中进入 PhocaCommander 文件管理器,打开 phoca-files/,点击文件 passwd,然后点击“编辑”即可在内置的 CodeMirror 编辑器中查看其内容。完整的 /etc/passwd 内容将被渲染显示:

www-data 可写的文件(包括其他服务的应用程序配置、锁文件和 cron 任务)都可能被永久删除/etc/shadow、私钥、其他应用的 .env 文件)复制到 Web 根目录后,无需任何进一步操作即可通过 HTTP 访问