Importar JSON en MySQL usando MySQL Shell

La utilidad MySQL Shell nos permite importar un fichero JSON en una tabla o colección de MySQL.

Primero debemos activar el protocolo mysqlX :

Y ahora ya podemos conectar con el servidor MySQL usando MySQLShell (y el protocolo mysqlX) :

Tengo creada una base de datos llamada addi, vacía, y quiero importar ahí el fichero result.json en una colección de nombre addi_collection.

El comando a ejecutar sería :

El problema que tuve es que mi fichero json no tenía un campo _id único en cada registro (ver post anterior de ikasten.io), así que tuve que crearlo. Esto no sería un problema en MySQL Server > 8.0, pero estoy usando un server viejuno (5.7.19), así que obtuve este error:

Processed 182.22 KB in 80 documents in 0.0340 sec (2.35K documents/s)
Total successfully imported documents 0 (0.00 documents/s)
Document is missing a required field (MySQL Error 5115)

Tras añadir el campo _id a todos los registros, pude importar sin problemas:

Más info sobre JSON import utility en MySQL Shell.

El resultado de la importación se guarda en una colección que recuerda a las colecciones de MongoDB

Buscar y reemplazar con valores incrementales en Vim

Supongamos que tenemos un fichero JSON como el siguiente:

y queremos añadir un campo nuevo al comienzo, con un _id incremental, para que quede así:

En Vim podremos hacerlo definiendo una función:

Una vez definida la función Incr(), podremos invocarla en una orden find&replace con el operador \= que permite evaluar expresiones y hacer la sustitución que buscamos:

Es decir:

:%s/cadena_a_buscar/cadena_sustituta/gc

