Más vale fuerza que maña: resolviendo un QR Hunt escaneando solo dos códigos

José Miguel Moreno
4 min readApr 9, 2022

--

Este jueves 7 de abril de 2022 asistí a la primera edición del CONF.IT organizado por la Delegación de Alumnos ETSISI perteneciente a la UPM donde, además de las ponencias y talleres, en paralelo también hubo otras actividades. Una de estas actividades fue “QR Hunt”, que consistía en escanear varios códigos QR (7 en total, uno al finalizar cada charla de un track) para obtener palabras que formaban una frase desordenada. La mecánica era sencilla: forma la frase y, cuando la tengas, avisa a la organización y te llevas un premio.

Teóricamente, la única forma de formar la frase era asistir a 7 ponencias del track que fuera desde las 10 am hasta las 8 pm, escanear los códigos QR a la salida de cada una y luego ordenar las palabras obtenidas. Sin embargo, al escenear el QR de la primera charla del día me fijé en que el código no contenía la palabra como tal, sino un enlace acortado que llevaba a un imagen (un PDF en realidad, pero da igual) con la palabra correspondiente. Aunque curioso, en ese momento no le di demasiada importancia. No fue hasta después de la segunda charla y escanear otro código cuando me di cuenta de que el primer y el segundo enlace se parecían bastante:

Hmm… ¿y si hubiera algún patrón aquí? ¿Sería posible formar la frase antes de que acabara la jornada?

Efectivamente, esos dos enlaces acortados tienen unos slugs que empiezan por los mismos caracteres (“bcu”) y de la misma longitud. En base a esto, podemos asumir que qrco.de genera los IDs de forma secuencial y que la organización del CONF.IT creó todos los enlaces más o menos a la vez. Hacer fuerza bruta de una cadena de tres caracteres es factible en un corto intervalo de tiempo (y más si uno de ellos parece que solo puede tomar los valores “B” o “C”) pero, dado que qrco.de es un servicio web público que utiliza más gente, ¿cómo distinguimos los enlaces de la conferencia de toda la purria restante?

¿Quizá con un parseador de PDF que lea el texto del documento de cada enlace? ¿O puede que haciendo OCR de las vistas previas de las imágenes? ¿Redes neuronales? ¿Blockchain? Nope, el propio acortador de enlaces utilizado para generarlos nos da todos los metadatos que necesitamos.

Si nos fijamos en el código fuente de las páginas web devueltas por los dos enlaces de antes, vemos que no solo se parecen en la URL sino en el contenido. Dentro de un snippet de JavaScript embebido en el documento, encontramos el identificador de la cuenta que creó el enlace acortado a partir de un enlace a un recurso en Amazon S3 y el nombre original del documento PDF:

Viendo que era posible obtener la frase antes incluso de la pausa para comer, me senté en las últimas filas del track 2 a escribir un script sencillito para dar con la frase. En ese momento lo programé en PHP, que para estas cosas viene genial porque el lenguaje tiene de todo sin tener que usar librerías, pero como los alumnos del grado de informática de la UPM me miraron mal para este post lo he reescrito en JavaScript, que tiene más clase:

Después de menos de media hora, el script terminó de ejecutarse (buen WiFi el de la ETSISI, por cierto) y ya tenía los resultados en pantalla:

Dado que había dos frases distintas (una para cada día de la conferencia), hay más de 7 enlaces válidos. Y como en el nombre del PDF original la organización del CONF.IT fue tan amable de indicar el orden de la palabra, obtener las soluciones es pan comido:

Y eso es todo. Un agradecimiento en particular a una de las organizadoras del evento, que pese a ser totalmente consciente de cómo habíamos dado con la solución tan pronto pidió que nos dieran el premio solo por el esfuerzo. A ver si en la próxima edición me puedo llevar ese boli/destornillador tan fantástico del que no quedaban existencias a las dos de la tarde… 😜

--

--