How I made a bruteforcer via infrared

9 minute read


Introducción

Después de tanto tiempo sin aparecer por aquí, hoy vengo con un proyecto bastante interesante y del que he aprendido mucho, se trata de un bruteforcer para desbloquear el control parental de una televisión. Antes de enseñar el script, veamos como funciona el infrarrojo.

Al final del artículo tienes un pequeño glosario donde podrás consultar la terminología que uso.

¿Qúe es el infrarrojo? ¿Cómo funciona?

Si nos fijamos en la mayoría de los mandos a distancia de las televisiones, podremos notar que tienen una pequeña bombilla en la parte superior (no todos)

Esta bombilla es el emisor infrarrojo, la cual emite pulsos de luz con una longitud de onda de entre 700 nm y 1 mm, rango el cual está fuera del espectro visible.

La información se emite apagando y encendiendo el LED miles de veces por segundo, la velocidad a la sucede esto se denomina como frecuencia del portador (del inglés carrier frequency). Establecer esta frecuencia para la transmisión de datos trae consigo la ventaja de poder envíar y recibir datos en entornos “ruidosos” (con interferencias por otra luz del entorno).

La información se almacena en el “portador” (mando a distancia) en formato binario y esta se transmite. La forma más común de transmisión es la que se conoce Pulse-Width Modulation o Modulación del ancho del pulso, esta técnica juega con los periodos de encendido y apagado. Cada fabricante elige que números almacenar y enviar y el significado de cada uno de ellos. Debido a que siempre hay algo de “ruido” en el entorno (Puede ser cualquier cosa, la luz del sol u otras luces brillantes) algunos fabricantes también agregan información adicional en la transmisión para asegurar que lleguen al equipo correctamente, como enviar los números 2 veces

Resumiendo, la transmisión de IR se lleva a cabo mayoritariamente variando los tiempos de encendido y apagado del emisor para representar números binarios siguiendo un patrón establecido.

NEC protocol

Profundicemos un poco más para ver uno de los protocolos que hace uso del PWM, el protocolo NEC.

En este protocolo, las ráfagas de luz infrarroja se transmiten en una frecuencia de 38KHz y cada pulso mide 562.5 µs (Lo que corresponde a 21 ciclos de onda en esa frecuencia) un 1 lógico tarda 2.25ms en trasmitirse y un 0 lógico tarda la mitad, 1.125ms.

En la imagen nos podemos dar cuenta de donde vienen esos tiempos de transmisión. El 1 lógico está compuesto por una ráfaga de 562.5 µs y seguido por espacio de 1.6875ms, resultando en 2.25ms de transmisión en total, y un 0 lógico está compuesto también por una ráfaga de 562.5 µs y seguido por un espacio de la misma longitud, resultando en un tiempo de transmisión total de 1.125ms.

Cuando se pulsa una tecla del mando a distancia, el mensaje que se transmite es el siguiente:

El mensaje consiste en los siguiente:

  • Una ráfaga inicial de 9ms con la que empieza la transmisión
  • Una espacio de 4.5ms
  • Una dirección para el recibidor de 8 bits
  • 8 bits invertidos de la dirección
  • Un comando en 8 bits
  • 8 bits invertidos del comando
  • Una ráfaga de 562.5 µs para indicar el final del mensaje

Nota: En los 4 bytes enviados siempre se envía primero el LSB

Probablemente te preguntes (o no) que pasa si dejamos un botón del mando a distancia presionado. Lo que pasa es que se envía un código de repetición que indica que se va a repetir el mensaje anterior. Este código normalmente se envía 40ms después de la ráfaga de 562.5 µs que indica el final del mensaje.

El código de repetición se ve así:

Este consiste en lo siguiente:

  • Una ráfaga de pulsos de 9ms*
  • Un espacio de 2.25 ms
  • Una ráfaga de 562.5 µs que indica el final del código de repetición

Pronto Hex

Algo también muy importante que debemos ver es el formato Pronto Hex. A continuación podemos ver una emisión infrarroja en este formato:

