PhocaCommander ≤ 6.1.3 — 已认证管理员可在 Web 根目录之外写入文件
PhocaCommander 中的文件上传处理程序从攻击者可控的 base64 编码 folder 参数构造目标路径,且没有任何路径边界验证。经过身份验证的管理员可以将文件上传到 Web 根目录之外、Web 服务器进程可写的任意位置。
已在实验室确认:使用 folder=Li4vLi4vLi4vdG1w(即 ../../../tmp)上传时,上传的文件会被放置在 /tmp/——位于 /var/www/html/ 之外——且属主为 www-data。在生产环境的 PHP-FPM 中,此漏洞可被链式利用以实现远程代码执行。
| 组件 | 受影响版本 | 测试环境 | 已修复版本 |
|---|---|---|---|
| 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/helpers/fileupload.php — realMultipleUpload()
realMultipleUpload() 会将 folder POST 参数从 base64 解码,并直接将其传入 Path::clean() 的拼接中,随后用作上传目标路径,且没有任何边界检查。
FILEUPLOAD.PHP — 漏洞代码
$folder = $app->getInput()->get('folder', '', '', 'string');
$folder = base64_decode($folder); // ← attacker-controlled
$path = JPATH_ROOT; // = /var/www/html
if (isset($folder) && $folder != '') {
$pathFolder = Path::clean($path . '/' . $folder . '/');
// e.g. Path::clean('/var/www/html/../../../tmp/')
// = '/tmp/' — outside the webroot, no error thrown
}
// ...
File::upload($file['tmp_name'], $pathFolder . strtolower($file['name']));
Path::clean() 会规范化目录分隔符,但不会解析或去除 ../ 序列。解析后的路径直接传递给 File::upload(),且没有后续的边界检查。
上传扩展名白名单
该处理程序强制执行扩展名白名单(图片、文档、压缩包、文本文件),并阻止服务器可执行类型(如 .php 和 .htaccess)。然而,白名单允许的许多文件类型——包括 shell 脚本、cron 任务定义和配置片段——在写入敏感的系统路径时可能造成严重危害。
通过管理登录页面进行身份验证。从任意管理页面获取 Joomla CSRF 令牌——它以隐藏表单字段的形式出现,也可从页面源码中提取。

向 POST /administrator/index.php?option=com_phocacommander&task=phocacommanderupload.multipleupload 发送一个 multipart POST 请求,在 file 字段中携带文件内容,并在 folder 字段中携带 base64 编码的遍历路径 Li4vLi4vLi4vdG1w(即 ../../../tmp)。服务器返回 HTTP 200 以及 {"jsonrpc":"2.0","result":"OK","code":200,"message":"Success: ","details":"Files uploaded"}。
请求 / 响应

确认文件位于 /tmp/upload_test.txt,属主为 www-data,位于 /var/www/html/ 之外。

www-data 可写的路径都可以接收攻击者选择的内容,包括操作系统调度器、SSH 守护进程及其他服务使用的路径.txt 文件与 .user.ini(auto_prepend_file)一起上传到 Web 可访问目录,会在下一次请求该目录时触发 PHP 执行