Hacking HardwareUncategorized

Chiquito&Controlauer – Activación remota vía GPRS

Buenas a todos! Aquí vuelvo en estas fechas tan especiales en las que apenas tenemos un rato para dejar a un lado el turrón (cuidado no os pongáis como un ternero) y echarle un vistazo a nuevas ideas y aportaciones. Pero como siempre, Follow the White Rabbit interrumpe su descanso para traeros nuevos conocimientos 🙂

Hoy vamos a aprender a utilizar la red GPRS (General Packet Radio Service) (algo parecido aprendimos utilizando bots de telegram) para enviar órdenes remotas a actuadores mediante mensajes de texto o SMS.

¿Para qué nos va a servir esto? Podemos imaginar múltiples usos, como pueden ser la activación de alarmas o sistemas de domótica, control remoto de sistemas que no pueden estar conectados a red local o WiFi ya sea por su localización o por requerimientos de ocultación.

Podríamos incluso programar varios sistemas o dispositivos embebidos de forma que de forma automática ellos mismos “hablen” entre ellos o envíen datos a un servidor remoto a través de red móvil.

El material que vamos a necesitar para una sencilla prueba de concepto no podría ser más sencillo:

  • Raspberry Pi, cualquier modelo nos valdrá. En mi caso  he reciclado un modelo 1 B+ de los viejetes.
  • Un módulo GPRS SIM900 o uno similar. Se encuentran por alrededor de 20-30 euros y sirven también para Arduino y multitud de otros sistemas para permitir su conectividad móvil. Yo he utilizado un modelo de SIM900A compacto, pero de elegir os recomendaría el SIM900 con un shield que tenga jacks de entrada y salida por si queréis usarlo para proyectos más complejos.
  • Una tarjeta SIM, nos vale cualquiera de una compañía que siga ofreciendo redes GSM (en España todas las principales lo permiten). A modo de simplificación (y dado que algunos módulos, como el SIM900A no lo permiten), desativaremos el PIN. En módulos como el SIM900 sí es posible utilizarlo para desbloquear la tarjeta.
  • Unos pocos cables (5) hembra-hembra para conectar la RPI con el SIM900.
  • Cable mini USB y conector de corriente para éste para alimentar el sistema.
  • Un altavoz con conexión jack (los de cable de toda la vida). Si es con batería mejor para hacer el conjunto más portable.

Pero ¿para qué vamos a necesitar ese altavoz? Muy sencillo. Tenemos el concepto de que mediante una orden enviada mediante SMS y el sistema remoto (que mantendremos lo más agnóstico posible en la PoC para que podáis adaptar el proyecto a vuestras necesidades) realizará una acción. En nuestro caso, la acción será reproducir un sonido que represente un ataque a un sistema remoto. No se me ocurre uno mejor que Chiquito de la Calzada gritando ¡¡al ataqueerr!!

Podéis descargar un sample en MP3 y muchos otros en el siguiente enlace: http://www.tonosfrikis.com/buscar/melodias/m/chiquito

Vamos ahora a echarle un ojo al montaje. Como únicamente hay dos componentes no tiene mucho sentido hacer un esquema detallado, pero estas son las conexiones que debéis hacer entre los pines GPIO de la Raspberry y el módulo SIM900:

  • 5V — 5V, alimentando así el módulo GPRS con la energía de la Raspberry.
  • GND — GND. En mi modelo de SIM900A había dos tierras que conectar.
  • TXD — RXD y RXD — TXD, conectando así cada lado de emisión y recepción de datos de los dispositivos a su inverso.

Para muestra, un diagrama de los pines de la Raspberry Pi (modelos con 26 pines, los de 40 están ampliados pero son compatibles con éste):

Vemos enseguida los puertos de 5V, los GND y los TxD y RxD. Los marcados como DNC servirán también como tierra. Fijaos bien en la orientación, el pin con el cuadradito está también marcado en la Raspberry real 🙂

Para poder comunicarnos desde la Raspberry con el dispositivo GPRS debemos realizar un par de pequeños cambios en la misma.

  • Editaremos el fichero /boot/config.txt (asumimos que utilizamos Raspbian) y nos aseguramos de que la opción enable_uart está puesta a 1. Esto nos permitirá comunicarnos mediante UART, el protocolo que utilizamos con los pines RXD y TXD.
  • Editaremos el fichero /boot/cmdline.txt y en la única línea que compone el fichero borraremos el elemento console=/dev/ttyAMA0 en caso de la Raspberry 1 y 2, y en modelos posteriores console=/dev/ttyS0. Este es el puerto consola a nivel de software que se utiliza para UART, pero de forma predeterminada la Raspberry ofrece su propia consola por ahí, lo cual nos va a imposibilitar comunicarnos de forma fiable.

