Amañamos una Tragamonedas y Retamos al Hacker Summer Camp a Romperla

La banca siempre gana. Esa era toda la propuesta en la pantalla de nuestro stand durante el Hacker Summer Camp — DEF CON, Black Hat y BSides Las Vegas. Elige un alias — sin correo, sin registro — recibe cinco créditos y tira de la palanca de una tragamonedas “777” en neón. Los rodillos giran, caen en una calavera, y el feed del crupier imprime paid=false. Tira otra vez. Calavera. Otra vez. Calavera.

Diez premios por evento, cuatro de ellos reservados para quien reventara el bug más difícil, y un contador en la cabecera bajando en vivo. El correo solo se pedía después de que alguien ganara de verdad.

La máquina está amañada. Te lo avisamos, ahí en el pie de página: esta máquina está amañada a propósito. Ese es el punto. El cliente nunca puede ganar. Pero la máquina está hablando con un servidor, y el servidor es descuidado. Lee la máquina, rompe la máquina, y el premio de verdad eran hasta tres meses de Tandera, gratis.

La pantalla inicial de 777: Jackpot or Jail

Bajo el neón era un CTF web de cuatro flags, cada una un bug que vemos en la práctica — sobre todo en el rincón poco regulado de los juegos de “casino social” en línea. Aquí va el recorrido, ahora que los códigos ya se reclamaron.

Flag 1 — el cliente es un mentiroso

Cada giro envía un trozo de telemetría al servidor: client_outcome, los rodillos que el navegador cree que mostró. El cliente honesto reporta lo que sacó. El detalle es que el servidor decide el resultado e ignora tu reporte por completo — los rodillos nunca son tuyos para cantarlos.

¿Y si los cantas de todos modos? Abre la pestaña de red, repite el giro con client_outcome puesto en un trío ganador, y el servidor responde:

nice try — the client cannot authorize a payout. the house signs its own outcomes.

El feed del crupier con el giro manipulado y la captura de la flag 1

Esa es la flag uno, con 100 puntos de consolación y ningún premio. La lección es la más vieja de la seguridad web: el cliente está controlado por el atacante. Un número alarmante de front-ends reales de apuestas decide la victoria en JavaScript y simplemente confía en que el navegador la reporte de vuelta. El nuestro no confía — pero te entrega una flag por demostrar que entiendes por qué importa.

Flag 2 — XOR no es cifrado

Cuando te sientas, /api/hsc/start devuelve un vault: un blob base64 que la máquina llama “cifrado”. No lo es. Es JSON pasado por un XOR de clave corta repetida — ofuscación disfrazada de candado.

XOR cae con un crib de texto conocido. Sabes que el blob es JSON, así que sabes que empieza con {"flag":". Haz el XOR del texto cifrado contra ese prefijo conocido y la clave repetida sale al instante; aplícala al resto y el vault se lee en texto claro, incluyendo una clave de firma por sesión y, de regalo, la receta para usarla. Envía la clave recuperada y te llevas la flag dos: 250 puntos y un mes de Tandera.

Enviar el token recuperado del vault se lleva la flag 2

El punto no es que XOR sea débil — es que un secreto que le entregas al cliente no es un secreto. Toda clave que llega al navegador se puede recuperar desde el navegador. Ya hemos abierto respuestas de API “cifradas” exactamente así en engagements reales, y el cifrado era exactamente así de delgado.

Flag 3 — el pago doble

Hay un botón de “reclamar bono” que vale cinco créditos gratis, una vez por sesión. El servidor comprueba si ya reclamaste y entonces concede los créditos. Léelo otra vez despacio: comprueba y luego actúa, y no hay nada atómico entre ambas cosas.

Ese hueco es un TOCTOU — time-of-check to time-of-use. Haz clic en el botón y recibes tus cinco créditos como buen ciudadano. Un doble clic perezoso no basta; dispara una ráfaga de verdad a la vez y varias de ellas leen “aún no reclamado” antes de que cualquiera termine de escribir “reclamado”. El bono se paga una y otra vez. El servidor nota que pagó varias veces y te entrega la flag tres — 500 puntos, dos meses.

La ráfaga dispensa el bono varias veces y entrega la flag 3

Esta es la carrera clásica detrás de todo incidente de “retiré mi saldo dos veces”: una guarda correcta en aislamiento e inútil bajo concurrencia. Un servidor de dev serializado lo esconde por completo; producción, con workers realmente paralelos golpeando una sola fila compartida, no.

Flag 4 — probablemente injusto

El gran premio se esconde detrás de la función de la que la máquina más se enorgullece: es provably fair (demostrablemente justa). Cuando te sientas, /start se compromete con una server seed publicando su hash. El resultado de cada giro es v = int(sha256(round_seed : client_seed : nonce)[:8], 16), y un giro es jackpot cuando v % 20000 == 7770 — alrededor de uno entre veinte mil, así que nunca comprarás tu camino hasta ahí con cinco créditos. Cada giro incluso te devuelve su propio round_seed para que verifiques que la máquina no te hizo trampa.

Esa transparencia es el bug. Las round seeds son una cadena hacia adelanteround_seed[n+1] = sha256(round_seed[n]) — y la máquina revela cada una a medida que juegas. Revela una sola seed y puedes avanzar el hash para calcular cada ronda futura: cada seed, cada resultado, hasta donde quieras mirar. Así que giras una vez, tomas la seed revelada y mueles sha256 hacia adelante hasta encontrar el nonce cuyo resultado da el jackpot. Entonces lo reclamas — POST /api/hsc/jackpot {nonce, seed} — nombrando la ronda exacta en la que la máquina pagará, y adjuntando la seed de esa ronda para probar que puedes calcularla. Adivina una seed equivocada y el reclamo es rechazado; no hay nada que forzar. Cantaste el jackpot antes de que ocurriera. Esa es la flag cuatro — 1000 puntos y los tres meses completos.

Los casinos provably fair de verdad se comprometen con la seed y la revelan después, en la dirección segura. Equivoca la dirección y la prueba de justicia se convierte en una bola de cristal.

Cantar la ronda del jackpot antes de que ocurra se lleva la flag 4

Las cuatro flags capturadas, con el premio listo para reclamar

El ranking High Rollers

¿Por qué un casino?

Porque el código de casino es donde estos bugs sostienen el negocio y, demasiadas veces, están en producción. Resultados decididos en el cliente, “cifrado” casero, actualizaciones de saldo no atómicas y esquemas provably-fair que filtran el futuro no son exóticos — son los hallazgos del día a día de las pruebas de aplicaciones web, y el dinero los vuelve caros. Envolverlos en una tragamonedas solo hizo el riesgo legible.

Y para eso existe Tandera. Construimos la plataforma que los equipos de seguridad ofensiva usan para encontrar exactamente estos problemas y convertirlos en informes limpios, estandarizados y white-label — desde el descubrimiento de activos hasta los hallazgos y la entrega. La tragamonedas era un juguete. La metodología detrás de encontrar sus cuatro bugs es el trabajo de verdad.

A todos los que leyeron la máquina en vez de tirar de la palanca: el ranking era vuestro, y los meses también. Nos vemos en el próximo camp.

acceso anticipado

Consigue Tandera antes de tu próximo engagement.

Únete a la waitlist para acceso anticipado. Estamos incorporando equipos de pentest por oleadas.

Onboarding prioritario para equipos de pentest.
Línea directa con quienes lo construyen.
Precio de acceso anticipado, asegurado.

Sin spam, sin tarjeta. Cancela cuando quieras.

enespt-br