Cadena a buscar: ^{ (que empiece por {)
Cadena sustituta: =«{\»_id\»:» . Incr() . «,» (es decir, evaluar la expresión «_id\»:» . Incr() . «,», que inicialmente será «_id»:1 )
/gc : Cambios globales (a todo el documento, no sólo la primera aparición) y con confirmación (puedes pulsar la tecla «a» (all) cuando veas que los cambios son correctos tras las primeras sustituciones)

Si quieres más info sobre funciones y el lenguaje VimScript, échale un vistazo a este tutorial.

Desactivar Command+c en VirtualBox para macOS

Un tip rápido que me tenía intrigado desde hace tiempo. Si usas VirtualBox en macOS, seguro que al tener una máquina virtual lanzada has pulsado sin querer Command+c (⌘+c) para copiar texto (la combinación por defecto en macOS) en lugar de Ctrl+C (la combinación por defecto en Linux y Windows). El problema es que en VirtualBox la combinación Command+C escala el tamaño de la pantalla (¡y la hace minúscula!). Para desactivar este molesto comportamiento, basta con entrar en las preferencias de VirtualBox (pulsa ⌘ + ,), pestaña Input, pestaña VirtualMachine, pulsa sobre ScaledMode y elimina el dichoso shortcut.

¡ Adiós ⌘+C !

HackIt, SolveIt and SmashCTF (III) – HTML5 DRM – Conflicto ideológico


DRM y HTML5. EME (Encrypted Media Extensions). Hay que empaparse algo sobre estos temas para resolver el nivel. EME ofrece un API que permite a las aplicaciones web interactuar con sistemas de protección de contenido para poder reproducir audio o video cifrado. El famoso DRM en HTML5, algo que muchos consideran una aberración (la web nació para ser abierta, no para ofrecer contenidos cerrados). Pero… ahí está el API. Y es precisamente lo que hay que intentar resolver. Básicamente el cliente tiene una etiqueta video. Al pulsar el play se visualizan 26 segundos. Pero a partir de ahí, todo está negro. Parece que el video webm está protegido. En el código vemos que en un momento dado se hace una petición de licencia a un servidor license, que nos envía la clave para desproteger el webm.

Pero esa petición sólo se puede hacer si rellenamos los bytes que faltan… esos bytes forman parte de la solución al sudoku que nos han puesto debajo del vídeo. ¿Qué hacer cuando tengamos la clave de desprotección del vídeo? Visualizarlo en el navegador 🙂 ¿Y después? Bueno, eso lo veremos enseguida… Vayamos por partes. Lo primero es solucionar el sudoku. Lo siguiente es automatizar el proceso de meter los números en las casillas del sudoku (hacerlo a mano es un infierno).
Solucionar el sudoku es fácil. Entramos en sudoku-solutions.com, metemos los datos y pulsamos en check…
Vaya, tiene 9 soluciones posibles. No podía ser tan fácil …

Para no perder tiempo tecleando cada una de ellas, podemos automatizar el proceso. Abrimos la consola JavaScript y tecleamos:

Por cierto, en ese código ya va la solución correcta 🙂 La última línea informa al navegador que el sudoku ha cambiado y debe leer sus datos. Bien, todo preparado. Pulsamos play y vemos que pasamos del segundo 26. Es un trailer de «Inception». Hay una serie de fotogramas que muestran pixels distorsionados. Seguramente porque se haya introducido por ahí algún string que no debería estar… Habrá que bajar el webm, descifrarlo y abrirlo más o menos por esa parte, para ver de qué string se trata.

¿Pero cómo obtenemos la clave de descodificación del webm? (el navegador la conoce, pero necesitamos aislarla…) ¿Por cierto, cuántas claves habrá? Vamos allá.

Abrimos main.js y metemos un punto de ruptura en la línea 71

En e tendremos la clave. Ojo, veremos que el breakpoint se ejecuta dos veces, y necesitaremos apuntar ambas claves (una es para cifrar el vídeo y otra para cifrar el audio). Creo recordar que no era «tan sencillo», sino que había que convertir el formato de las claves obtenidas en «e» con una línea como

y a continuación extraer las claves de 16 bytes con un script como el siguiente (una de las claves era w-UHS…):

Momento de descargar el vídeo (cifrado) y descifrar. ¿Cómo desciframos? Bien, sabemos la clave y tenemos el vídeo cifrado. Nos falta saber cómo se cifró. Investigando un poco, nos encontramos con la utilidad webm_crypt de las webm-tools. Tiene una dependencia con libwebm, pero siguiendo las instrucciones de compilación del anterior enlace, lo podremos obtener sin problemas (en Linux, en macOS no iba).

Desciframos con :

Y por fin, podremos abrir el fichero decrypted.webm (por ejemplo, con vlc…)

o con strings (!)

(Nota: -n 10 = dame los strings ASCII de decrypted.webm que puedas visualizar, siempre y cuando esos strings sean de longitud mayor o igual a 10)

Y analizando la salida de strings, veremos la clave para el siguiente nivel 🙂

PD: creo que hay una herramienta que te permite pasar como input un vídeo webm y una marca de tiempo (hh:mm:ss) y te da como salida el contenido del fotograma de esa marca de tiempo. Lo cual te evitaría el uso de strings (o lo facilitaría). Pero eso lo dejo para que la gente de W0pr, navarparty o Barcelona92 nos lo cuenten en los comentarios.

HackIt, SolveIt and SmashCTF (II). カッター注意

Nos pasan una captura .pcap que abrimos con Wireshark. Vemos en los primeros paquetes UDP que el dispositivo 10.10.0.78 se está comunicando con el 10.10.0.70.

Según la MAC, el .78 ha sido fabricado por CASIO (lo que cuadra con la pista del level). Se trata de un tagger (según los strings de los primeros paquetes), y parece que el modelo es un MEP r2 (?). Buscando Casio Tagger MEP en Google, sale una pequeña impresora o etiquetadora. Si buscamos en el Twitter de marcan algo relacionado con las palabras clave:»casio marcan42 twitter»… Bingo!

Es más, el tweet en cuestión apunta a un Gist con un programa en Python que implementa el protocolo de la impresora para poder convertir, enviarle e imprimir imágenes a partir de ficheros.

Leyéndolo mientras tenemos el pcap abierto, vemos que inicialmente se realiza un primer intercambio de mensajes de protocolo (donde se especifica, entre otras cosas la altura y anchura de la imagen)

Hay 368 filas * 16 columnas de bytes. Por tanto 16×8 = 128 bit en cada fila.

Los datos de la imagen en sí comienzan a enviarse a partir del paquete 43 (todos aquellos con un payload de 512 bytes). Ya tenemos todo preparado para extraer los datos que forman la imagen.

Si ejecutamos el script:

Podremos resolver directamente con:

Pero ya que tenemos el código para hacer el encoding de una imagen a 1’s y 0’s, podemos invertir el proceso fácilmente:

Y resolver 🙂

PD: カッター注意 = Cutter Attention ? (algo así como, «cuidado con la cuchilla» – que corta los trozos de papel de la impresora?)