0000 0070 0003 0002 0006 0002 0004 0002 0004  
0006 0006 0003 0003 000С

Como podemos ver, está dividido por bloques en hexadecimal que llamaremos palabras. El significado de cada una de estas es el siguiente:

  • Offset 0 (0000): ID del formato, mide un bloque y corresponde al formato con el que estaremos trabajando: el formato raw.
  • Offset 1 (0070): Divisor del Carrier frequency, mide un bloque. Para obtener la frecuencia en KHz se utiliza la siguiente formula: 1000000 / (N * 0.241246) donde N es el valor decimal del bloque. En este caso la frecuencia es de 37037 KHz
  • Offset 2 (0003): Número de pares de ráfagas en la primera secuencia. Cada par de ráfagas indica los tiempos de apagado y encendido de la secuencia. Mide un bloque.
  • Offset 3 (0002): Número de pares de ráfagas en la secuencia de repetición. Mide un bloque.
  • Offset 4 (0006 0002 0004 0002
    0004 0006)
    : Secuencia a emitir. Mide 2 * (offset 2), en este caso 6 bloques.
  • Offset 10 (4 + 2*(offset 2)) (0006 0003 0003 000C): Secuencia de repetición. Mide 2 * (offset3), entes caso 4 bloques

Un par de ráfagas , si no ha quedado claro es lo siguiente: Pongamos de ejemplo el par: 0006 0002:

Offset Tamaño Estado del LED Descripción Muestra  
0 1 Parpadeando Cantidad de periodos en los que el LED parpadea acorde al carrier frequency 0006  
1 1 Apagado Cantidad de periodos en los que el LED está apagado 0002  

Pin bruteforcer

Al comenzar a investigar en este proyecto, me dí cuenta de que lo primero que tenía que hacer era encontrar los patrones de emisión en hexadecimal correspondientes a mi televisión. En mi larga búsqueda dí con esta mina de oro:

Se trata de una de las mayores bases de datos de códigos infrarrojos. Contiene código casi para cualquier dispositivo que haga uso de esta tecnología. Busqúe los códigos correspondientes al fabricante de mi TV y estaban, el único inconveniente que tenía era que estos estaban en un formato que no había visto:

¿Device, Subdevice y Function? No sabía lo que era, pero había algo que me preocupaba más, ¿Cómo iba a transmitir esos códigos? Había visto que se podía usar una placa Arduino con emisores infrarrojos, pero nunca había tenido esa placa y no sabía como funcionaba.

Más tarde me dí cuenta de que mi telefono móvil cuenta con un emisor infrarrojo y buscando maneras para poder enviar mis propias secuencias, veo que hay una aplicación que emula una terminal unix llamada Termux que junto con su API permiten lo que buscaba.

Bien, para montar tu entorno para enviar tus secuencias desde tu teléfono (tiene que tener infrarrojo) deberás seguir los siguientes pasos:

1º Paso | Instalar Termux desde Fdroid

Sé que esta app está en la Play Store pero debido a un cambio de políticas que hubo ya no está siendo actualizada en esta plataforma. Podemos descargar la última versión desde aquí

2º Paso | Actualizar repositorios e instalar algunos paquetes

Una vez descargada e instalada la app, entraremos y ejcutaremos los siguientes comandos:

apt update && pkg upgrade -y

pkg install nc termux-api
3º Paso | Instalar Termux-api desde Fdroid

Ahora tendremos que instalar la propia aplicación de Termux-api la cual se puede descargar desde Fdroid

4º Paso | Ejecutar el script que nos interesa

Una vez completados todos los pasos, ya tenemos listo nuestro entorno. El programa que vamos a estar utilizando es termux-infrared-transmit. Si lo ejecutamos desde Termux con el parámetro -h veremos las opciones que se nos requieren:

Por un lado tendríamos que especificar el carrier frequency con el parámetro -f y luego los intervalos de encendido y apagado separados por comas. Estos dos valores los podemos sacar del formato Ponto HEX, pero por ahora lo que tenemos es los valores de device, subdevice y function. ¿Cómo convertimos esos valores a Pronto HEX?