Vamos a comprobar rápidamente la conectividad con nuestro módulo GPRS. En la línea de comandos de la Raspberry ejecutaremos el comando:

screen /dev/ttyAMA0 115200

O bien sustituyendo ttyAMA0 por ttyS0 en modelos actuales. El valor numérico es la tasa de baudios para la conexión, au nque con otros valores debería funcionar, dado que se ajusta dinámicamente.

Nos presentará una pantalla en negro, pero es que aún no hemos enviado o recibido nada. Lo que debemos hacer es escribir el comando “AT” (no os preocupéis si no se muestra la introducción) y presionar Enter. Si todo ha ido bien, nos mostrará la respuesta “OK”.

Comprobado esto, podríamos utilizar de esta manera comandos AT para manejar el módulo y enviar un SMS de forma manual. Los comandos AT o conjunto de comandos Hayes es un estándar actualmente abierto para configurar módems, en este caso GPRS 🙂 Por si queréis trastear, os dejo una referencia rápida: https://www.sparkfun.com/datasheets/Cellular%20Modules/AT_Commands_Reference_Guide_r0.pdf

Lo que haremos será automatizar el envío de estos comandos para recibir un SMS de forma remota utilizando Python3 y la librería pyserial para comunicarnos mediante con el SIM900 (podéis instalarla con pip3 install pyserial, no confundir con serial que es un módulo diferente).

Además, para la reproducción de audio sin un reproductor en entorno gráfico, instalaremos en la Raspberry el paquete mpg321 (apt install mpg321).

Os dejo aquí el código, con una breve explicación de los comandos AT que se envían. Una breve nota: es necesario terminar los comandos con un retorno de carro o \r  para que se reciban correctamente.

import serial, time, os

ser = serial.Serial("/dev/ttyAMA0",115200,timeout=1) # Abrimos conexion con el SIM900A

while True:
  ser.write(b'AT+CMGF=1\r') # Colocamos el SIM900 en modo texto o SMS
  time.sleep(0.5)
  ser.write(b'AT+CMGL="ALL"\r') # Leemos todos los mensajes recibidos
  time.sleep(1)

  data = []
  msgs = []
  lines = ser.readlines()

  # Por cada linea, cogemos la linea de los datos del mensaje y la linea del contenido
  for line in lines: 
    if line.startswith(b"+CMGL:"): 
      dat = line.decode('utf-8').strip()
      print(dat)
      data.append(dat)
      msg = lines[lines.index(line)+1].decode('utf-8').strip()
      print(msg)
      msgs.append(msg)

  # Si no hay mensajes nuevos, continuar
  if not msgs: 
    print("Nothing new")
    time.sleep(1)
    continue

  # Inspeccionar mensajes encontrados buscando el comando de la orden
  for msg in msgs: 
    if msg == "Ataquer": 
      os.system("mpg321 chiquito_de_la_calzada_al_ataque.mp3 >/dev/null 2>&1") 
      # Borramos el mensaje ya leido de la memoria del SIM900
      msg_no = data[msgs.index(msg)].split()[1].split(",")[0].encode()
      ser.write(b'AT+CMGD=' + msg_no + b'\r') # Borra el mensaje identificado por su numero en lista
      time.sleep(1)

  time.sleep(2)

Ejecutamos ahora el script, que quedará en un bucle comprobando mensajes nuevos hasta que reciba uno con la orden. Os muestro la salida cuando llega uno:

 

Veis, aparte del mensaje de “Nothing new” cuando no hay nada nuevo en la comprobación, dos líneas diferentes. Primero la que empieza por “+CMGL” es la que indica los datos del mensaje, entre ellos el número que identifica el mensaje en memoria, la fecha de recepción y el número desde el que se envía (evidentemente censuradito).

Vamos ahora a ver un pequeño vídeo con el sistema en acción:

¡¡AL ATAQUEEER!! Esto ha sido todo por hoy chicos. Espero que hoy día 28 os lo paséis especialmente bien, pero no seáis demasiado malos 😉 Y si ya no os veo antes, feliz año!!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Los datos introducidos se guardarán en nuestra base de datos como parte del comentario publicado, como se indica en la política de privacidad.