Skip to content
KitploitKITPLOIT
OutilsBlog
Log in
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
CVE-2017-5123 — PoC CVE-2017-5123 - LPE - Contournement de SMEP/SMAP. Sans KASLR | Kitploit
Outils/GitHubGitHub/c3r34lk1ll3r/cve-2017-5123
Escalade de PrivilègesExploitationApprentissage et ÉducationExploitation de BinairesLabs et Pratique
GitHubc3r34lk1ll3r/cve-2017-5123

CVE-2017-5123

PoC CVE-2017-5123 - LPE - Contournement de SMEP/SMAP. Sans KASLR

Voir le dépôt
33411il y a 6 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

CVE-2017-5123

PoC CVE-2017-5123 - LPE - Contournement de SMEP/SMAP. Sans KASLR

L'implémentation de waitid dans les noyaux en amont ne restreignait pas la destination cible pour copier les résultats d'informations. Cela peut permettre aux utilisateurs locaux d'écrire dans de la mémoire du noyau autrement protégée, ce qui peut conduire à une élévation de privilèges.

Introduction

Dans ce petit article, j'analyserai une vulnérabilité du noyau qui nous permet d'obtenir les privilèges root.

Ce fichier est divisé en quatre parties :

  1. Configuration de la VM ;
  2. analyse de la vulnérabilité ;
  3. exploitation ;
  4. PoC.

Je tiens à souligner qu'il existe de bien meilleures façons d'exploiter cette CVE (en effet, ce n'est qu'un PoC pour apprendre le noyau, il ne peut pas être utilisé dans la nature) mais je pense que cette méthodologie peut être utile comme introduction à l'exploitation du noyau.

Configuration de la VM

Compilation du noyau

Cette vulnérabilité a été introduite dans 4c48abe91be0, nous devons donc compiler cette version du noyau.

Cela peut être un peu délicat car il s'agit d'une ancienne version et le code doit être patché. J'ai créé un dépôt avec un code de noyau déjà patché et un fichier .config afin que vous puissiez cloner et compiler.

git clone https://github.com/c3r34lk1ll3r/kernel_mirror.git
cd kernel_mirror
git checkout origin/modified_v4.14
wget https://gist.githubusercontent.com/c3r34lk1ll3r/c9c34ae86140cc7a24d0d90141686ee8/raw/52431b577a71e3fe8f89d6ce355ce9c1c54c53b6/.config
make -j 8 --output-sync=recurse

Notez que ce noyau sera compilé avec les pilotes virtio, vous pouvez donc utiliser un disque virtio pour partager des fichiers depuis/vers la VM.

Configuration du rootfs

Maintenant, nous allons créer le rootfs initial :

qemu-img create -f raw hda.raw 10G
# Format the disk to ext4
mkfs.ext4 ./hda.raw 
# Make a mountpoint for the image
mkdir /tmp/mount1
# Mount the disk
sudo mount -o loop ./hda.raw /tmp/mount1

Ensuite, nous devons installer une distribution Linux de base, par exemple en utilisant pacstrap ou debootstrap.

sudo pacstrap /tmp/mount1 base base-devel vim

Enfin, nous pouvons modifier le système :

# Add a 'test' user
echo 'test:x:1000:1000::/home/test:/bin/bash' | sudo tee -a /tmp/mount1/etc/passwd
# without password
echo 'test::14871::::::' | sudo tee -a /tmp/mount1/etc/shadow 
# we can mount a virtio disk in order to share files between host and guest
echo '/transient /home/test/shared 9p trans=virtio,version=9p2000.L,rw,user,exec 0 0' | sudo tee -a /tmp/mount1/etc/fstab
sudo mkdir -p /tmp/mount1/home/test/shared 
# It is usefull to have sudo permission
echo '%wheel ALL=(ALL) NOPASSWD: ALL' | sudo tee -a /tmp/mount1/etc/sudoers
echo 'wheel:x:998:test' | sudo tee -a /tmp/mount1/etc/group

sudo chown -R 1000:1000 /tmp/mount1/home/test
sudo umount /tmp/mount1

Si tout est en ordre, nous pouvons maintenant essayer notre système de test avec qemu :