IrScrutinizer

Hay un programa maravilloso llamado IrScrutinizer que automatiza esta tarea y muchísimas más. Ahorra el dolor de cabeza de tener que hacerlo de forma manual. Podremos instalarlo desde su repositorio en GitHub, si manejas un sistema Linux, descarga el AppImage o si manejas un sistema Windows pues descarga el EXE

Una vez instalado, para generar códigos IR en formato Pronto HEX es muy sencillo:

Lo primero es ir a la pestaña Render. Luego tendremos que rellenar los campos con los valores de Device, Subdevice y Function. Probemos a generar el código para el botón de apagado/encendido:

Acción Protocolo Device Subdevice Function
POWER NEC1 4 -1 8

Una vez hecho eso, hacemos clic en el botón Open last export y podremos ver el código Pronto HEX

Para hacer el pin bruteforcer necesitaríamos el código Pronto HEX de todos los números, pero por suerte alguien ya nos ha proporcionado esta lista en un foro

Creación del script

Una vez obtuve todos los códigos Pronto HEX, hice un script con para convertirlos (con las fórmulas que vimos anteriormente) a periodos de encendido y apagado para que Termux pudiese interpretarlos.

#!/usr/bin/python3

power = "0000 006D 0022 0002 0155 00AA 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0040 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0040 0015 0040 0015 0015 0015 0040 0015 0040 0015 0040 0015 0015 0015 0040 0015 05ED 0155 0055 0015 0E47"

def command_generator(keys):
    keys = keys.split(" ")
    freq = round(1000000 / (int(keys[1], 16) * .241246))

    milisecs = []
    for hex_value in keys:
        milisecs.append(round(1000000 * int(hex_value, 16) / freq))

    to_str = ','.join(str(x) for x in milisecs[4:])

    return f"termux-infrared-transmit -f {freq} {to_str};"

print(command_generator(power))

Si ejecutamos este script nos generaría un comando listo para usar, algo tal que así:

termux-infrared-transmit -f 38029 8967,4470, etc

Ejecutamos este script en nuestro PC y envíamos el ouput hacia el teléfono con el comando nc :

python3 command_generator.py | nc 192.168.1.10 4444

Reemplazamos la la IP por la IP local de nuestro teléfono (Es necesario que el equipo host y el teléfono estén conectados a la misma red, la IP local se puede consultar con el comando ifconfig). Antes de ejecutar este comando, tendremos que estar en escucha con Termux con este comando:

nc -lnp 4444 -k | sh

Ese comando lo que hace es quedarse en escucha por el puerto 4444 y que todo lo que le enviemos como data lo ejecute con sh


Bien, el control parental de mi TV me dejaba insertar 3 contraseñas incorrectas, después de eso se cerraba el prompt y había que darle al botón OK para hacerlo aparecer de nuevo. A partir de eso, hice el bruteforcer que teneís en mi GitHub

Aquí teneis un video de la herramienta en acción:

Conclusión

Este ha sido un proyecto en el que he aprendido mucho. En mi opinión, si sabes hacer estas cosas, el pin del control parental no sirve para nada ya que ni siquiera tiene un cooldown para evitar esto. Me ha gustado mucho tanto investigar en este campo como escribir este artículo, es por eso que posiblemente traiga más cosas así por el blog.

Glosario

  • IR: Infrarrojo (Del inglés infrared)
  • Carrier frequency: Frecuencia de una carrier wave o onda portadora
  • Carrier wave: Onda que se modula (modifica) con una señal portadora de información con el fin de transmitirla.
  • PWM: Acrónimo de Pulse-Width Modulation o Modulación del ancho del pulso
  • Medida µs: Microsegundos, 1 milisegundo = 1000 microsegundos
  • LSB: Bit menos significativo (del inglés, Least Significant Bit) posición del bit en un entero binario que da el valor de las unidades.
  • Periodo: Acorde a Wikipedia, el periodo es la duración del tiempo de un ciclo en un evento que se repite
  • raw: Datos sin procesar