L’application est vulnérable à une injection SSTI.
L’objectif consiste à créer un exploit personnalisé permettant de supprimer le fichier /home/carlos/.ssh/id_rsa.
Connexion possible avec l’utilisateur : wiener:peter.
Il est possible de définir un avatar personnalisé via :
Ce mécanisme crée un symlink vers n’importe quel fichier lisible.
Ainsi, on peut récupérer son contenu en téléchargeant l’avatar.
Exemple
Lire /etc/passwd
Le fichier est accessible lors de l’ouverture de l’image
Analyse du code User.php
Le fichier /home/carlos/User.php révèle :
La fonction gdprDelete() supprime réellement le fichier pointé par le lien symbolique.
C’est exactement ce que l’on doit exploiter pour effacer id_rsa.
Exploitation : suppression de /home/carlos/.ssh/id_rsa
Créer un symlink vers la clé SSH de Carlos
Déclencher la suppression via :
Le lien symbolique pointe vers id_rsagdprDelete() efface la cible du lien
Le fichier id_rsa est supprimé.
<?php
class User {
public $username;
public $name;
public $first_name;
public $nickname;
public $user_dir;
public function __construct($username, $name, $first_name, $nickname) {
$this->username = $username;
$this->name = $name;
$this->first_name = $first_name;
$this->nickname = $nickname;
$this->user_dir = "users/" . $this->username;
$this->avatarLink = $this->user_dir . "/avatar";
if (!file_exists($this->user_dir)) {
if (!mkdir($this->user_dir, 0755, true))
{
throw new Exception("Could not mkdir users/" . $this->username);
}
}
}
public function setAvatar($filename, $mimetype) {
if (strpos($mimetype, "image/") !== 0) {
throw new Exception("Uploaded file mime type is not an image: " . $mimetype);
}
if (is_link($this->avatarLink)) {
$this->rm($this->avatarLink);
}
if (!symlink($filename, $this->avatarLink)) {
throw new Exception("Failed to write symlink " . $filename . " -> " . $this->avatarLink);
}
}
public function gdprDelete() {
$this->rm(readlink($this->avatarLink));
$this->rm($this->avatarLink);
$this->delete();
}
private function rm($filename) {
if (!unlink($filename)) {
throw new Exception("Could not delete " . $filename);
}
}
}
?>