JSForge
Acceder →
← Volver al catálogo
SERVIDORDIFÍCIL Descargable

De Prototipo a Root

Prototype Pollution → RCE

// OBJETIVO

Encadenar la contaminación de Object.prototype con un sink que ejecute comandos, para lograr ejecución remota de código en el servidor del lab.

// ZONA DE ATAQUE

Próximamente

Lab en construcción

Este reto ejecuta código de servidor real, así que corre en un lab Docker que todavía no está publicado. Mientras tanto, el código vulnerable y su remediación de al lado son material completo para estudiar la vulnerabilidad.

// CONSULTÁ

Pistas

    Código vulnerable

    La contaminación llega a un sink que compila código. El motor de plantillas lee una opción que, por herencia, ahora controla el atacante:

    // 1) Primitiva: mismo deep merge inseguro del reto anterior.
    deepMerge(settings, req.body);
    
    // 2) Sink: se renderiza una plantilla usando opciones "por defecto".
    const render = template.compile(view.source, view.options);
    res.send(render(data)); // view.options.escape viene del prototipo contaminado

    Contaminando la opción que el compilador inserta literalmente en la función generada (por ejemplo escape o el sourceURL del template), el string controlado por el atacante pasa a ejecutarse cuando se compila la plantilla, llegando a child_process y a ejecución de comandos.

    Remediación

    Cortá la primitiva y no dejes que las opciones del motor se resuelvan por herencia:

    - deepMerge(settings, req.body);
    + deepMerge(settings, req.body); // ya endurecido: descarta __proto__/constructor/prototype
    +
    - const render = template.compile(view.source, view.options);
    + const options = Object.assign(Object.create(null), SAFE_DEFAULTS, view.ownOptions);
    + const render = template.compile(view.source, options);

    Por qué funciona: una vez que el merge no puede tocar Object.prototype, el sink deja de heredar opciones ajenas; y construir las opciones sobre Object.create(null) con defaults explícitos garantiza que ninguna propiedad provenga del prototipo. Sin la opción contaminada no hay código que compilar, y la cadena hacia RCE se rompe en su primer eslabón.

    Reto descargable. Permite ejecución de código: nunca lo expongas a internet. Descargá el lab Docker y corrélo aislado en tu propia máquina.

    Verificación

    La verificación de flag se habilita cuando se publique el lab de este reto.