Cómo viajar en taxi a expensas de otra persona: vulnerabilidades en el ejemplo de un servicio

Después de encontrar vulnerabilidades en la banca móvil de un banco ucraniano ( post ), quería cambiar un poco la dirección y cambiar de servicios financieros a otros.

Un artículo publicitario sobre la aplicación de taxi móvil actualizada me llamó la atención, y lo elegí como experimental.

Aquí las herramientas son las mismas: PC, Fiddler, teléfono inteligente Android: instale la aplicación y realice un seguimiento de sus solicitudes.

Específicamente no consideré solicitudes y respuestas al registrarme o iniciar sesión (por ejemplo, no verifiqué la posibilidad de una contraseña de fuerza bruta), pero cambié a las funciones disponibles después del registro.

Como no tenía un historial de viajes con este servicio y no quería realizar un viaje real para realizar pruebas, necesitaba datos de uno de los otros clientes. Decidí pedirle a mis amigos una cuenta en el servicio. Entre los conocidos había clientes de este taxi, pero lo llamaron a la antigua usanza, con la ayuda de una llamada.

Luego, comencé a buscar números de teléfono entre la información disponible públicamente en Internet, por ejemplo, en el sitio web oficial y entre las revisiones en las redes sociales (a menudo, los clientes insatisfechos, que describen quejas, los dejan en los comentarios para que el público los vea en lugar de enviar la empresa a su PM personal ). Como resultado, encontré un par de teléfonos en uno de los sitios de búsqueda de empleo. Sustituí uno de ellos en solicitudes posteriores y recibí información que no debería haber sido accesible a nadie desde el exterior.



Estos fueron los siguientes problemas:

1. Obtenemos la identificación del cliente, su nombre, teléfono, correo electrónico y ciudad (el taxi funciona en varias ciudades).

Cuando la aplicación carga el perfil, se ejecuta la siguiente solicitud POST:

https://sometaxi/mobile3/templateAll.php?PHPSESSID=4cmdlokh4luo209d88kv6uh7 Content-Type: application/x-www-form-urlencoded charset: utf-8 User-Agent: User Host: sometaxi Connection: Keep-Alive Accept-Encoding: gzip Content-Length: 37 func=loadMyInfo&phone=%2B380671234567 

Sustituyendo el número de teléfono de otra persona en la función loadMyInfo&phone , en respuesta recibí la identificación del cliente, su nombre completo, teléfono, correo electrónico y ciudad:

 [{"id":14014,"varFirstName":" ","varLastName":"","varSurName":" ","varTel":"+380671234567","varTel2":"","varEmail":"Sergey_ivan@some.mail","city":1,"cityName":""}] 


2) Información sobre las tarjetas de pago del cliente.

En la segunda solicitud, pude obtener información sobre las tarjetas de pago agregadas por el cliente a mi cuenta personal:

 https://sometaxi/mobile3/ClientCard.php?PHPSESSID=4cmdlokh4luo209d88kv6uh7 HTTP/1.1 Content-Type: application/x-www-form-urlencoded charset: utf-8 User-Agent: User Host: sometaxi Connection: Keep-Alive Accept-Encoding: gzip Content-Length: 58 data={"Task":"GetClientCardsData","phone":"+380671234567"} 

La respuesta es:

 {"data":[{"masked_card":"512345XXXXXX6789","rectoken":"ccaffe873a0e88caf49bc65bbef2390329","card_type":"MASTERCARD","default":true,"card_name":""}]} 

Aquí estaban disponibles: un número de tarjeta truncado, algún tipo de token, tipo de tarjeta, si la tarjeta está instalada por defecto y su nombre.

3) Obtener información sobre los viajes del cliente

La tercera solicitud, loadHistory, me proporcionó la cantidad de información más grande y más importante (como pensaba entonces):

 https://sometaxi/mobile3/templateAll.php?PHPSESSID=4cmdlokh4luo209d88kv6uh7 HTTP/1.1 Content-Type: application/x-www-form-urlencoded charset: utf-8 User-Agent: User Host: sometaxi Connection: Keep-Alive Accept-Encoding: gzip Content-Length: 38 func=loadHistory&phone=%2B380671234567 

Parte de la respuesta (como antes, los datos cambiaron) :

 {"id":454875,"From":"- ., 1","To":"і ., 13","When":"10-01-2019 15:55","WhenDate":1569942900,"Price":"160","Rate":0,"preorder":0,"status":1,"orderid":"11174445","additionalServices":"[]","classAvto":2,"callsignid":6426,"Car":"  ,Toyota Corolla,, 3733 ","city":1,"cityName":"ї","distance":"0.00"} {"id":408880,"From":"  ., 2","To":"- ., 1","When":"25-12-2018 03:44","WhenDate":1545709440,"Price":"79","Rate":0,"preorder":0,"status":1,"orderid":"10966503","additionalServices":"[]","classAvto":2,"callsignid":4545,"Car":"  ,Toyota Corolla,, 0415 ","city":null,"cityName":null,"distance":"0.00"} 

Aquí están disponibles: dirección de salida, dirección de destino, fecha y hora del viaje, costo, así como el nombre completo del taxista, tipo, color y número de su automóvil.

Total: con un par de solicitudes, por número de teléfono puede averiguar todo sobre el cliente de este servicio, incluidos ciertos detalles de su vida personal (por ejemplo, un viaje al Año Nuevo a las 2 a.m. de una dirección a otra).

Seguramente había otros lugares en la aplicación donde se podía obtener otra información. Pero ya se encontró suficiente para informar a los desarrolladores sobre esto, lo que hice inmediatamente para dirigir las direcciones de trabajo.

