Kimdir01/webcalendar-multi-vuln-cve
GitHub: Kimdir01/webcalendar-multi-vuln-cve
一份针对 WebCalendar v1.9.18 的安全审计报告与 PoC,披露了 29 个严重漏洞及其完整攻击链。
Stars: 0 | Forks: 0
# GitHub 安全公告:WebCalendar v1.9.18 — 多个严重漏洞(权限提升、Cookie 伪造、26 个 XSS)
## 公告信息
| 字段 | 值 |
|-------|-------|
| **严重程度** | 严重 |
| **CWE** | CWE-621 (变量注入) / CWE-327 (弱加密) / CWE-79 (XSS) / CWE-284 (访问控制失效) |
| **CVSS v3.1** | 9.8 (默认禁用 UAC) / 9.1 (全局变量污染 PrivEsc) / 8.6 (Cookie 伪造) |
| **CVSS 向量** | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
## 摘要
WebCalendar v1.9.18(包含 252 个 PHP 文件的成熟网络日历应用程序)存在 29 个漏洞:(1) 默认禁用用户访问控制(UAC),授予未认证用户完全访问权限;(2) 通过 `$GLOBALS` 注入导致全局变量污染,实现管理员权限提升;(3) 使用可预测密钥的 XOR 密码进行弱 Cookie 混淆,导致会话伪造;(4) 涵盖存储型和反射型向量的 26 个 XSS 漏洞;(5) 开放重定向和 Host 头注入。
## 漏洞详情
### 受影响的包/仓库
- **仓库:** `webcalendar/webcalendar`
- **受影响版本:** v1.9.18 及更早版本
- **修复版本:** 无 (0-day)
**Commit Hash (已审计):** `64714738c8061d93d11a76a267c8f72a2dc32e28`
## CVE-REQUEST-001:默认禁用访问控制 (CVSS 9.8)
**文件:** `includes/access.php`,第 370-371 行,406-411 行
```
if( ! access_is_enabled() )
return true; // ALWAYS ALLOW ACCESS
```
当 `$UAC_ENABLED != 'Y'`(默认设置)时,每个用户——包括未认证的 `__public__` 用户——都可以访问所有页面:用户管理、系统设置、访问控制管理。
结合公共自动登录(默认 `PUBLIC_ACCESS=Y`),完全未认证的访问者即可拥有管理权限。
## CVE-REQUEST-002:全局变量污染导致管理员权限提升 (CVSS 9.1)
**文件:** `includes/functions.php`,第 4096-4102 行 (load_global_settings),第 4369-4391 行 (load_user_preferences)
```
function load_global_settings() {
$rows = get_global_settings();
foreach ($rows as $row) {
$GLOBALS[$row['name']] = $row['value']; // INJECTS INTO $GLOBALS!
}
}
function load_user_preferences($user) {
$rows = get_user_prefs($user);
foreach ($rows as $row) {
$GLOBALS[$row['name']] = $row['value']; // INJECTS INTO $GLOBALS!
}
}
```
每个 `webcal_config` 和 `webcal_user_pref` 行都会成为全局变量。如果攻击者能够(通过 SQL 注入、存储型 XSS 或管理员滥用)将 `is_admin=Y` 插入到 `webcal_user_pref` 中,他们将立即成为管理员。可被覆盖的有效安全关键全局变量包括:`$is_admin`、`$single_user`、`$user`、`$login`。
## CVE-REQUEST-003:通过弱混淆进行会话 Cookie 伪造 (CVSS 8.6)
**文件:** `includes/functions.php`,第 1775-1785 行 (encode_string),第 955-967 行 (decode_string)
```
function encode_string($str) {
$offsets = get_offsets(); // Derived from install_password + md5(db_password)
// Fallback: 'oogabooga'
// Simple XOR-like substitution cipher
}
```
这种“加密”是一种替换密码,使用源自 `install_password` 和 `md5(db_password)` 的 `$offsets`。这些值存储在 `includes/settings.php` 中(在默认配置中可通过 Web 读取)。读取 `settings.php` 的攻击者可以伪造任何用户的会话 Cookie。
## CVE-REQUEST-004:26 个 XSS 漏洞 (CVSS 8.6)
**具有代表性的严重 XSS:**
1. **edit_entry_handler.php:1282-1293** — 原始 `$_POST` 被输出到隐藏的 `value=""` 属性中
2. **approve_entry.php:15-16** — form action 中的 `$_SERVER['QUERY_STRING']`
3. **help_bug.php:5-9** — User-Agent 头被存储并输出且未转义
4. **pref.php:199,878** — JavaScript `onclick` 上下文中的 `$prefuser`
5. **upcoming.php:213,215,221** — 通过事件描述/位置引发的存储型 XSS
6. **functions.php:1371,1402** — 月视图 title 属性中的事件名称
7. **view_entry.php:737-744** — 未转义的外部参与者名称
8. **rss.php:293,342** — RSS CDATA 中的事件描述
## 其他发现(共 29 个):
| # | 漏洞 | CVSS | 类型 |
|---|--------------|------|------|
| H-1 | 所有用户均可查看用户密码哈希 | 7.5 | 信息泄露 |
| H-2 | 通过 return_path 的开放重定向 | 7.4 | 开放重定向 |
| H-3 | 模板 LFI(启用 ALLOW_EXTERNAL_HEADER 时) | 7.2 | LFI |
| H-4 | 翻译缓存中的不安全反序列化 | 8.1 | 反序列化 |
| H-5 | XSS 黑名单过滤器从根本上可被绕过 | 7.3 | XSS |
| H-6 | 使用 addslashes() 而非上下文感知转义 | 7.3 | XSS |
| H-7 | get_events.php 忽略 UAC 权限 | 7.5 | IDOR |
| H-8 | .git 目录暴露 | 7.5 | 信息泄露 |
| M-1 | 公共访问自动认证 | 6.5 | 认证绕过 |
| M-2 | 非用户 Cookie "nonuser" 魔术字符串 | 6.5 | 认证绕过 |
| M-8 | 分类图标任意文件读取 | 6.5 | 路径遍历 |
| M-9 | Host 头注入 | 5.3 | SSRF |
| M-10 | CSRF 创建账户 | 5.3 | CSRF |
| L-1 | 硬编码的 MD5 管理员默认密码 | 3.7 | 硬编码凭据 |
| L-9 | 通过登录错误进行用户枚举 | 5.3 | 枚举 |
## 攻击链:未认证 → 管理员 → 完全沦陷
1. 公共访问自动登录 (M-1) → 以 `__public__` 身份登录
2. 默认禁用 UAC (C-1) → 访问所有管理员功能
3. 或者通过读取 `settings.php` 进行 Cookie 伪造 (C-3) → 冒充管理员
4. 全局污染 (C-2) → 通过数据库操纵设置 `is_admin=Y`
5. 存储型 XSS (C-4) → 通过事件描述注入 JavaScript → 窃取管理员会话
6. 路径遍历 (M-8) → 读取 `includes/settings.php` → 泄露数据库和安装密码
## 补丁 / 修复
1. 默认启用 UAC (`$UAC_ENABLED = 'Y'`)
2. 用专用的配置数组替换 `$GLOBALS` 注入
3. 用合适的 `random_bytes()` + HMAC 会话 token 替换 XOR 密码
4. 对于 HTML 输出,使用 `htmlspecialchars()` 替换 `addslashes()`
5. 添加 CSP 头以缓解 XSS
6. 根据白名单验证 return_path 以防止开放重定向
7. 添加 `.htaccess` 以阻止对 `.git/` 的访问
8. 登录后重新生成会话 ID
## 披露时间线
- **2026-06-28:** Fatullayev Asadbek (Kimdir01) 发现了所有 29 个漏洞
- **待定:** 报告给维护者
- **待定:** 请求 CVE
- **待定:** 发布公告
## 致谢
- 发现者:Fatullayev Asadbek | GitHub:Kimdir01
- 独立安全研究员
## 参考
- CWE-621:变量提取错误
- CWE-327:使用已破解或存在风险的加密算法
- CWE-79:跨站脚本攻击
- CWE-284:不当访问控制
标签:Modbus, Web安全, Web报告查看器, 协议分析, 权限提升, 漏洞 PoC, 自动化分析, 蓝队分析, 访问控制缺陷, 跨站脚本