msgbartop
Sé lo que estás pensando, si disparé las seis balas o sólo cinco.
msgbarbottom

25 ene 20 Integración de una estación meteorológica doméstica en el sistema de domótica

Estas Navidades me han regalado una estación meteorológica casera, de las que tienen capacidad para mostrar temperatura y humedad tanto en interior como en exterior, esto último mediante un módulo externo que se deja a la intemperie, y que transmite la información a la estación mediante señal de radio a 433 MHz. Aparte de por el regalo en sí, este tipo de estaciones me venía interesando desde hace bastante tiempo por el hecho de enviar la información utilizando la banda antes mencionada, de la que dispongo unos cuantos receptores. Así que en cuanto abrí el regalo supe que iba a invertir algo de tiempo en intentar integrar el sensor externo en mi sistema de domótica.

Mi nueva estación meteorológica

Mi nueva estación meteorológica

Tras investigar un poco sobre este tipo de estaciones, encontré que la mayoría de ellas hacen uso de protocolos de comunicación bien definidos y relativamente estandarizados, lo que hace que sea razonablemente sencillo encontrar información sobre las mismas, e incluso implementaciones de dichos protocolos para entornos linux o arduino. Dicho lo cual, empecé a hacer algunas pruebas de implementación de un sistema que permitiera recibir la información del emisor externo. Las primeras pruebas las hice con un receptor basado en arduino y un módulo 433 MHz, más la librería rc-switch que tan buenos resultados me había dado en el pasado. No fue este el caso, ya que al intentar capturar paquetes enviados por la estación el programa de captura de paquetes basados en esta librería producía un error de desbordamiento, siendo incapaz de recibir correctamente el datagrama. Hice algunas pruebas en bruto con otras librerías, entre las que se incluían algunas diseñadas específicamente para alguno de los protocolos de envío antes mencionados, con resultados igualmente infructuosos.

NodeMCU con receptor a 433 MHz y módulo externo de la estación

NodeMCU con receptor a 433 MHz y módulo externo de la estación