Nos mantuvimos en contacto durante un mes y luego me pagaron una tarifa.



Y luego esta publicación podría terminar, pero decidí verificar nuevamente si todos los errores fueron corregidos.

Sí, dos de las tres solicitudes ya no me daban información de otras personas, pero una aún era válida.

Las tarjetas de pago se agregan a esta aplicación de la misma manera que a cualquier otra: primero, en una página especial, el cliente indica el número completo, la fecha de vencimiento y las tarjetas CVV. Luego viene la verificación cancelando 1 UAH. y la confirmación del cliente de dicha operación utilizando 3-D Secure / LookUp. Esta es una práctica normal, el número completo y otros detalles de pago de las tarjetas de los clientes no estaban en las solicitudes.

Pero como vi que mi tarjeta agregada se elimina al solicitar los data={"Task":"DeleteClientCardsData", "rectoken":"bc65bbef2390329ccaffe873a0e88caf49" } del formulario data={"Task":"DeleteClientCardsData", "rectoken":"bc65bbef2390329ccaffe873a0e88caf49" } , decidí verificar: qué sucederá si especifico la rectificación de otro cliente.

4) Eliminar la tarjeta de otra persona por ficha

Ejecuto la solicitud con otro token:

 https://sometaxi/mobile3/ClientCard.php?PHPSESSID=5n4tim74asve7uefdf3hvd6c3 HTTP/1.1 Content-Type: application/x-www-form-urlencoded charset: utf-8 User-Agent: Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-G925F) Host: sometaxi Connection: Keep-Alive Accept-Encoding: gzip Content-Length: 86 data={"Task":"DeleteClientCardsData","rectoken":"ccaffe873a0e88caf49bc65bbef2390329"} 

¡Y la carta alienígena se ha ido!

También verifiqué esto con la misma consulta # 2: ¿fue solo una respuesta visual {"status":"Success"."err":""} , o fue la tarjeta realmente eliminada del cliente.

El mapa ha sido eliminado.

Inmediatamente escribí una segunda carta, disculpándome, pero decidí seguir experimentando creando otra cuenta para mí: si la tarjeta se puede eliminar con el token, ¿tal vez se pueda vincular con el mismo token y se pueda vincular a sí misma?

5) Agregar la tarjeta de otra persona por token a su cuenta

Sí, no languideceré: la tarjeta de otra persona podría estar atada a sí misma. Lo principal es saber rectoken (y puedes obtenerlo gracias al problema abierto # 2).

En la solicitud POST, fue posible especificar cualquier dato, los primeros 6 y los últimos 4 dígitos del número de tarjeta, al menos 500,000 **** 1111, la tarjeta estaba asociada visualmente con estos datos, y el token era de otro cliente y era válido.

 POST https://sometaxi/mobile3/ClientCard.php?PHPSESSID=5n4tim74asve7uefdf3hvd6c3 HTTP/1.1 Content-Type: application/x-www-form-urlencoded charset: utf-8 User-Agent: Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-G925F) Host: sometaxi Connection: Keep-Alive Accept-Encoding: gzip Content-Length: 221 data={"Task":"ClientCardData","default":false,"phone":"+380991234567","masked_card":"500000XXXXXX1111","card_name":"Test","card_type":"MASTERCARD","rectoken":"4f6d228517f2d45690670aba78013a0408"} 

¿Qué significa esto? Debido a la posibilidad de vincular el token a mi cuenta, podría hacer un viaje a expensas de otra persona sin conocer los detalles completos de la tarjeta y sin ninguna verificación adicional; después de todo, el cliente ya ha agregado la tarjeta y el servicio de pago la verificó con éxito.

Explicación sobre la posibilidad de pagar con la tarjeta de otra persona:
Para simplificar la entrada de detalles de pago para pagos, se utiliza el pago con un solo clic basado en tokens. En la primera compra, el cliente ingresa los datos de pago, con pagos posteriores al cliente, es suficiente hacer clic en el botón "pagar".

Un token es un número único que se asigna a un conjunto de parámetros de tarjeta en el sistema. Este token se puede usar para pago directo sin ingresar CVV y sin autenticación 3-D Secure.

Opcional
La creación de un token es un proceso de pago / bloqueo exitoso de fondos en la tarjeta de un cliente con el ingreso de todos los detalles del cliente (número de tarjeta, fecha de vencimiento, CVV). Puede crear un token de la siguiente manera:

  1. Aceptar pago (Compra): pago exitoso por parte del cliente con la introducción de los detalles completos de la tarjeta. A la tarjeta se le asigna un recToken y se transmite en la respuesta.
  2. Verificación de la tarjeta / recibo de un token (Verificar) - verificación exitosa de la tarjeta, bloqueando fondos en la tarjeta del cliente. A la tarjeta se le asigna un recToken y se transmite en la respuesta.


Cancelación por token: la operación de debitar / bloquear fondos en la tarjeta, sin la participación del cliente, transfiriendo el token del comerciante.

Una explicación de ejemplo se toma de aquí .

Los desarrolladores pidieron demostrar la posibilidad de transferir el token de su cuenta a la mía y solicitar un taxi; tenían que asegurarse de que la deducción del token realmente sucedería. Por supuesto, la orden pasó, el dinero fue cargado ( no entré al auto ). Más tarde me pagaron más dinero.



Como puede ver en este y en artículos anteriores, a veces PHPSESSID, Authorization o SecurityToken no es suficiente.

Si es desarrollador, siga lo que le da cuando lo solicita. Si es un probador, busque y encuentre, pero asegúrese de informar a los desarrolladores al respecto. Las vulnerabilidades están llenas de aquí y de allá, así que sé un hacker blanco.

Source: https://habr.com/ru/post/443928/


All Articles