qemu-system-x86_64 \
    -kernel ./kernel_mirror/arch/x86_64/boot/bzImage \
    -hda ./hda.raw \
    -m 4G \
    -cpu "Skylake-Client-IBRS,ss=on,vmx=on,hypervisor=on,tsc-adjust=on,clflushopt=on,umip=on,md-clear=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,pdpe1gb=on,ibpb=on,amd-ssbd=on,skip-l1dfl-vmentry=on,hle=off,rtm=off" \
    -smp 4 \
    -vga virtio \
    -enable-kvm \
    -nographic \
    -machine type=q35,accel=kvm \
    -virtfs "fsdriver=local,id=fs.1,path=./trans_fs,security_model=mapped,writeout=immediate,mount_tag=/transient" \
    -append "root=/dev/sda rw noquiet nokaslr console=ttyS0 loglevel=5" \
    -chardev "vc,id=vc.0,cols=1920,rows=1080" \
    -net "user,hostfwd=tcp::10022-:22" \
    -net "nic" \
    -s

Vulnérabilité

La description de la CVE indique qu'il existe une opération d'écriture non restreinte lors de l'appel système waitid.

Ouvrons kernel/exit.c et regardons le code :

SYSCALL_DEFINE5(waitid, int, which, pid_t, upid, struct siginfo __user *,
		infop, int, options, struct rusage __user *, ru)
{
    struct rusage r;
    struct waitid_info info = {.status = 0};
    long err = kernel_waitid(which, upid, &info, options, ru ? &r : NULL);
    int signo = 0;

    if (err > 0) {
        signo = SIGCHLD;
        err = 0;
        if (ru && copy_to_user(ru, &r, sizeof(struct rusage)))
            return -EFAULT;
    }
    if (!infop)
        return err;
    user_access_begin();
    unsafe_put_user(signo, &infop->si_signo, Efault);
    unsafe_put_user(0, &infop->si_errno, Efault);
    unsafe_put_user(info.cause, &infop->si_code, Efault);
    unsafe_put_user(info.pid, &infop->si_pid, Efault);
    unsafe_put_user(info.uid, &infop->si_uid, Efault);
    unsafe_put_user(info.status, &infop->si_status, Efault);
    user_access_end();
    return err;
Efault:
    user_access_end();
    return -EFAULT;
}

Cette fonction est assez simple : après quelques vérifications, il y a divers appels à unsafe_put_user(...) puis la fonction retourne.

La partie principale de cette fonction est composée de la fonction unsafe_put_user(...), alors rendons-nous là-bas (arch/x86/include/asm/uaccess.h) :

/*
 * The "unsafe" user accesses aren't really "unsafe", but the naming
 * is a big fat warning: you have to not only do the access_ok()
 * checking before using them, but you have to surround them with the
 * user_access_begin/end() pair.
 */
#define user_access_begin()	__uaccess_begin()
#define user_access_end()	__uaccess_end()

#define unsafe_put_user(x, ptr, err_label)					\
do {										\
    int __pu_err;								\
    __typeof__(*(ptr)) __pu_val = (x);					\
    __put_user_size(__pu_val, (ptr), sizeof(*(ptr)), __pu_err, -EFAULT);	\
    if (unlikely(__pu_err)) goto err_label;					\
} while (0)

#define unsafe_get_user(x, ptr, err_label)					\
do {										\
    int __gu_err;								\  
    __inttype(*(ptr)) __gu_val;						\
    __get_user_size(__gu_val, (ptr), sizeof(*(ptr)), __gu_err, -EFAULT);	\
    (x) = (__force __typeof__(*(ptr)))__gu_val;				\
    if (unlikely(__gu_err)) goto err_label;					\
} while (0)

Il y a un gros avertissement dans le commentaire : si vous voulez utiliser unsafe_put/get_user, vous devez d'abord appeler access_ok() et les entourer avec user_access_begin/end().

Si nous examinons le code précédent (waitid), nous voyons que access_ok() n'est jamais appelé, donc l'appel système viole cet avertissement.

Mais que sont ces macros ?

SMAP/SMEP

SMAP et SMEP sont deux fonctionnalités de sécurité introduites dans le noyau afin de rendre plus difficile l'écriture d'exploits. Il est à noter que ces fonctionnalités sont appliquées par le CPU.

SMEP empêche d'exécuter du code utilisateur lorsque le CPU est en mode superviseur ; SMAP, quant à lui, bloque l'accès lecture/écriture à la mémoire utilisateur.

Le noyau a besoin d'écrire/lire des données vers/depuis la mémoire utilisateur, et cela peut être accompli de deux manières :

  1. il existe des fonctions (par exemple copy_from_user) qui permettent de copier la mémoire dans l'espace noyau ;
  2. désactiver temporairement SMAP.
Télécharger l’outil