Skip to main content

Solución de Fetch the Flag CTF 2022: Treasure Trove

Escrito por

Luke Watts

feature ctf treasure trove

10 de noviembre de 2022

0 minutos de lectura

¡Gracias por jugar Fetch con nosotros! Felicitaciones a los miles de jugadores que participaron en Fetch the Flag CTF. ¡Y muchas gracias a los Snykers que crearon, probaron y documentaron los desafíos!

Este año, Fetch the Flag fue muy divertido, ¡aunque también implicó mucho trabajo! Con 16 desafíos y poco tiempo, no todos los equipos pudieron completarlos. Para quienes no lograron vencer al reloj, veremos cómo nuestro equipo abordó el desafío Treasure Trove.

Guía paso a paso

El enunciado del desafío decía: «Ya está disponible el último Treasure Trove, pero ¿dónde puse mi clave de licencia?». Para empezar, hay una etiqueta que dice Ingeniería inversa y se proporciona un archivo obfuscator.js.

También hay un enlace a un sitio web que incluye campos de entrada de 5 x 5 caracteres, un botón y unas ilustraciones maravillosas que me recuerdan a cuando jugaba Curse of Monkey Island.

Juego de navegador Treasure Trove que muestra un cofre encadenado en una isla tropical, un barco pirata, campos de código y el botón “¡Canjea y surca los siete mares!”

Si revisas el código proporcionado, encontrarás una herramienta que convierte código legible para las personas en código basura.

Ahora, revisa el sitio web. Hay un endpoint swashbuckle.js que contiene un método llamado validate. El código parece coincidir con el resultado que genera el ofuscador. Mmm…

Si miramos más de cerca, vemos que el método validate está disponible en window y se ejecuta al enviar el formulario. ¡Vaya! Parece que la única forma es aplicar ingeniería inversa a validate… ¿Podrá ayudarnos el navegador?  Ejecutemos validate.toString() desde la consola del navegador. ¡Bingpot!

function anonymous(
) {

const segementOne = document.getElementById('seg-1');
const segementTwo = document.getElementById('seg-2');
const segementThree = document.getElementById('seg-3');
const segementFour = document.getElementById('seg-4');
const segementFive = document.getElementById('seg-5');

const setError = (message) => {
  document.getElementById('error-msg').innerText = message;
}

setError('');
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
const key = segementOne.value + segementTwo.value + segementThree.value + segementFour.value + segementFive.value;
if (key.length != 25) {
  setError('Invalid redemtion code!')
  return;
}

let val = 0;
for (let i = 0; i < 25; i++) {
  val += key.charCodeAt(i);
  if (!characters.includes(key[i])) {
    setError('invalid characters');
    return;
  }
}

if (val != 1800) {
  setError('invalid code');
  return;
}

fetch('/api/validatekey/' + key)
.then(async res => {
  const result = await res.json();
  setError('Argg ye got it! ' + result.flag);
});

}

Al parecer, el código realiza los siguientes pasos:

  1. Obtiene los valores de los campos de entrada HTML

  2. Verifica que los caracteres estén dentro del rango A-Z0-9

  3. Recorre los caracteres, los convierte a charCode y suma esos valores. El método charCodeAt() devuelve un entero entre 0 y 65535 que representa la unidad de código UTF-16 en el índice indicado. Fuente

  4. Genera un error si el valor no es igual a 1800

  5. Si el valor es igual a 1800, los valores de entrada originales se envían a un endpoint de API

La conclusión más interesante es que, a menos que el valor sea 1800, el código no es válido.

  1. 1800 / 25 (el total de caracteres disponibles)

  2. 72

  3.  String.fromCharCode(72)

  4. Devuelve H

Ingresar HHHHH en cada campo

Pantalla de un juego de navegador titulado “Treasure Trove”, con un cofre del tesoro encadenado debajo de una palmera en una isla, un barco pirata y el texto “¡Canjea y navega por alta mar!”

¡Doble bingpot!

Página del navegador titulada “Treasure Trove” que muestra un cofre encadenado en una isla con palmeras, un barco pirata, texto codificado y cinco campos de entrada

Logramos resolver este desafío sin tener que analizar el código del ofuscador. ¡Así nos quedó mucho tiempo para empezar con el siguiente desafío!

¿Quieres saber cómo encontramos las demás banderas? Visita nuestra página de soluciones de Fetch the Flag para ver cómo lo hicimos.