- Durante un proceso de ingeniería inversa para integrar unas luces LED Bluetooth LE económicas con Home Assistant, al probar un valor de efecto oculto en una tira de LED direccionables de 10 m, el controlador dejó de funcionar
- Usando Bluetooth HCI snoop de Android y Wireshark/tshark, se capturaron los paquetes BLE que la app escribía en las luces, rastreando los bytes de control en solicitudes de escritura
btatt.opcode.method==0x12 - Los paquetes de la app iDeal LED no parecían simples valores de encendido/apagado, y tras descompilar el APK y revisar un análisis previo, se descifraron con una clave AES fija dentro de
libAES.so - Los paquetes descifrados de encendido/apagado quedaron identificados por una cabecera fija y la diferencia
1/0en el quinto byte, y al repetir funciones de color, brillo y efectos se registraron sus patrones de bytes - Al enviar valores de 8 bits por encima del rango de 5 bits
0x1Fque usaba la app para RGB, se lograron colores más brillantes, pero al enviar el efecto número 12 las luces se apagaron y también desapareció la publicidad Bluetooth
El punto de partida para integrar luces BLE baratas a la automatización del hogar
- Partiendo de la idea de que los dispositivos que se comunican por Bluetooth LE y tienen una app propia pueden integrarse en un sistema de automatización del hogar, se hizo ingeniería inversa a varias tiras LED económicas
- Antes ya se había conectado a Home Assistant una tira LED no direccionable de 5 m con control por Bluetooth LE que costó £2.38, y el código relacionado está publicado en bj_led
- También existe trabajo de ingeniería inversa del controlador LEDnetWF por BLE en lednetwf_ble
- En esta ocasión, el objetivo fue una guirnalda LED direccionable de 10 m que estaba sobre un escritorio y se controlaba con la app “iDeal LED”
- La app tiene muchas funciones y funciona relativamente bien
- Es probable que los LED sean WS2812 o algún producto similar
- Las luces fueron compradas en AliExpress
Captura de los bytes BLE que envía la app
- Para controlar el dispositivo con software propio, primero había que ver la secuencia de bytes que la app enviaba al dispositivo por Bluetooth
- Un protocolo de iluminación típico puede estar compuesto por una cabecera, bytes de comando para acciones como encender/apagar o cambiar el color, y un pie que podría ser un checksum
- En Android, la captura se hizo con esta secuencia
- Activar el modo desarrollador
- Instalar la app de las luces
- Habilitar
Bluetooth HCI snoopen la configuración de desarrollador - Realizar acciones en la app, como encender y apagar las luces
- Copiar el registro a la computadora con
adb pull sdcard/btsnoop_hci.log .
- Al abrir el registro en Wireshark se pueden ver los bytes enviados a las luces
- Un ejemplo de filtro es
bluetooth.dst == ff:ff:ff:ff:ff:ff && btatt.opcode.method==0x12 - La dirección MAC debe cambiarse por la MAC real de las luces
btatt.opcode.method==0x12significa que hubo una operación de escritura desde el dispositivo Android hacia las luces
- Un ejemplo de filtro es
- Con tshark también se pueden extraer directamente los valores de los paquetes desde la terminal
tshark -r <filename> -T fields -e btatt.valueimprime la carga útil escrita en el controlador LED
El protocolo de iDeal LED no se resolvía con simple replay
- Algunas luces muestran patrones casi literales en las acciones de encendido/apagado
- Un ejemplo es la repetición de
69 96 02 01 01y69 96 02 01 00 - El último byte cambia entre
1y0para indicar encendido y apagado
- Un ejemplo es la repetición de
- En esta luz iDeal LED, en cambio, se repetían secuencias de bytes mucho más largas, y aunque se distinguían dos tipos de paquetes para encendido/apagado, los valores parecían ruido
- Si el objetivo fuera solo encender y apagar, podría bastar con un replay reenviando exactamente la secuencia de bytes capturada
- Con
gatttoolse puede conectar a un dispositivo BLE y enviar bytes - El handle al que hay que escribir debe identificarse en Wireshark
- Con
- Para tener más control era necesario entender la estructura del paquete, así que el análisis pasó a estudiar la propia app de Android
Descompilación del APK y búsqueda de la clave AES
- Se descargó el APK y se abrió con jadx para revisar el código de la app
- En el código aparecían referencias a AES, lo que sugería que el protocolo podía estar cifrado
- Sobre los datos cifrados se asumieron las siguientes condiciones
- El texto cifrado de una misma acción no cambiaba cada vez, así que podía existir una clave consistente
- Como debía descifrarse rápido en un MCU de bajo consumo, una clave corta sería ventajosa
- La clave podía no ser única por dispositivo, sino una clave fija
- La app incluía una biblioteca AES compilada llamada
libAES.so, que no podía analizarse solo conjadx - Se encontró un análisis donde otra persona descompiló la biblioteca AES con
ida freey encontró la clave integrada, y esa clave se puso a prueba - Al descifrar con AES en modo ECB de
Crypto.Cipher, los paquetes de encendido/apagado pasaron a tener una forma con sentido- Los valores descifrados aparecieron como
05 54 55 52 4E 01 ...y05 54 55 52 4E 00 ... - Después de una cabecera fija, el quinto byte cambiaba entre
1y0para indicar encendido y apagado - El resto estaba rellenado con ceros
- Los valores descifrados aparecieron como
- A partir de ese punto fue posible descifrar los paquetes que enviaba la app y reproducir el mismo control en código propio
Registro de patrones de bytes por función
- El alcance del protocolo se fue ampliando ejecutando una por una todas las funciones de la app y registrando los bytes transmitidos
- Cada acción se repitió varias veces y, para separar secciones, se intercaló un patrón de apagar/encender las luces
- Se cambiaron los colores varias veces en el orden red, green, blue
- Se cambió el brillo a 100%, 50%, 10%, 50%, 100%
- Entre cada bloque se insertó off/on para facilitar la identificación de límites en el registro capturado
- Con este método se pudo ver qué bytes cambiaban según la acción y hacer coincidir las acciones anotadas con los paquetes capturados
El efecto número 12 que convirtió el controlador en un ladrillo
- Al investigar el cambio de color, se confirmó que la app no enviaba valores mayores que
0x1Fpara red, green y blue0x1Fcorresponde a un rango de 5 bits- Al enviar directamente valores de 8 bits, funcionaron colores más brillantes
- Para comprobar si había efectos adicionales aparte de los 10 usados por la app, se ejecutó un bucle
range(20)para enviar los números de efecto en orden- Del 1 al 10 todo avanzó normalmente
- En 11 se encontró un comportamiento que parecía un modo oculto
- Al pasar a 12, las luces se apagaron
- Después de eso, las luces ya no volvieron a encender
- Dejaron de anunciarse por Bluetooth
- Ya no aceptaban conexión
- No se recuperaban ni manteniendo pulsado el botón al encenderlas
- Tampoco volvieron después de dejarlas desconectadas toda la noche
- Se sospechó que un desbordamiento de búfer pudo haber dañado el firmware, pero la causa no quedó confirmada
- Como los propios LED son LED direccionables estándar, la guirnalda todavía puede reutilizarse conectándola a otro microcontrolador
Resultados restantes y precauciones
- A pesar del fallo, se documentó la mayor parte del protocolo y se creó un proyecto en GitHub que incluye un componente personalizado de Home Assistant
- El componente funciona, pero experimentar del mismo modo puede dañar el controlador de las luces, así que cada quien debe hacerlo bajo su propia responsabilidad
1 comentarios
Comentarios de Hacker News
Más que un “encabezado fijo” de la FTA, parece un byte de longitud (“el comando son 5 bytes”), con el comando
TURN, el argumento 0/1, y el resto rellenado con 0 hasta 16 bytes54 55 52 4Esalta a la vista enseguida como las letras mayúsculasTURNSi sabes que los números empiezan en
0x30, las mayúsculas en0x41y las minúsculas en0x61, es fácil encontrar patrones alfanuméricos en un volcado hexadecimalEste conocimiento sirve para cadenas cortas, pero al ver paquetes o volcados de memoria, lo mejor sigue siendo el formato estándar de hexdump
0x54 55 52 4Eefectivamente esT U R NuintPodría ser un problema de alimentación eléctrica. La familia WS281x puede encenderse con muchísimo brillo, y al juntar varias consume una barbaridad de corriente
Para una tira de 100 LEDs, una fuente de 12V 3A apenas alcanza para encenderla toda en blanco a brillo máximo, y deslumbra muchísimo
Así que yo revisaría primero si se fundió un fusible. También da una pista que el firmware solo use 31 de los 255 niveles máximos de brillo
0x1f. Con suerte, la fuente tiene fusible y solo se quemó esoAunque no se pueda revivir, una cadena LED WS281x estándar se puede conectar a una Raspberry Pi, y también puedes usar mi controlador open source para LEDs direccionables :) https://github.com/mbevand/ledthemfight
Trae efectos integrados, y está hecho de forma muy modular para DIY, así que con dos líneas de Python puedes crear un módulo simple de efectos LED personalizados. Demo aquí: https://youtu.be/qpd2rILsnM4
12V, rojo, verde y azulNo parece direccionable de forma individual, sino una tira RGB analógica donde toda la tira se enciende del mismo color
https://www.aliexpress.com/item/1005005485885067.html
Cualquiera que quiera meterse a modificar iluminación LED debería ver WLED. Tiene muchos efectos integrados, una GUI web, usa un ESP32 o ESP8266 baratísimo como controlador y hasta puede reaccionar al sonido. Ahora mismo tengo WLED corriendo en mis luces navideñas interiores y se ve genial
Es una forma elegante de limitar el consumo eléctrico
Buen post. Me recordó cuando intenté hacer ingeniería inversa a unas luces que tenía y descubrí que estaban cifradas
Una era una amaran 60d y las otras eran unas luces LED a batería SmallRig RM75; quería poder encenderlas y apagarlas todas con un solo script en vez de estar lidiando con dos apps
Pasé bastante tiempo haciendo ingeniería inversa de la app y el protocolo, y parecía que ambas luces usaban el mismo procedimiento de negociación, pero implementado con bibliotecas distintas
Intenté imitar el intercambio de claves Diffie-Hellman que hacen al conectarse, pero al final me rendí. Si mal no recuerdo, después había uno o dos pasos más, y tras enviar la primera clave también mandaban otro número de aspecto aleatorio (¿otra clave?), pero nunca logré descifrar qué querían ahí
Al ver este post, me dan ganas de simplemente probar con una clave hardcodeada y ver si funciona
Si apareciera una integración open source para Elgato Stream Deck o Home Assistant, sería un gran caso de éxito. Para la gente de YouTube que graba videos tipo talking head desde el escritorio, sería muchísimo mejor que controlar la iluminación desde una app en el teléfono
Intenté automatizar unas luces navideñas con conexión BLE y terminé creando residuos electrónicos. Ahora tú también puedes hacerlo
No sé en iPhone, pero en Android, si la dejas en segundo plano, puede capturar la actividad BLE desde la interfaz bonita del teléfono. La uso todos los días
Me recordó a ciertos MCU de teclados que se brickeaban al recibir comandos específicos de iluminación
OpenRGB al final tuvo que desactivar la ejecución automática de ese módulo en ese hardware. A veces incluso el software del fabricante disparaba el mismo bug
Lamentablemente, para entrar al modo de programación dentro del sistema normalmente había que enviar un reporte USB HID, pero los dispositivos afectados ya ni siquiera volvían a enumerarse
Otra cuestión es si realmente era corrupción de firmware, o si el hardware se dañaba por otro comportamiento indefinido
“No es seguro mandar texto plano por el aire”
“Tranquilo, le puse cifrado AES”
Así es como funciona el emparejamiento. La app hace broadcast indiscriminado de paquetes a
255.255.255.255, y el dispositivo objetivo (foco, enchufe, etc.) espera en modo promiscuoEl contenido de los paquetes sí está protegido por WPA2 y demás, pero la longitud del paquete no lo está, así que envía montones de paquetitos diminutos donde la longitud de cada paquete se fija al valor ASCII del siguiente carácter del handshake de configuración. Supongo que lo repiten varias veces
Por eso el emparejamiento tarda 2 minutos y luego siempre se detiene de golpe justo antes de que el contador llegue a 0
Esto era exactamente lo que más me preocupaba cuando hice ingeniería inversa del controlador BLE de mi chimenea el año pasado.
En particular, el comando “Set password” aceptaba entrada de bytes en crudo, pero la app del OEM solo enviaba datos numéricos con longitud limitada.
Por suerte, parecía que si se cortaba la energía por un momento, olvidaba por completo todo lo ocurrido antes.
Así que parece que la mayoría de los controladores BLE de esa misma marca se quedan con la contraseña predeterminada
0000. Si hay un corte de luz, al final vuelven a ese estado. Si de verdad estás aburrido, sería un material bastante bueno para hacer wardriving de BLE.Yo también convertí los resultados de mi ingeniería inversa en una integración para Home Assistant (https://github.com/kaechele/napoleon-efire), y también documenté el sistema y el protocolo (https://bonaparte.readthedocs.io/en/latest/index.html)
Estoy buscando una luz flexible y resistente para montar en el portaequipajes del techo de un auto.
Debe funcionar con batería y servir para exterior / todo clima, y sería ideal poder sujetar fácilmente la caja de baterías a una superficie con cinchos plásticos.
Si es posible, me gustaría que fuera formato “mini”
T5, con RGB y programable para usarla por temporada: rojo/verde en Navidad, morado/naranja en Halloween, etc.Me pregunto si alguien conoce un producto que cumpla con esto. Las primeras tres condiciones se pueden resolver en Walmart o Home Depot, pero me costó encontrar algo que cumpliera con la última.
Al buscar, solo sale un montón de ruido.
[1] https://cdn.christmaslightsetc.com/images/CategoryDetail/788...
Por ejemplo, las tiras LED de 12V con protección IP67 (las que vienen dentro de un tubo de silicón) se consiguen fácilmente [0], y como tienen muchísimos más LEDs que una tira tipo luces navideñas, el efecto probablemente sería mucho más fuerte.
Eso sí, tendrías que comprar y programar un microcontrolador como Arduino, ESP32 o ESP8266, y también resolver por tu cuenta cómo tomar la energía de la batería del auto [1].
También podrías dejar los componentes electrónicos dentro del auto y sacar solo los cables fuera de la cajuela, esperando que el sello existente de la cajuela ya sirva como impermeabilización.
[0] https://www.aliexpress.com/item/1005004289391906.html
[1] https://www.aliexpress.com/item/1005005977505151.html
También es fácil volver a soldar extensiones o unirlas en cadena.
https://www.aliexpress.com/item/4000105913323.html
Por lo que he leído, este tipo de producto o luces parecidas de 5V parecen usarse como un estándar en shows navideños al aire libre.
#projectsy#showcase. Hay muchos proyectos de gente que ha instalado iluminación LED RGB en vehículos.Eso sí, cuidado, porque este tema puede volverse absorbente muy fácil.
Link de invitación: https://discord.gg/eVhhh2Wh
¿Podríamos ver una desarmada de las luces navideñas descompuestas?
Saber qué chip trae dentro podría dar pistas sobre si tiene memoria flash y qué tan fácil sería hacerle un dump.