Quería ejecutar la siguiente instrucción en SQLite
ALTER TABLE staff
ADD COLUMN IF NOT EXISTS username TEXT NOT NULL DEFAULT "";
pero SQLite no soporta la claúsula IF NOT EXISTS en ADD COLUMN.
Así que le pedí sugerencias a Claude 3.5 Sonnet y GPT-4o.
Ambos estaban de acuerdo en que esto funcionaría:
BEGIN TRANSACTION;
-- Check if the username column exists, if not, add it
SELECT CASE
WHEN COUNT(*) = 0 THEN
'ALTER TABLE staff ADD COLUMN username TEXT NOT NULL DEFAULT ""'
ELSE
'SELECT 1' -- Do nothing
END
FROM pragma_table_info('staff')
WHERE name = 'username';
Parece un buen truco: se comprueba en los metadatos de SQLite a ver si existe una columna username (se cuenta cuántas veces existe) y si el conteo es 0, entonces hay que ejecutar el ADD COLUMN.
Pero, hemos sido engañados.
El SQL es sintácticamente correcto pero la orden dentro del THEN es simplemente para mostrar un string, no para ejecutar el ALTER TABLE.
Cuando te digan que los ingenieros software no existirán en 5 años, acuérdate de esto. O de esto otro:
$ file mystery_file mystery_file: SQLite 3.x database, last written using SQLite version 0, page size 1024, file counter 4, database pages 0, cookie 0x2, schema 1, UTF-8, version-valid-for 0
Es un archivo que contiene una base de datos SQLite.
$ sqlite3 mystery_file SQLite version 3.43.2 2023-10-10 13:08:14 Enter ".help" for usage hints. sqlite> .schema CREATE TABLE idx (val text); CREATE TABLE data (id integer primary key asc, val blob);
Analicemos el contenido:
sqlite> select * from idx; 1c9a44eb2e8eaf3da1eb551da310cce7 sqlite> select * from data LIMIT 3; 1|� 2|� 3|�
La tabla idx solo tien un columna val con una única fila: 1c9a44eb2e8eaf3da1eb551da310cce7
Buscando en Google, vemos que ese hash corresponde al string ‘lost’
Respecto a los binarios guardados en la tabla data:
Podemos copiar esos valores hexa, convertirlos a binario y generar un fichero, que podremos analizar con el comando file:
Pare que son 100 blobs gzip. Saquemos todos ellos:
import sqlite3
# Connect to the SQLite database
conn = sqlite3.connect('mystery_file')
cursor = conn.cursor()
# Query to fetch all blobs from the data table
cursor.execute("SELECT val FROM data")
rows = cursor.fetchall()
# Concatenate all blobs into a single file
with open("combined_blobs.gz", "wb") as file:
for row in rows:
file.write(row[0])
# Close the connection
conn.close()
print("All blobs have been concatenated into 'combined_blobs.gz'.")
Tras descomprimir con gunzip el fichero combined_blobs.gz:
Y tratando de descifrar ese bonito ASCII art estuvimos más de 24 horas. Sacamos todas las posibles combinaciones (ordenando por longitud de cada línea y agrupando las de la misma longitud). Pero… había una forma más fácil o de idea feliz.
Resulta que si buscamos el ‘lost’ de la tabla idx con la palabra números:
Resulta que en la serie Lost esos números son recurrentes… ¿Y si sacamos los blobs en ese orden?
import sqlite3
# Connect to the SQLite database
conn = sqlite3.connect('mystery_file')
cursor = conn.cursor()
# Select the specific rows with the provided indices
indices = [4, 8, 15, 16, 23, 42]
blobs = []
for index in indices:
cursor.execute("SELECT val FROM data WHERE rowid=?", (index,))
row = cursor.fetchone()
if row is not None:
blobs.append(row[0])
# Concatenate the selected blobs into a single file
with open("selected_combined_blobs.bin", "wb") as file:
for blob in blobs:
file.write(blob)
# Close the connection
conn.close()
print("Selected blobs have been concatenated into 'selected_combined_blobs.bin'.")
Vaya… estuvimos 24 horas deambulando cuando la solución estaba a nuestro alcance con una ‘simple’ búsqueda:
Nota: Este WriteUp ha sido desarrollado por Owen, del equipo basados. ¡Muchas gracias por la colaboración! (y si alguien más quiere participar, será bienvenido 🙂
Este tercer nivel, aunque era relativamente sencillo, quizá más que el anterior, no lo han resuelto tantos equipos.
“1111111111111111111 tres primos son y juntos les gusta ir”.
La primera pregunta que nos hicimos: ¿este número, interpretado como decimal, es primo? Sí, lo es.
La segunda: ¿este número, interpretado como binario, es también primo? Si lo pasamos de binario a decimal, obtenemos 524287, que también es primo.
Tenemos dos primos, nos falta el tercero. Si contamos el número de unos, observamos que son 19, así que parece que lo tenemos.
Recapitulando, tenemos 3 primos:
1111111111111111111
524287
19
También sabemos que les gusta ir juntos, pero no sabemos en qué orden. Podemos ir problando, aunque, por ser ordenados, podría tener sentido que fueran de menor a mayor, tal que así:
195242871111111111111111111
Ahí está la respuesta que buscábamos; los tres primos, juntos, en familia.
Nota: Este WriteUp ha sido desarrollado por Owen, del equipo basados. ¡Muchas gracias por la colaboración! (y si alguien más quiere participar, será bienvenido 🙂
El título del segundo nivel, “Beautiful music”, nos adelanta que tendrá que ver con música.
Nos proporcionan el fichero music.it, que podemos escuchar con cualquier reproductor común. Escuchamos dos instrumentos, un piano y una percusión, intercalados. Aunque esto no sea un nivel de hack-it, sino de solve-it, es inevitable ejecutar file music.it para comprobar de qué tipo de archivo se trata.
$ file music.it
music.it: Impulse Tracker module sound data - "untitled" compatible w/ITv217 created w/ITv200
Vemos que se trata de un fichero creado con Impulse Tracker, un antiguo secuenciador para MS-DOS. Antes de enfocarnos en el sonido en sí, hemos abierto el fichero con Schism Traker, para ver qué información nos da.
Este programa nos permite reproducir y editar la secuencia de las notas, su escala, etc. En el panel inferior, podemos ver qué nota se reproduce en cada paso: D#5, E-6, F#5… Nuestra intuición nos dijo que la contraseña podría estar detrás de esa secuencia de notas, pero no salía nada que tuviera sentido.
Después de trastear con SchismTracker, sin éxito, tiramos de un clásico: el espectrograma de Audacity.
De aquí sí parece que puede sacarse algo. Después de darle vueltas a cómo interpretarlo, viendo el espectrograma y escuchando el audio, pensamos que el mensaje podría estar codificado en morse. En el espectrograma, se ven bloques bastante bien diferenciados, por ejemplo:
En este primer bloque, podemos ver que los 3 golpes de percusión y la primera nota de piano, más larga, se pueden interpretar como “…-”, lo que sería una “V”, como podemos comprobar en la tabla:
Con cada letra que identificábamos nos convecíamos más de que íbamos por el camino correcto. Así pues, llegamos a la solución 🙂
Vamos a hacer un paréntesis en el HackIt para hablar un poco sobre el primer nivel del SolveIt. En el equipo diariolinux solemos centrar nuestros esfuerzos únicamente en el HackIt, pero entre prueba y prueba, curioseamos el SolveIt. Pero este año, la primera prueba nos volvió locos, no entendíamos qué había que hacer.
Pero mira… bastaba con buscar en Google las dos primeras filas de ese cuadrado de letras. Y salía como primer resultado:
Vaya, ese cuadrado de letras nos suena, ¿verdad?
Así que la solución era 243540508935111696.
Ahora que conocemos la solución al level, ¿era difícil? Sinceramente, no. Fallamos en algo básico: siempre, siempre, siempre, consultar con Google cualquier texto que aparezca en la prueba. No lo hicimos y pagamos las consecuencias.