Ante ello, no me quedó más remedio que cambiar el enfoque. Tocaba acometer el problema desde una perspectiva más basica. Así que me tocó desempolvar un receptor RTL SDR que compré hace algún tiempo para un proyecto similar, e intentar hacer una captura del datagrama a nivel de onda enviada, e intentar decodificar la misma (tirando para ello de programas como Gqrx, audacity, y algo de tiempo. Sin embargo, tuve algo de suerte, y tras seguir investigando un poco más, encontré una referencia a un proyecto, rtl_433, que se dedica a decodificar el tráfico de dispositivos que envían información en esta banda.

Captura de pantalla de rtl_433 capturando tráfico

Captura de pantalla de rtl_433 capturando tráfico

Tras una instalación sencilla en mi equipo con Debian (apt install rtl_433), y tras conectar el receptor RTL SDR al mismo, tuve la suerte de que el programa tuviera perfectamente identificado el tipo de protocolo que mi estación estaba utilizando, en concreto el protocolo “Kedsum Temperature & Humidity Sensor, Pearl NC-7415″. Trasteando un poco con el programa, pude tener algo más de información sobre este protocolo, a saber:

Frame structure:
Byte: 0 1 2 3 4
Nibble: 1 2 3 4 5 6 7 8 9 10
Type: 00 IIIIIIII BBCC++++ ttttTTTT hhhhHHHH FFFFXXXX
- I: unique id. changes on powercycle
- B: Battery state 10 = Ok, 01 = weak, 00 = bad
- C: channel, 00 = ch1, 10=ch3
- + low temp nibble
- t: med temp nibble
- T: high temp nibble
- h: humidity low nibble
- H: humidity high nibble
- F: flags
- X: CRC-4 poly 0×3 init 0×0 xor last 4 bits

_Modulation = OOK_PULSE_PPM,
-Short_width = 2000,
-Long_width = 4000,
-Gap_limit = 4400,
-Reset_limit = 9400,

Bien, ya tenía identificado claramente el protocolo, y aquí puede verse una captura de la señal recibida:

root@asustinker:/etc/systemd/system# /usr/local/bin/rtl_433 -R 57
rtl_433 version 19.08-147-g639ab8a branch master at 202001210044 inputs file rtl_tcp RTL-SDR
Use -h for usage help and see https://triq.org/ for documentation.

Consider using “-M newmodel” to transition to new model keys. This will become the default someday.
A table of changes and discussion is at https://github.com/merbanan/rtl_433/pull/986.

Registered 1 out of 145 device decoding protocols [ 57 ]
Found Rafael Micro R820T tuner
Exact sample rate is: 250000.000414 Hz
[R82XX] PLL not locked!
Sample rate set to 250000 S/s.
Tuner gain set to Auto.
Tuned to 433.920MHz.
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
time : 2020-01-25 15:24:00
model : Kedsum Temperature & Humidity Sensor ID : 226
Channel : 1 Battery : OK Flags2 : 129 Temperature: 60.20 F Humidity : 78 % Integrity : CRC
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

Bien, esto me planteaba dos problemas: el primero es que la información recibida de temperatura estaba expresada en grados Fahrenheit, por lo que necesitaba hacer una conversión a Celsius. Y por otro lado, el poder transmitir esta información a mi plataforma de domótica, preferentemente a través de MQTT. Este segundo problema quedó solucionado mediante la capacidad del programa rtl_433 de encapsular la información en un JSON, que puede ser retransmitido posteriormente. En mi caso, lo hice mediante un servicio linux que lanza el programa rtl_433 con las opciones adecuadas (formato JSON, protocolo 57 -Kedsum-, e incrustando la hora UTC), que mediante un pipe es procesado por el cliente MQTT mosquitto y enviado a mi servidor MQTT, a un topic específico:

“/usr/local/bin/rtl_433 -R 57 -F json -M utc | /usr/bin/mosquitto_pub -l -h servidor_mqtt -t topic”

…donde posteriormente es procesado gracias a Node Red, en el que se hace la conversión a Celsius, se obtiene también la sensación térmica, y se inyecta la información resultante en formato JSON en un topic específico:

var data=JSON.parse(msg.payload);
//Datagram example: {“time” : “2020-01-22 19:27:58″, “model” : “Kedsum Temperature & Humidity Sensor”, “id” : 226, “channel” : 1, “battery” : “WEAK”, “flags” : 66, “temperature_F” : 54.600, “humidity” : 79, “mic” : “CRC”}
temp_value=((data.temperature_F-32)*5/9).toFixed(2);
humidity=data.humidity;

HI = 0.5*(data.temperature_F + 61.0 + ((data.temperature_F-68.0)*1.2) + (humidity*0.094))
HIc = (((HI)-32)*5/9).toFixed(2); // converting to Celsius

var thing = {
temp: temp_value,
humidity: humidity,
heatindex: HIc
};
msg.payload=thing;

return msg;

…y el resultado de todo esto fue un… ¡exito! Pasé a conectar el receptor RTL SDR a mi Asus Tinker Board donde tengo implementado el sistema de domótica, con excelentes resultados. El sistema, emplazado en la segunda planta de casa, es capaz de recibir las señales del receptor externo emplazado en el patio.

Asus Tinker Board con receptor RTL SDR

Asus Tinker Board con receptor RTL SDR

Por otro lado, quedaba la integración en el sistema de domótica Home Assistant. En este caso, se trataba de alto tan simple como crear los nuevos sensores en base a la suscripción al topic MQTT de salida definido en el flujo Node Red. El resultado, como no podía ser menos, fue perfecto:

Información mostrada en Home Assistant de la estación meteorológica

Información mostrada en Home Assistant de la estación meteorológica

Gráfica de la información histórica recibida

Gráfica de la información histórica recibida

Este artículo podría haber quedado aquí, pero no me encontraba completamente satisfecho con el resultado, ya que me daba la impresión de que utilizar el receptor RTL SDR solo para este propósito era matar moscas a cañonazos. Mi idea originaria era usar un ESP8266 junto con un módulo RF de 433 Mhz para recibir estas señales, y decodificarlas en el mismo, para inyectar la información directamente en el servidor MQTT, y no tener que dar tantos saltos (RTL SDR -> JSON -> MQTT -> Node Red -> MQTT). No tuve éxito en encontrar una codificación del protocolo bajo el nombre de Kedsum, pero sí la tuve con Pearl NC-7415. Encontré un hilo en un foro de Arduino en alemán, que hablaba precisamente de ello: Dekodieren Temperatursensor von PEARL NC7427(NC7415) 433MHz. Gracias, Google Translate. :mrgreen:

En este hilo pude encontrar alguien que había decodificado exitosamente el protocolo, y que compartía el código. Lo descargué y lo probé y… ¡funcionaba perfectamente! Solo tuve que hacer una modificación menor para realizar la conversión de Fahrenheit a Celsius, calcular la sensación térmica, e inyectarlo en el topic MQTT (el original no hacía nada de esto, se limitaba a mostrar la información por pantalla). Y de nuevo, éxito:

Información recibida en ESP8266 y RF, enviada a servidor MQTT

Información recibida en ESP8266 y RF, enviada a servidor MQTT

Sin embargo, esta vía tiene un problema: el receptor apenas es capaz de recibir la señal cuando se encuentra a unas pocas decenas de centímetros del emisor externo. Así que en la práctica ahora mismo es inusable. He probado con varios formatos de antena acoplados al módulo (173mm de largo, en hilo recto, en espiral…) con resultados bastante pobres. Tengo encargada en aliexpress una antena específica, pero aún tardará algunas semanas en llegar. Espero poder reportar mejoras una vez la reciba. :D

VN:F [1.9.20_1166]
Rating: 10.0/10 (1 vote cast)

Etiquetas: , , , , , , , , , , , , ,

06 jul 19 Hacking lab sobre Modbus TCP. Elementos configurados

Esta entrada es la parte 2 de 4 de la serie Hacking Lab Modbus TCP

En el artículo anterior se hacía referencia al objeto del hacking lab y se daba una visión general de la arquitectura implementada. En este artículo se va a entrar en un mayor detalle de los elementos que forman parte de dicha arquitectura: HMI, PLC, actuador TCP y plataforma de ataque.

HMI de control de luces LED
El HMI de control simula un sistema SCADA. Está implementado mediante Node-Red, sistema software que permite la programación basada en flujos para desarrollar sistemas para Internet de las Cosas. A fin de poder realizar la implementación del sistema de control industrial, se ha hecho uso de las siguientes librerías:

  • Modbus,que permite implementar un sistema de comunicación basado en Modbus TCP y Modbus Serie.
  • Dashboard, que permite crear cuadros de mandos y aplicaciones web para interactuar con los flujos de control.

El sistema desarrollado consta de dos partes:

  • El cuadro de mandos es una simple botonera que permite encender la iluminación LED rojo, verde y azul mediante interruptores individuales. Estos interruptores, al actuar sobre ellos, envían una señal MODBUS TCP al PLC simulado, para cambiar el estado de la bobina que corresponda a cada color, y muestra el resultado final del mismo en pantalla.
  • Captura de la interfaz de control

    Captura de la interfaz de control

  • La lógica de interacción del HMI con el PLC se ha desarrollado para leer cada 500 ms el estado de las 3 bobinas del PLC, y desplegar en la botonera el estado de las mismas. Si el usuario cambia uno de los interruptores, el sistema envía al PLC mediante MODBUS sobre TCP una orden para escribir un cambio de estado en la bobina correspondiente. El flujo de control corresponde al siguiente diagrama:
  • Flujo de control HMI-PLC

    Flujo de control HMI-PLC

PLC de control de luces
El PLC que actúa como Master MODBUS se ha desarrollado igualmente haciendo uso de Node-Red con la librería MODBUS. En este caso se ha implementado la funcionalidad de Master Modbus, escuchando en el puerto 1502/TCP (frente al habitual 502/TCP por razones de permisos) de la Raspberry Pi que despliega los servicios de Node-Red.

PLC simulado con Raspberry Pi

PLC simulado con Raspberry Pi

El flujo Node-Red definido es el siguiente:

Flujo Modbus TCP del PLC simulado

Flujo Modbus TCP del PLC simulado

Este flujo realiza dos funciones: la primera es levantar el servidor Master MODBUS, que escucha en la IP 192.168.0.39 por el puerto 1502/TCP. La segunda inyecta los valores por defecto en las 3 bobinas (posiciones de memoria 1 a 3) que se han definido para almacenar los valores de la iluminación LED RGB. En este caso, las tres bobinas se inicializan a cero (FALSE lógico).

Actuador TCP
El actuador TCP se ha implementado como un esclavo Modbus que consulta al PLC el estado de las tres bobinas que controlan el estado de los LED RGB. En función de la lectura realizada del valor de dichas bobinas, enciende o apaga la iluminación LED. Al ser tres las bobinas implementadas, la iluminación puede tomar un máximo de 8 valores combinados (considerando “apagado” como uno de los estados posibles).
La implementación del actuador se ha realizado mediante un dispositivo NodeMCU, que permite su programación mediante el IDE Arduino, con capacidades de conectarse a una red WiFi. Se ha hecho uso de la librería Modbus-Arduino para la implementación del cliente.

Actuador desarrollado con NodeMCU

Actuador desarrollado con NodeMCU

Actuador con iluminación en azul

Actuador con iluminación en azul


Actuador con iluminación en rojo

Actuador con iluminación en rojo

Kali Linux
Para simular la intrusión de un atacante externo se ha hecho uso de una Raspberry Pi con la distribución Kali Linux instalada. Kali Linux es una distribución de Linux especialmente pensada para servir de herramienta para realizar tests de intrusión en el ámbito del hacking ético y auditorías de seguridad de sistems de información.

Se ha realizado el siguiente flujo de ataque:

  1. Reconocimiento: Mediante ingeniería social (fuera del laboratorio) se ha determinado la existencia de un sistema de iluminación LED basado en Modbus.
  2. Escaneo: Una vez conseguido un equipo en la red, se ha procedido a un escaneo de la red en busca del dispositivos que escuchen en el puerto Modbus(habitualmente 502/TCP, pero para este caso se ha hecho uso de 1502/TCP) con ZenMap, cliente gráfico para NMAP.
  3. Ganar acceso: Una vez identificado el equipo Master Modbus, se ha realizado un proceso de escucha mediante modbus-cli, una herramienta desarrollada en Ruby disponible para Kali, que permite escanear y escribir sobre sistemas MODBUS. En una primera fase se ha escuchado hasta determinar las bobinas que controlan el sistema de iluminación, y en una segunda fase, se han realizado cambios sobre la misma.
  4. Para el laboratorio no se han realizado el resto de fases del hacking (mantener acceso ni borrar huellas).

En el siguiente artículo se detallarán los resultados obtenidos en el laboratorio.

VN:F [1.9.20_1166]
Rating: 10.0/10 (1 vote cast)

Etiquetas: , , , , , ,

03 jul 19 Hacking lab sobre Modbus TCP. Introducción

Esta entrada es la parte 1 de 4 de la serie Hacking Lab Modbus TCP

Por temas relacionados con un máster de ciberseguridad industrial que estoy cursando he tenido que preparar una serie de ejercicios para el mismo, entre los que se encuentra la realización de un hacking lab. La idea de un hacking lab es preparar un entorno controlado en el que poder hacer ataques a un sistema para aprender posibles vulnerabilidades, técnicas para desvelarlas, y herramientas que se pueden utilizar para ello, a fin de ser capaz en un futuro de proteger un entorno real con las lecciones aprendidas en el entorno de pruebas.

Para la realización de este hacking lab opté por preparar un escenario en el que se pudiera realizar un ataque a un entorno de control industrial que hiciera uso de comunicaciones basadas en Modbus sobre TCP. Modbus es un protocolo de comunicación industrial desarrollado en 1979, y que constituye un estándar de facto en los sistemas de producción industrial. El objetivo general es perturbar el funcionamiento de un sistema de iluminación LED cuyo sistema de control está implementado empleando Modbus sobre TCP. El mismo consta de los siguientes elementos:

  • Una red plana que simula una red de control industrial. En este caso es una red del rango 192.168.0.0/24. Si bien en un caso real sería una red cableada, para este escenario de prueba es una red mixta cableada y WiFi, con un enrutador proporcionando conectividad a los distintos elementos de la misma.
  • Un PLC que actúa como Master Modbus, y que permite controlar, mediante el uso de tres bobinas (coils), el encendido y apagado de un sistema de iluminación LED de colores rojo, verde y azul. Este PLC, al no tener disponible ningún dispositivo real disponible, se simula mediante el aplicativo Node-RED de IBM con una librería Modbus desarrollada al efecto. Este PLC (virtual) tiene la IP 192.168.0.39, y escucha en el puerto 1502 (por razones de privilegios en el dispositivo, no se ha hecho uso del puerto estándar 502/TCP de Modbus).
  • Un actuador físico como Slave Modbus, que en base a las lecturas que realiza de los valores de las bobinas del Master Modbus, enciende y apaga los LEDs del sistema de iluminación. Este actuador físico se ha implementado con un dispositivo ESP8266 programado mediante Arduino IDE y librerías específicas. Las comunicaciones con el Master Modbus se realizan mediante protocolo Modbus sobre TCP. El actuador tiene la IP 192.168.0.34.
  • Un HMI de control de las luces, que permite controlar el encendido y apagado de las mismas mediante una aplicación web tipo SCADA. Este HMI se ha desarrollado mediante el aplicativo Node-RED de IBM y las librerías gráficas para desplegar cuadros de mando, así como una librería MODBUS desarrollada al efecto. EL HMI tiene la IP 192.168.0.31.
  • Un dispositivo atacante, que tiene como objeto descubrir sistemas Modbus en la red desplegada, e interferir los valores normales de operación de los mismos. Este dispositivo es una Raspberry Pi con Kali Linux instalado, teniendo la IP 192.168.0.99.

El siguiente diagrama de red muestra el sistema desarrollado:

Diagrama de la red

Diagrama de la red

En siguientes artículos iré dando mayor detalle de los dispositivos del entorno, así como de los pasos dados en el hacking lab, además de las conclusiones obtenidas de la puesta en marcha del mismo.

VN:F [1.9.20_1166]
Rating: 10.0/10 (1 vote cast)

Etiquetas: , , , , , , , ,