Veamos de qué tipo de archivo se trata:
$ 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:
$ echo "1f 8b 08 00 7f f9 96 4a 02 ff 53 50 20 04 b8 00 7d 5c bc 09 23 00 00 00" | xxd -r -p > output.bin
$ file output.bin
output.bin: gzip compressed data, last modified: Thu Aug 27 21:24:15 2009, max compression, truncated
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: