Multiples vulnerabilidades en la aplicación OLX de Android

1. Información del reporte

Título: Multiples vulnerabilidades en la aplicación OLX de Android
Reporte ID: STIC-2014-0401
Reporte URL: http://www.fundacionsadosky.org.ar/publicaciones-2
Fecha de publicación: 2014-11-11
Fecha de última actualización: 2015-11-30
Fabricantes contactados: OLX
Modo de publicación: Unilateral

2. Información de vulnerabilidades

Clase: Information Exposure Through Sent Data [CWE-201], Authentication Bypass by Spoofing [CWE-290], Insufficiently Protected Credentials [CWE-522]
Impacto: Perdida de datos, Eludir mecanismos de seguridad
Remotamente explotable: Yes
Localmente explotable: No
Identificador CVE: N/A

3. Descripción de vulnerabilidad

OLX es un mercado de clasificados online accesible a través de internet y aplicaciones móviles. Desde Noviembre 2015, la aplicación de Android tiene entre 50 y 100 millones de descargas a nivel mundial[1].

La aplicación OLX de Android tiene dos versiones, cada una con su propia API para comunicarse con los servidores. Ambas versiones y sus correspondientes APIs se encuentran funcionando y tienen múltiples vulnerabilidades que permiten a un atacante comprometer remota y localmente cuenta de usuarios.

3.1. Acceso remoto a la cuenta de usuarios que se registraron utilizando Facebook

Se puede ingresar a OLX desde un perfil de Facebook y asociarlo a una cuenta de correo que no es propia. OLX no verifica que cuenta y perfil sean del mismo propietario y envía al atacante la contraseña del usuario del correo electrónico consignado.

3.2. Acceso remoto a la cuenta de cualquier usuario

La primera versión de la API de la aplicación de OLX también tiene problemas de validación del servidor. Cuando se envía un pedido de registro utilizando Facebook que contiene una dirección de email de una cuenta víctima ya registrada, pero el token de acceso de una cuenta de Facebook no relacionada a esa dirección (por ejemplo, una controlada por una atacante), el servidor responde al pedido con un hash MD5 sin salt de la contraseña de la cuenta de la víctima. Este hash puede ser usado por un atacante para impersonar a la víctima utilizando cualquiera de las APIs de OLX de Android o puede llegar a ser empleada para realizar ataques de cracking offline (por ejemplo, utilizando sitios como Crackstation [2]) para intentar obtener la contraseña del usuario.

3.3. Autenticación insegura en la nueva API de OLX

La autenticación de usuarios en la API de la nueva aplicación de OLX utiliza un protocolo de desafío y respuesta para obtener una clave de sesión que sirve luego para autenticar los pedidos del usuario. Este proceso de autenticación implementado por OLX tiene varios problemas.

Un atacante puede capturar el hash del la dirección de correo y la contraseña de un usuario y reutilizar dicho hash luego para loguearse como dicho usuario o directamente obtener el desafío correspondiente a uno de una cuenta víctima con solo su dirección de correo o nombre de usuario y con este desafío falsificar la clave de sesión.

3.4. Protección insuficiente de la capa de transporte

Los dispositivos corriendo la aplicación de OLX se comunican con el servidor utilizando HTTP. Por lo tanto, atacantes en la misma red pueden capturar información sensible del usuario cuando éste se encuentre utilizando la aplicación. A modo de ejemplo: podrían obtener las credenciales de usuarios cuando se están registrando o cuando cambian su contraseña. También se pueden capturar los tokens de acceso emitidos por Facebook, las claves de sesión (en la nueva versión de la aplicación) , etc.

4. Paquetes vulnerables

5. Información y soluciones del fabricante

La vulnerabilidad descripta en la sección 3.2 fue solucionada. La última versión revisada (4.35.2) hasta el 30 de Noviembre de 2015 seguía siendo vulnerable a los restantes ataques mencionados en el reporte.

6. Créditos

Las vulnerabilidades fueron descubiertas e investigadas por Joaquín Manuel Rinaudo. La publicación de este reporte fue coordinada por Programa Seguridad en TIC.

7. Descripción técnica

7.1. Acceso remoto a la cuenta de usuarios que se registraron utilizando Facebook

Cuando un usuario se loguea utilizando Facebook, la aplicación de OLX utiliza el protocolo de Oauth vía el SDK de Facebook para requerirle al usuario acceso a OLX a su cuenta de Facebook. Si el usuario autoriza este acceso, a la aplicación se le provee un token de acceso que podrá ser utilizado para obtener información personal de usuario o realizar acciones en su nombre.

La API de la versión anterior de la aplicación también utiliza Oauth para comunicarse con los servidores de OLX. La aplicación usa la librería Oauth-signpost para ello. Si un usuario se loguea utilizando la su nombre y contraseña, OLX utiliza el nombre de usuario como clave de cliente y un hash MD5 de la contraseña como secreto para firmar los pedidos.

