
Un escenario de prueba de concepto para la explotación de CVE2021-38297, desbordamiento de búfer en GO WASM.
WebAssembly (WASM) sirve como un formato de instrucciones binarias ejecutable en la mayoría de los navegadores web modernos. Actúa como destino de compilación para varios lenguajes de alto nivel como C, C++, Rust y GO, permitiendo que el código escrito en estos lenguajes se compile a WASM.
CVE-2021-38297 destaca un error crítico en la compilación y carga por parte de GO de binarios WASM compilados con GO. La vulnerabilidad reside en el cargador JS wasm (wasm_exec.js) proporcionado por GO, que permite cargar binarios WASM con datos sin restricciones en el argumento argv. Dado que argv se almacena en la memoria lineal de WASM, los actores maliciosos podrían explotar esto para sobrescribir la memoria lineal del programa WASM compilado con GO con una entrada argv excesivamente grande.
Esta vulnerabilidad persistió en versiones de GO anteriores a la 1.17.2.
Esta prueba de concepto muestra una aplicación de redes sociales, Vuln-Twitter, que permite a múltiples usuarios publicar contenido y comentarios. El servidor web, construido con Node.js, utiliza SQLite para almacenar los datos de publicaciones y comentarios.
El front-end emplea JavaScript plano junto con un módulo GO WASM llamado wordprocessor.wasm. Este módulo expone métodos como toLeetSpeak, que transforma cadenas de entrada en "LeetSpeak" (por ejemplo, "Hello!" se convierte en "h3ll0!").
Los módulos GO WASM ayudan a renderizar publicaciones y comentarios en LeetSpeak.

Durante el proceso de renderizado en el front-end, al recibir publicaciones y comentarios del servidor, cada comentario se renderiza a "LeetSpeak" usando el módulo GO WASM. El comentario de cada publicación se pasa como parte de la variable argv después de cargar el módulo GO WASM.
Además, existe un método, processSharedVar(), en el módulo GO, diseñado para leer la cadena ubicada en la dirección 0x5000 y convertirla a habla simplificada (por ejemplo, "How are you?" se convierte en "How r u?"). La publicación original se añade explícitamente en 0x5000 en la memoria lineal para que este método acceda a ella, modificando el contenido de la publicación.
Consulte la sección de código que hace lo mismo:

Diagrama de la memoria lineal de WASM al renderizar un comentario:

En resumen:
argv y las publicaciones en la dirección de memoria 0x5000.toLeetSpeak y processSharedVar se utilizan para el contenido de comentarios y publicaciones, respectivamente.Considerando la falta de comprobaciones de tamaño en argv debido a CVE-2021-38297, surge una amenaza potencial. Si un usuario malicioso comenta con un comentario de tamaño excesivo en una publicación que no le pertenece, este comentario se pasará a través de argv durante el renderizado. Como no hay límite de tamaño, el contenido en la dirección 0x5000 (que representa la publicación original) queda expuesto a ser sobrescrito.
Al explotar esta falla, un usuario malicioso altera efectivamente el contenido de la publicación original, de forma similar a un ataque XSS almacenado. Posteriormente, cuando otros ven la página, se muestra el contenido alterado, perpetuado por la lógica compartida del front-end aplicada al renderizado para todos, lo que resulta en que la publicación sobrescrita sea visible para todos.

Nota: Para reproducir esto necesitas instalar la versión go1.17.1 de go localmente, que es la versión vulnerable utilizada en este escenario. Puedes consultar la documentación oficial de go sobre cómo instalar versiones específicas de go.
Ahora intentemos reproducir el escenario anterior:
git clone [email protected]:gkrishnan724/CVE-2021-38297.git && cd vuln-twitternpm install para instalar todas las dependenciasnpm run resetDB, que inicializará la base de datos con algunas publicaciones y comentarios.npm run dev, que iniciará el servidor local, abre localhost:3000 en un navegador y deberías poder ver una página de inicio de sesión.Ahora, iniciemos sesión con una cuenta maliciosa usando las credenciales nombre de usuario: I_CANT_HACK, contraseña: hacker; una vez iniciada la sesión, deberías poder ver el feed con algunas publicaciones.
Esta publicación parece bastante interesante:
Amazon: ready 4 black friday? https://www.amazon.com/blackfriday
¿Qué pasaría si, usando la técnica anterior, pudiéramos sobrescribir la publicación de Amazon.com para que apunte a un enlace malicioso?
Consulta el archivo exploit.txt; este contiene el comentario que está relleno con un padding de "A"s de modo que sobrescribimos todo hasta la dirección 0x5000; al final puedes ver el texto ready for black friday? https://evil.com/blackfriday. Si copiamos este texto y comentamos en la publicación anterior, deberíamos poder sobrescribir la publicación original con el texto mencionado.
Pruébalo por ti mismo y verás :)

En esta aplicación, también he proporcionado un script de parcheo, que usa una versión más nueva de go:
npm run patchServerEsto debería recompilar el archivo go con la nueva versión e iniciar el servidor con la versión parcheada.
Ahora deberías notar que la publicación no se sobrescribe y, si observas la consola, vemos un error en su lugar: Argument length too long.

Hemos demostrado un escenario en el que aprovechar un desbordamiento de búfer en WASM sobre la memoria lineal nos permitió ejecutar un ataque XSS almacenado. Sin embargo, es esencial señalar la especificidad de este exploit: requirió que manipuláramos un texto en una dirección fijada en el código de la memoria lineal. En aplicaciones web prácticas, descubrir este tipo de vulnerabilidades puede ser extremadamente desafiante debido a ese nivel de especificidad. Además, sobrescribir datos arbitrarios en la memoria lineal sin provocar un bloqueo del sistema es complejo, particularmente al tratar con los módulos y datos internos de GO, debido en gran medida a la falta de documentación exhaustiva sobre el diseño de la memoria de GO.
Según nuestro entendimiento, creemos que el diseño de la memoria lineal de GO se representa a continuación:

Si bien esta explotación introduce vectores de ataque interesantes en el desarrollo web, particularmente dentro de WASM, también introduce riesgos de seguridad inherentes asociados con los lenguajes de programación. Por ejemplo, consideremos un escenario donde un programa en C se compila a WASM. Si el programa en C original tiene desbordamientos o vulnerabilidades, estos riesgos se transfieren al entorno WASM, exponiéndolo a vulnerabilidades y amenazas similares.
Somos estudiantes de Carnegie Mellon University y presentamos esta prueba de concepto del CVE en una de nuestras clases (18-739D Hacking101). Puedes consultar nuestra presentación aquí: GOWasm.pptx