Explorer les Vulnerabilites d Upload de Fichiers sans Enfreindre la Loi
Comment contourner les validations d upload dans votre propre lab, cartographier les classes de bugs et durcir les serveurs web contre le RCE par fichier.
Un endpoint d upload mal configure reste l un des moyens les moins chers de transformer un simple formulaire en RCE. Dans un lab monte avec DVWA, OWASP Juice Shop et un Nginx 1.25 en reverse proxy, nous sommes passes de l upload d avatar a un shell www-data en moins de 40 minutes. Avant tout payload, le contrat compte: la cible est notre propre VM, isolee sur un reseau 10.10.0.0/24 sans route internet, et l objectif final est d ecrire des regles de hardening, pas de collectionner des trophees. Si cet environnement n est pas encore pret, parcourez Pentest Web depuis Zero: Construire un Lab Sur avec DVWA, Juice Shop et Burp Suite avant de continuer.
La premiere classe de faille qui apparait est la validation d extension cote client. Le PHP legacy embarque souvent une blacklist (.php, .phtml, .php5) sans aucune verification reelle du Content-Type. Renommer shell.php en shell.pHp.jpg, intercepter avec Burp et forcer Content-Type image/jpeg fait sauter environ 80% des filtres amateurs vus dans les CTF corporate. Lors d un test recent sur un module de CV, un fichier .gif contenant GIF89a; renomme en .phtml a suffi a obtenir execution. Ce n est pas la regex qui a echoue, c est l architecture: Apache avait un AddHandler sur tout fichier .phtml dans n importe quel dossier.
La deuxieme couche interessante est le double parsing de l ancien Nginx (CVE-2013-4547 et ses descendants modernes). Un fichier nomme shell.jpg\x00.php trompe encore les stacks combinant Nginx + PHP-FPM avec un pathinfo mal regle. Dans le lab j ai reconstruit le scenario avec nginx:1.14-alpine et php:7.2-fpm pour reference historique; avec Nginx 1.25 et cgi.fix_pathinfo=0 le meme payload meurt. Ce type d exercice se marie bien avec SQL Injection en Pratique: Exploiter, Detecter et Mitiger dans un Lab Controle: chasser une seule CVE est inutile sans comprendre toute la chaine de traitement de la requete, du load balancer a l interpreteur.
Quand le backend valide les magic bytes, la donne change. Les polyglots GIF/PHP battent getimagesize() mais echouent face a finfo plus Imagick avec retraitement. L astuce est d attaquer le pipeline de transformation: ImageMagick avec des policies laxistes parse encore MVG et SVG, et la famille ImageTragick continue de remonter dans des forks de plateformes LMS. Chez un client fintech j ai trouve un upload de recu qui appelait convert sans -limit memory et avec un policy.xml vide; un SVG de 12 Ko avec xlink:href pointant sur file:///etc/passwd a fuit son contenu dans le PDF genere. Pour le pendant SSRF cote web, SSRF Demystifie: Exploiter Cloud Metadata dans un Lab AWS Local couvre le cas AWS quasi identique.
Une autre surface sous-estimee est la destination finale du fichier. Le stockage dans /var/www/uploads servi directement par Apache est le classique, mais on retrouve le meme probleme dans des buckets S3 avec un mauvais Content-Disposition et dans des CDN qui retraitent du HTML. Le path traversal dans le nom de fichier (../../tmp/cron.d/pwn) fonctionne encore contre des middlewares Node qui font confiance a l originalname de Multer. Pour une checklist de test plus formelle, surtout sur les API JSON avec base64 embarque, croisez avec Pentest APIs REST et GraphQL : Checklist Technique pour Bug Bounty Legal et validez tailles, mimetype declare vs detecte et quotas par utilisateur authentifie.
Cote defensif, les regles que je facture en rapport sont ennuyeuses et marchent: nom aleatoire (UUIDv7), stockage hors document root, service via un handler qui force Content-Disposition: attachment et Content-Type: application/octet-stream, validation mimetype avec libmagic cote serveur, et blocage des doubles extensions directement dans Nginx avec location ~* \.(php|phtml|phar)\. { deny all; }. En conteneur je monte le volume d upload en noexec,nosuid et je colle clamav en sidecar. L audit continu releve de AppSec Shift-Left: SAST, SCA et Secrets Scanning sans Bloquer l Equipe, ou Semgrep attrape les regex de validation faibles avant le deploiement.
Un point ethique que je repete en formation: rejouer ces techniques contre un SaaS en production 'juste pour voir' n est pas du bug bounty, c est un delit sous la LCEN en France et equivalents ailleurs. Les programmes legitimes publient un perimetre explicite, et meme la-dedans, exfiltrer /etc/passwd est inutile quand l id de la VM suffit a prouver le bug. La difference entre chercheur et prevenu, c est generalement le snapshot de la VM et l autorisation ecrite. Takeaway pratique: au prochain sprint, prenez un endpoint d upload de votre produit, ecrivez un test d integration qui tente shell.phtml, .htaccess, un polyglot GIF/PHP et un SVG avec xlink, et faites echouer le pipeline si l un d eux passe. Ca vaut plus que cent heures de lecture.