Descripción

We have detected interferences in our comertial radio band. Our technical team has been able to isolate the interference signal, but they cannot figure out the meaning of the broadcast. You are responsible to find out what is being transmited and report the message to our team.

Write-Up

Se nos da un archivo .wav con la señal en cuestión. Si lo escuchamos, solo se oye ruido. Lo primero que se nos puede ocurrir es abrirlo con algún programa como Audacity para analizar el espectro de la señal y ver la forma de onda. Cuando lo abrimos vemos lo siguiente:

Vemos que es una señal digital con código de línea bipolar-nrz (No Return to Zero) en el que se representan los unos con un voltaje positivo y los ceros con voltaje negativo. Encontramos 2 canales que, en principio, parecen contener la misma información. Sin embargo, si ampliamos un poco:

Encontramos una disparidad de 2 bits (01, 10) a los 29 bits. De hecho, cada 29 bits encontramos la misma (y única) disparidad en el mismo orden (01, 10).

Si tenemos 2 canales transmitiendo una señal digital, lo mas probable es que estemos ante una modulación en cuadratura como QAM o QPSK. A simple vista podemos ver que será QAM-4 o QPSK-4, pero vamos a representar la señal en un diagrama de fase y cuadratura para asegurarnos.

En el eje de abscisas hemos puesto el canal de fase (canal izquierdo de stereo) y en el eje de ordenadas el canal de cuadratura (canal derecho).

Efectivamente, la nube de puntos tiene 4 símbolos. Observamos que la densidad de símbolos recibidos en (0.6, 0.6) y (-0.6, -0.6) es mucho mayor. Los dos símbolos que aparecen menos son los que encontramos cada 29 bits, lo cual tiene sentido, ya que los bits que forman esos símbolos son dispares.

Con esto en mente, podemos pensar que las disparidades son algún método de separación de tramas, alineamiento o sincronismo. En definitiva, nada que aporte información, por lo que realmente solo se están usando 2 símbolos para representar la información (sistema binario).

Si separamos la señal recibida cada par de símbolos dispares obtenemos 29 secuencias de 29 bits cada una. Al tratarse de un sistema binario, asignaremos el valor 1 al símbolo (0.6, 0.6) y 0 al (-0.6, -0.6).

A modo de ejemplo, hemos usado este pequeño script para resolver esta parte:

import math
import wave
import struct

def decisor(Lamp, Ramp):
    Lamp = Lamp[0]
    Ramp = Ramp[0]
    if Lamp>0: l = 1
    elif Lamp<0: l = 0
    if Ramp>0: r = 1
    elif Ramp<0: r = 0
    return(str(l) + str(r))

def formatter(array):
    msj_final = ""
    for i in array:
        if i == "11": msj_final += "1"
        elif i == "00": msj_final += "0"
        elif i == "01": msj_final += "\n"
        else: pass
    return(msj_final)

wav_file = wave.open("RadioSignal_1.wav", "r")
print(wav_file.getparams())
simbolo = []
mensaje = []

for i in range(wav_file.getnframes()):
    frame = wav_file.readframes(1)
    Lamp = struct.unpack('h', frame[:2])
    Ramp = struct.unpack('h', frame[2:])

    if (i % 40 != 0) or i == 0:
        simbolo.append(decisor(Lamp, Ramp))
    else:
        A=B=C=D=0 #A=11, B=10, C=00, D=01
        for j in simbolo:
            if j == "11": A += 1
            elif j == "10": B += 1
            elif j == "00": C += 1
            else: D += 1
        if max(A,B,C,D) == A: mensaje.append("11")
        elif max(A,B,C,D) == B: mensaje.append("10")
        elif max(A,B,C,D) == C: mensaje.append("00")
        else: mensaje.append("01")
        simbolo = []
print(formatter(mensaje))

Obtenemos la siguiente matriz de bits:

Si lo transformamos a ASCII no obtenemos nada coherente. Habrá que buscar otra forma.

Observando un poco mejor las secuencias de bits podemos ver que en las esquinas se repite un patrón de 1 y 0 muy seguidos formando cuadrados concéntricos. Con esta observación y teniendo en mente que son 29 secuencias de 29 bits cada una parece claro que estamos ante un código QR de 29x29.

A partir de aquí solo restaría formar el QR de forma que sea escaneable. En mi caso he hecho un script muy sencillo que transforma los 1 en el caracter bloque de ASCII (█) y los 0 en espacios.

# -*- coding: utf-8 -*-
entrada = open('solucion_bin.txt', 'r')
salida = open('solucion_readable.txt', 'w')

for line in entrada:
    line = line.replace("1", "██")
    line = line.replace("0", "  ")
    salida.write(line)

entrada.close()
salida.close()

De forma que obtenemos lo siguiente:

Y si lo escaneamos, finalmente obtenemos la flag:

hackiit_flag{y0u_ar3_an_a1r_pir4t3}

Leave a comment

Your email address will not be published. Required fields are marked *