El secreto del cliente es obtenido desde el servidor cuando un usuario utiliza Facebook para loguearse. Cuando el usuario clickea en el botón de "Login with Facebook" se realiza un pedido a api.olx.com/iphone/user/facebook/[USER-ID]/connect con el token de accceso de Facebook como parámetro para obtener este secreto. Si el usuario ya existía, el servidor no valida si el token de acceso es válido, por lo que un atacante puede obtener el secreto del usuario con solo su ID de Facebook y proveyendo un token de acceso falso. El servidor responderá a este pedido con un objeto json que contiene el ID del usuario (de OLX), su dirección de correo y el secreto correspondiente a la cuenta asociada a ese ID de cuenta de Facebook. En realidad, el secreto se encuentra encriptado con una clave fija ("0395a67c9aa847a756daa8535917e805") y un IV con solo ceros. Estos valores se pueden observar en la clase com.olx.olx.util.OlxCryptoUtil.

En la nueva API, la aplicación necesita obtener la clave de sesión para autenticar los pedidos del usuario. Para hacerlo, envía un pedido de GET a api-v2.olx.com/users/facebook/[USER-ID] con el token de acceso de Facebook como parámetro dentro de la URL. Nuevamente un atacante puede enviar un token de acceso inválido y seguir obteniendo la clave de sesión del usuario. Esta clave puede ser utilizada para realizar cualquiera de los pedidos expuestos por la nueva API. Estos pedidos a la API pueden econtrarse en la interfaz com.olx.smaug.api.AuthenticatedContract. Las nuevas versiones de OLX utilizan la librería retrofit [3] para convertir esta interfaz en la API usada para comunicarse con el servidor.

7.2. Acceso remoto a la cuenta de cualquier usuario

Al registrarse usando Facebook por primera vez en la primera versión de OLX, se envía un pedido POST a api.olx.com/iphone/user/facebook/[USER-ID]/signup especificando el token de acceso obtenido por Facebook, la dirección de correo relacionada a esa cuenta de Facebook junto con el nombre completo del usuario y un ID del país. El servidor responde a este pedido de la misma forma que cuando un usuario se loguea, con una clave que será usada como secreto para el protocolo Oauth.

Si un atacante cambia la dirección correo por una de un usuario existente (manteniendo el mismo token de acceso de Facebook), el servidor responde con la clave generada, que cuando es desencriptada (con las claves especificadas en [Sec. 7.1]), corresponde a un MD5 hash sin salt de la contraseña de dicho usuario. Esto entonces permite a los atacantes obtener remotamente el hash de la contraseña de cualquier usuario de OLX. Este hash puede ser utilizado como secreto de Oauth para la API anterior de OLX o incluso con ella generar un hash válido para el protocolo de desafío y respuesta de la nueva API. Un atacante también podría intentar romper el hash de forma offline para obtener la contraseña en texto plano.

El siguiente POC (proof-of-concept) script de python muestra que es posible obtener el hash MD5 de la contraseña de cualquier cuenta solo con la dirección de correo del usuario. Es necesario pasar un token de acceso válido de Facebook junto con su ID correspondiente. Estos valores pueden obtenerse registrándose a OLX con Facebook con una cuenta y capturando el tráfico para obtener el token de acceso de Facebook cuando este es enviado al servidor.

[+ full code]

7.3. Autenticación insegura en la nueva API de OLX

En la nueva API de la aplicación, la autenticación consiste en pedir primero un desafío a api-v2.olx.com/users/challenge con el usuario como parámetro. Una vez que el desafío es obtenido, la aplicación realiza un SHA512 sobre la concatenación del hash MD5 de la contraseña con el usuario (es decir, SHA512(MD5(contraseña)+usuario)). Luego, tanto el desafío como el hash son enviados al servidor como parámetros de URL (c y h respectivamente) a api-v2.olx.com/users/login para luego obtener la clave de sesión.

Hay varios problemas con el procedimiento de autenticación. El desafío del servidor es predecible dado que es un base64 del nombre de usuario (encriptado utilizando cifrado Ceasar), el ID del usuario y un timestamp. Luego puede ser fabricado por un atacante.

Además, el desafío no es usado en el hash SHA512 para modificar la respuesta de la aplicación cada vez que un usuario se loguea entonces si un atacante puede capturar el hash, puede reutilizarlo para loguearse pidiendo un nuevo desafío y después respondiendo con el hash capturado y dicho desafío. Una nota interesante es que el desafío probablemente sea predecible e incluye el ID del usuario porque el servidor necesita una forma para saber de que usuario es el hash que recibió (sin guardar ningún estado) y así poder recalcular el hash con el usuario y la contraseña del usuario correspondiente a dicho ID para compararlo con el hash suministrado por el usuario.

Finalmente, la clave de sesión obtenida del servidor con el mecanismo de autenticación es realmente una codificación en base64 del ID del usuario junto con un timestamp del servidor. Esta clave de sesión predecible permite a los atacantes saltarse el procedimiento de login generando una clave de sesión válida simplemente con pedir un desafío al servidor para la víctima (utilizando su dirección de correo o nombre de usuario), decodificar el desafío (en base64), borrar el nombre de usuario y el primer delimitador ('|') y luego codificar nuevamente el resultado a base64.

7.4. Protección insuficiente de la capa de transporte

Por último, toda la comunicación de ambas versiones de las APIs entre la aplicación y el servidor es realizada sobre HTTP. Luego, un atacante en la misma red o en la ruta al servidor podría capturar información sensible. Por ejemplo, en ambas aplicaciones de OLX, los siguientes pedidos que contienen información privada podrían llegar a ser capturados:

En la nueva API, la clave de sesión de usuario puede ser capturada cuando se realiza cualquiera de los pedidos de la interfaz AuthenticatedContract.

8. Cronología del reporte