Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
laf — Este proyecto pretende proporcionar una serie de herramientas para crear, procesar, enviar, analizar y descifrar un conjunto de paquetes LoRaWAN con el fin de auditar o realizar pruebas de penetración de la seguridad de una infraestructura LoRaWAN. | Kitploit
Herramientas/GitHubGitHub/ioactive/laf
Sniffing y Análisis de PaquetesSeguridad IoTAnálisis de VulnerabilidadesExplotaciónFuzzingSeguridad InalámbricaCriptografíaPruebas de Penetración
GitHubioactive/laf

laf

Este proyecto pretende proporcionar una serie de herramientas para crear, procesar, enviar, analizar y descifrar un conjunto de paquetes LoRaWAN con el fin de auditar o realizar pruebas de penetración de la seguridad de una infraestructura LoRaWAN.

1873742hace 4 añosRevisado por Kitploit
Ver Repositorio

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

LoRaWAN Auditing Framework - VERSIÓN ALPHA

Las implementaciones de IoT siguen creciendo y una parte de ese crecimiento significativo está compuesta por millones de sensores LPWAN (red de área amplia de baja potencia) desplegados en cientos de ciudades (Smart Cities) alrededor del mundo, también en industrias y hogares. Una de las tecnologías LPWAN más utilizadas es LoRa, para la cual LoRaWAN es el estándar de red (capa MAC). LoRaWAN es un protocolo seguro con cifrado incorporado, pero problemas de implementación y debilidades afectan la seguridad de la mayoría de las implementaciones actuales.

Este proyecto tiene como objetivo proporcionar una serie de herramientas para crear, analizar, enviar, analizar y descifrar un conjunto de paquetes LoRaWAN con el fin de auditar o realizar pruebas de penetración en la seguridad de una infraestructura LoRaWAN.

A continuación, la estructura de este repositorio:

root@kitploit:~
|-- tools 
    |-- UdpSender.py
    |-- UdpProxy.py
    |-- TcpProxy.py
    |-- lorawan
        |-- BruteForcer.py
        |-- MicGenerator.py
        |-- PacketCrafter.py
        |-- PacketParser.py
        |-- SessionKeysGenerator.py 
        |-- Loracrack (https://github.com/matiassequeira/Loracrack/tree/master) 
    |-- utils
        |-- DevAddrChanger.py
        |-- Fuzzer.py    
        |-- FileLogger.py
|-- auditing
    |-- datacollectors
        |-- MqttCollector.py
        |-- UdpForwarderProxy.py
    |-- analyzers
        |-- LafProcessData.py
        |-- bruteForcer
            |-- LafBruteforcer.py
            |-- keys
        |-- dataanalysis
            |-- LafPacketAnalysis.py
        |-- printer
            |-- LafPrinter.py
    |-- db
        |-- __init__.py
        |-- Models.py
        |-- Service.py
|-- lorawanwrapper 
        |-- LorawanWrapper.py
        |-- utils 
            |-- jsonUnmarshaler.go
            |-- lorawanWrapper.go
            |-- micGenerator.go
            |-- sessionKeysGenerator.go
|-- scripts
    |-- gateway_channel_changer
        |-- LoRa-GW-Installer.sh
        |-- Continuous-Channel-Switch.sh
        |-- LoRa-GW-Channel-Setup.sh

Primeros pasos

Ofrecemos diferentes opciones para tener tu LoRaWAN Auditing Framework listo y funcionando:

  1. La primera es para aquellas personas que quieran instalarlo localmente. Recomendamos esta opción si tu objetivo principal es usar las herramientas de pentesting ubicadas en el directorio tools/, para evitar problemas con el mapeo de puertos de Docker.
  2. La otra opción es para aquellos que quieran ejecutarlo en un contenedor Docker, evitando así instalar manualmente cualquier dependencia. Recomendamos esta opción en caso de que quieras usar los analizadores y no tengas mucho tiempo para configurar el entorno manualmente.
  3. Por supuesto, puedes ejecutar LAF localmente y usar la base de datos Postgres desde el contenedor Docker en lugar de sqlite ;). LAF intentará conectarse a Postgres a través de localhost. Consulta las instrucciones a continuación para configurar Docker.

Instalar LAF en tu entorno local

Estas instrucciones te darán una copia del proyecto y sus dependencias en tu máquina local. Los comandos a continuación son para un entorno basado en Debian:

  1. Clona este repositorio: git clone --recurse-submodules https://github.com/IOActive/laf.git

  2. Instala python3:

    1. sudo apt-get update
    2. sudo apt-get install python3.6
  3. Descarga e instala las dependencias de Python:

    1. sudo pip3 install paho-mqtt && sudo pip3 install sqlalchemy && sudo pip3 install psycopg2-binary &&sudo pip3 install python-dateutil
  4. Establece PYTHONPATH y ENVIRONMENT

    1. cd laf && export PYTHONPATH=$(pwd) && export ENVIRONMENT='DEV'
  5. Instala y configura golang:

    1. Descarga golang desde https://golang.org/dl/ según tu sistema operativo.
    2. Muévete a la carpeta donde se descargó el instalador de go: cd ~/Downloads
    3. Descomprime el instalador: sudo tar -C /usr/local -xvzf TU_ARCHIVO_GOLANG
    4. Exporta a PATH: export PATH=$PATH:/usr/local/go/bin
    5. Establece GOPATH: export GOPATH="$HOME/go"
  6. Compila la biblioteca go:

    1. cd laf/lorawanwrapper/utils
    2. go build -o lorawanWrapper.so -buildmode=c-shared jsonUnmarshaler.go lorawanWrapper.go micGenerator.go sessionKeysGenerator.go hashGenerator.go
  7. Dependiendo de la base de datos que desees usar:

    a. PostgreSQL: Sigue las instrucciones 'Instalar LAF usando Docker' hasta el paso 3.

    b. SQLite:

    1. cd laf/auditing/db
    2. Modifica __init__.py con tu editor de texto preferido y comenta las líneas para usar con Postgres (conexión DB y variables de entorno) y descomenta la línea para usar con sqlite.

¡Y eso es todo!

Instalar LAF usando Docker

Este método evita lidiar con la instalación de dependencias e inicia una base de datos PostgreSQL donde las herramientas guardan paquetes y datos. Contenedores:

  • Tools.
  • PostgreSQL.
  • PgAdmin4.

Pasos:

  1. Clona este repositorio: git clone https://github.com/IOActive/laf.git
  2. Ve a cd laf/
  3. Inicia los contenedores: docker-compose up --build
  4. Si deseas usar las herramientas dentro del contenedor docker exec -ti laf_tools_1 /bin/bash
  5. ¡Disfruta!

Conexión a la base de datos pgAdmin

Puedes revisar los datos en la base de datos usando pgAdmin:

Primero, accede a pgAdmin:

  • URL: http://localhost:5001
  • Usuario: pgadmin
  • Contraseña: pgadmin

Luego, debes agregar el servidor:

  • Host: db
  • Puerto: 5432
  • Usuario: postgres
  • Contraseña: postgres

Descripción de herramientas

Aquí se describe el contenido de los directorios y las herramientas/funciones dentro de ellos.

/tools

El propósito principal de las herramientas proporcionadas en este directorio es facilitar la ejecución de una prueba de penetración a una infraestructura LoRaWAN.

UdpSender.py

Esta herramienta está diseñada para enviar paquetes uplink (hacia el servidor de red o gatewayBridge, dependiendo de la infraestructura) o paquetes downlink (hacia el packet-forwarder). Opcionalmente, los paquetes pueden ser sometidos a fuzzing y se puede calcular un MIC válido.

Argumentos opcionales:

root@kitploit:~
-h, --help            muestra este mensaje de ayuda y sale
--lcl-port LCL_PORT   Puerto de origen, ej. --lcl-port=623.
--timeout TIMEOUT     Tiempo en segundos entre cada paquete enviado. Por defecto es
                        1s. Durante este tiempo, el remitente escuchará respuestas.
--repeat              Enviar mensaje/s varias veces
--fuzz-out FUZZ_OUT [FUZZ_OUT ...]
                        Datos de fuzzing enviados al puerto de destino (consulta los modos de fuzzing en
                        utils/fuzzer.py), ej. --fuzz-out 1 2.
--key KEY             Ingresa la clave (en formato hex, un total de 32 caracteres
                        / 16 bytes) para firmar paquetes (calcular y agregar un nuevo
                        MIC). Ten en cuenta que para JoinRequests debe ser la
                        AppKey, y NwkSKey para paquetes de datos. Esto no puede
                        ser validado de antemano por este programa. ej.
                        00112233445566778899AABBCCDDEEFF
-a DEVADDR, --devaddr DEVADDR
                        Dirección de dispositivo a suplantar, en formato hex (8 caracteres
                        en total), ej. AABB0011.
--fcnt FCNT           El contador de trama a establecer en el paquete de datos dado.
                        Esto no funcionaría en un JoinRequest/JoinAccept ya que
                        estos paquetes no tienen un fCnt

Argumentos requeridos:

root@kitploit:~
--dst-ip DST_IP       IP de destino, ej. --dst-ip 192.168.3.101.
--dst-port DST_PORT   Puerto de destino, ej. --dst-port 623.
--data DATA           Paquete UDP. También se pueden agregar más paquetes en
                        el arreglo "data" al final de este script. El paquete
                        debe ser una cadena de bytes (deberás escapar las comillas
                        dobles). ***EJEMPLO*** con el formato packet_forwarder:
                        --data "b'\x02\xe67\x00\xb8\'\xeb\xff\xfez\x80
                        \xdb{\"rxpk\":[{\"tmst\":2749728315,\"chan\":0,\"rfch\
                        ":0,\"freq\":902.300000,\"stat\":1,\"modu\":\"LORA\",\
                        "datr\":\"SF7BW125\",\"codr\":\"4/5\",\"lsnr\":9.5,\"r
                        ssi\":-76,\"size\":23,\"data\":\"AMQAAAAAhQAAAgAAAAAAA
                        ACH9PRMJi4=\"}]}'" ***EJEMPLO*** usando el formato gatevice
                        [GV] en modo inmediato, en BW125 y frecuencia 902.3 es "b'{\"tx_mode\": 0, \"freq\": 902.3,
                        \"rfch\": 0, \"modu\": 16, \"datarate\": 16,
                        \"bandwidth\":3, \"codr\": 1, \"ipol\":false,
                        \"size\": 24, \"data\":
                        \"QOOL8AGA6AMCnudJqz3syCkeooCvqbSn\", \"class\": 2}'"

Ejemplo:

Para enviar un solo paquete cada 2 segundos a (localhost, 10001) desde el puerto 10000, aplicando fuzzing aleatorio al MIC y al FCounter:

root@kitploit:~
python3 UdpSender.py --lcl-port 10000 --dst-ip 127.0.0.1 --dst-port 10001 --timeout 2 --fuzz-out 4 5 --data "b'\x02\xe67\x00\xb8\'\xeb\xff\xfez\x80\xdb{\"rxpk\":[{\"tmst\":2749728315,\"chan\":0,\"rfch\":0,\"freq\":902.300000,\"stat\":1\"modu\":\"LORA\",\"datr\":\"SF7BW125\",\"codr\":\"4/5\",\"lsnr\":9.5,\"rssi\":-76,\"size\":23,\"data\":\"AMQAAAAAhQAAAgAAAAAAAACH9PRMJi4=\"}]}'"

UdpProxy.py

Este proxy UDP está diseñado principalmente para colocarse entre una serie de gateways (packet_forwarders) y un servidor de red o gateway bridge, dependiendo de la infraestructura que se esté evaluando. También ofrece la posibilidad de aplicar fuzzing a los datos en la dirección deseada (uplink o downlink)

Argumentos opcionales:

root@kitploit:~
-h, --help            muestra este mensaje de ayuda y sale
--collector-port COLLECTOR_PORT
                        Puerto del recolector de datos de packet forwarder, ej. --collector-
                        port 1701. Consulta
                        auditing/datacollectors/PacketForwarderCollector.py
--collector-ip COLLECTOR_IP
                        IP del recolector de datos de packet forwarder. Por defecto es
                        localhost. ej. --collector-ip 192.168.1.1. Consulta
                        auditing/datacollectors/PacketForwarderCollector.py
--fuzz-in FUZZ_IN [FUZZ_IN ...]
                        Datos de fuzzing enviados al puerto de destino en los modos dados
                        (consulta los modos de fuzzing en utils/fuzzer.py), ej. --fuzz-in 1 2
                        ...
--fuzz-out FUZZ_OUT [FUZZ_OUT ...]
                        Datos de fuzzing enviados al puerto de (origen) en los modos dados
                        (consulta los modos de fuzzing en utils/fuzzer.py), ej. --fuzz-out
                        1 2 ...
-k KEY, --key KEY     Ingresa una AppSKey de dispositivo (en formato hex, un total de 32
                        caracteres / 16 bytes) para descifrar su FRMPayload e
                        imprimirlo en texto plano. También puedes ingresar la AppKey
                        si deseas descifrar un Join Accept dado. ej.
                        00112233445566778899AABBCCDDEEFF
-p PATH, --path PATH  Ruta del archivo donde guardar los datos. Si no se proporciona,
                        los datos no se guardarán.
--no-log              No imprimir paquetes UDP en la consola
--no-parse            No analizar PHYPayload. Si se selecciona esta opción,
                        las bibliotecas Golang de /lorawanwrapper/ no se
                        importarán (no se requiere compilar las bibliotecas golang)
                    

Argumentos requeridos:

root@kitploit:~
--port PORT           Puerto local para escuchar, ej. --port 623.
--dst-ip DST_IP       IP del host de destino, ej. --dst-ip 192.168.3.101.
--dst-port DST_PORT   Puerto del host de destino, ej. --dst-port 623.

Ejemplo:

Para enviar paquetes recibidos en el puerto 1234 a (localhost, 1235) y viceversa. Los paquetes recibidos en el puerto serán sometidos a fuzzing (se cambiará el devNonce aleatoriamente) y reenviados a (localhost, 1235).

root@kitploit:~
python3 UdpProxy.py --port 1234 --dst-ip 127.0.0.1 --dst-port 1235 --fuzz-in 9

TcpProxy.py

Este proxy TCP está diseñado principalmente para colocarse entre el servidor de red y un broker MQTT. También ofrece la posibilidad de aplicar fuzzing a los datos.

Argumentos opcionales:

root@kitploit:~
-h, --help            muestra este mensaje de ayuda y sale
--fuzz-in FUZZ_IN [FUZZ_IN ...]
                    Datos de fuzzing enviados al puerto de destino en los modos dados
                    (consulta los modos de fuzzing en utils/fuzzer.py)

Argumentos requeridos:

root@kitploit:~
--lcl-port LCL_PORT   Puerto local para escuchar, ej. --lcl-port=623.
--dst-ip DST_IP       IP del host de destino, ej. --dst-ip=192.168.3.101.
--dst-port DST_PORT   Puerto del host de destino, ej. --dst-port=623.

Ejemplo:

Enviar y recibir datos desde (localhost, 1884) y (localhost, 1883)

root@kitploit:~
    python3 TcpProxy.py --lcl-port 1884 --dst-ip 127.0.0.1 --dst-port 1883

tools/lorawan

Este directorio contiene una serie de scripts para analizar, crear, forzar por fuerza bruta, etc. paquetes LoRaWAN.

lorawan/BruteForcer.py

Este script recibe un JoinAccept o JoinRequest en Base64 e intenta descifrar su AppKey con un conjunto de posibles claves que pueden ser proporcionadas en un archivo o generadas sobre la marcha.

Argumentos opcionales:

root@kitploit:~
-h, --help            muestra este mensaje de ayuda y sale
-k KEYS, --keys KEYS  Archivo que contiene una lista de claves, separadas por \n. Por defecto
                        usará /auditing/analyzers/bruteForcer/keys.txt
--dont-generate       Selecciona esta opción si no deseas generar claves
                        sobre la marcha con las siguientes combinaciones: 1- Combinar
                        el primer byte y los últimos quince bytes. ej.
                        AABBBBBBBBBBBBBBBBBBBBBBBBBBBBBB 2- Combinar posiciones de bytes
                        pares e impares por igual. ej.
                        AABBAABBAABBAABBAABBAABBAABBAABB 3- Los primeros 14 bytes
                        en 00 y combinar los últimos 2. ej.
                        0000000000000000000000000000BA01

Argumentos requeridos:

root@kitploit:~
-a ACCEPT, --accept ACCEPT
                Join Accept en formato Base64 para ser forzado por fuerza bruta. ej. -a
                IHvAP4MXo5Qo6tdV+Yfk08o=
-r REQUEST, --request REQUEST
                Join Request en formato Base64 para ser forzado por fuerza bruta. ej.
                -r AMQAAAAAhQAAAgAAAAAAAADcYldcgbc=

Ejemplo:

Descifrar un JoinRequest con un conjunto de claves de my-keys.txt y también generar aproximadamente 200000 más dinámicamente.

root@kitploit:~
python3 BruteForcer.py -a IHvAP4MXo5Qo6tdV+Yfk08o= -r AMQAAAAAhQAAAgAAAAAAAADcYldcgbc= -k ./my-keys.txt
lorawan/MicGenerator.py

Este script recibe un paquete PHYPayload en Base64 y una clave que puede ser la NwkSKey o la AppKey dependiendo del tipo de paquete, y genera el nuevo MIC.

Argumentos opcionales:

root@kitploit:~
-h, --help            muestra este mensaje de ayuda y sale
--jakey JAKEY         [SOLO JoinAccept]. Ingresa la clave utilizada para cifrar el
                        JoinAccept previamente (en formato hex, un total de 32
                        caracteres / 16 bytes). Esto no puede ser validado de antemano
                        por este programa. ej.
                        00112233445566778899AABBCCDDEEFF. Una clave válida de ejemplo
                        para el JoinAccept "IB1scNmwJRA32RfMbvwe3oI=" es
                        "f5a3b185dfe452c8edca3499abcd0341"

Argumentos requeridos:

root@kitploit:~
-d DATA, --data DATA  Datos en Base64 a firmar. ej. -d
                        AE0jb3GsOdJVAwD1HInrJ7i3yXAFxKU=
-k KEY, --key KEY     Ingresa la nueva clave (en formato hex, un total de 32
                        caracteres / 16 bytes) para firmar paquetes (calcular y
                        agregar un nuevo MIC). Ten en cuenta que para
                        JoinRequest/JoinAccept debe ser la AppKey, y la NwkSKey para
                        paquetes de datos. Esto no puede ser validado de antemano
                        por este programa. ej. 00112233445566778899AABBCCDDEEFF

Ejemplo:

Firmar el PHYPayload dado con la AppKey 00112233445566778899AABBCCDDEEFF.

root@kitploit:~
python3 MicGenerator.py -d AE0jb3GsOdJVAwD1HInrJ7i3yXAFxKU= -k 00112233445566778899AABBCCDDEEFF
lorawan/PacketCrafter.py

Este script recibe un paquete JSON de LoRaWAN y lo transforma a Base64. Hace lo inverso que packetParser.py, por lo que la salida de ese script se puede usar aquí y viceversa.

Argumentos opcionales:

root@kitploit:~
-h, --help            muestra este mensaje de ayuda y sale
-k KEY, --key KEY     Ingresa una AppSKey o AppKey de dispositivo (en formato hex, un total de
                        32 caracteres / 16 bytes) para cifrar el FRMPayload o un Join Accept. ej.
                        F5A3B185DFE452C8EDCA3499ABCD0341
--nwkskey NWKSKEY     Ingresa la clave de sesión de red si deseas
                    generar un paquete de datos con un MIC válido.

Argumentos requeridos:

root@kitploit:~
-j JSON, --json JSON  Objeto JSON a analizar. ej. -j '{"mhdr":
                        {"mType":"JoinRequest","major":"LoRaWANR1"},"macPayloa
                        d":{"joinEUI":"55d239ac716f234d","devEUI":"b827eb891cf
                        50003","devNonce":51639},"mic":"7005c4a5"}'

Ejemplo:

Obtener un PHYPayload de JoinRequest en Base64 dado el JSON con los valores pasados en él.

root@kitploit:~
python3 PacketCrafter.py -j '{"mhdr":{"mType":"JoinRequest","major":"LoRaWANR1"},"macPayload":{"joinEUI":"55d239ac716f234d","devEUI":"b827eb891cf50003","devNonce":51639},"mic":"7005c4a5"}'
                      
lorawan/PacketParser.py

Este script analiza e imprime un solo dato PHYPayload de LoRaWAN en Base64. Hace lo inverso que packetCrafter.py, por lo que la salida de ese script se puede usar aquí y viceversa.

Argumentos opcionales:

root@kitploit:~
-h, --help            muestra este mensaje de ayuda y sale
-k KEY, --key KEY     Ingresa una AppKey o AppSKey de dispositivo según el
                        paquete a descifrar (join accept o paquete de datos).
                        Debe estar en formato hex, un total de 32 caracteres / 16
                        bytes. ej. 00112233445566778899AABBCCDDEEFF

Argumentos requeridos:

root@kitploit:~
-d DATA, --data DATA  Datos en Base64 a analizar. ej. -d
                    AE0jb3GsOdJVAwD1HInrJ7i3yXAFxKU=

Ejemplo:

Obtener el JoinRequest en formato JSON del ejemplo anterior.

root@kitploit:~
python3 PacketParser.py -d AE0jb3GsOdJVAwD1HInrJ7i3yXAFxKU=
lorawan/SessionKeysGenerator.py

Este script recibe un JoinAccept y un JoinRequest en Base64, y una AppKey para generar las claves de sesión. Un ejemplo de uso:

Argumentos opcionales:

root@kitploit:~
-h, --help            muestra este mensaje de ayuda y sale

Argumentos requeridos:

root@kitploit:~
-a JACCEPT, --jaccept JACCEPT
                    Payload JoinAccept en base64
-r JREQUEST, --jrequest JREQUEST
                    Payload JoinRequest en base64
-k KEY, --key KEY     Ingresa una AppKey de dispositivo (en formato hex, un total de 32
                    caracteres / 16 bytes). ej.
                    00112233445566778899AABBCCDDEEFF

Ejemplo:

Obtener la AppSKey y NwkSKey con los siguientes datos de join.

root@kitploit:~
python3 SessionKeysGenerator.py -r AE0jb3GsOdJVAwD1HInrJ7i3yXAFxKU= -a IB1scNmwJRA32RfMbvwe3oI= -k f5a3b185dfe452c8edca3499abcd0341
lorawan/utils/*

Estas son funciones auxiliares utilizadas por UdpSender.py y UdpProxy.py. En Fuzzer.py puedes ver los modos de fuzzing implementados.

/auditing

El propósito general de este directorio es recolectar paquetes LoRaWAN y analizar diferentes aspectos del tráfico, así como probar un conjunto de claves para intentar forzar por fuerza bruta la AppKey.

/auditing/datacollectors

Este directorio contiene un conjunto de scripts que reciben paquetes LoRaWAN de diferentes fuentes (por ejemplo, gateway packet_forwarder, The Things Network, etc.) y los guardan en archivos, con un formato estándar. Estos archivos deben ser recuperados posteriormente por el script /auditing/analyzers/LafProcessData.py para ejecutar diferentes sub-herramientas.

datacollectors/GenericMqttCollector.py

Este script se conecta al broker mqqt, recupera todos los topics y guarda los mensajes en un archivo en el campo especificado. El nombre del archivo se compone de la fecha en que inició este script.

Argumentos opcionales:-h, --help muestra este mensaje de ayuda y sale --collector-id COLLECTOR_ID El ID del recolector de datos. Este ID se asociará a los paquetes guardados en la BD. ej. --id 1 --organization-id ORGANIZATION_ID El ID del recolector de datos. Este ID se asociará a los paquetes guardados en la BD. ej. --id 1 --topics TOPICS [TOPICS ...] Lista los temas a los que deseas suscribirte separados por espacios. Si no se proporciona ninguno, el valor predeterminado será "#".

Argumentos requeridos:

root@kitploit:~
--ip IP               Dirección IP del broker MQTT, ej. --ip 192.168.3.101.
--port PORT           Puerto del broker MQTT, ej. --port 623.

Ejemplo:

Conectarse al broker MQTT con IP 200.200.200.200 en el puerto predeterminado (1883).

root@kitploit:~
python3 GenericMqttCollector.py --ip 200.200.200.200 --port 1883
datacollectors/LoraServerIOCollector.py

Este script se conecta a un broker mqtt de loraserver.io y guarda los mensajes en la BD. Debes especificar un collectorID único y puedes especificar los temas a los que deseas suscribirte.

Argumentos opcionales:

root@kitploit:~
-h, --help            muestra este mensaje de ayuda y sale
--port PORT           Puerto del broker MQTT, ej. --port 623. Predeterminado 1883.
--collector-id COLLECTOR_ID
                        El ID del recolector de datos. Este ID se
                        asociará a los paquetes guardados en la BD. ej. --id 1
--organization-id ORGANIZATION_ID
                        El ID del recolector de datos. Este ID se
                        asociará a los paquetes guardados en la BD. ej. --id 1
--topics TOPICS [TOPICS ...]
                        Lista los temas a los que deseas suscribirte separados por
                        espacios. Si no se proporciona ninguno, el valor predeterminado será "#".

Argumentos requeridos:

root@kitploit:~
--ip IP               Dirección IP del broker MQTT, ej. --ip 192.168.3.101.
datacollectors/PacketForwarderCollector.py

Este script recibe paquetes UDP del proxy UDP en el formato packet_forwarder de la puerta de enlace y los persiste.

Argumentos opcionales:

root@kitploit:~
-h, --help            muestra este mensaje de ayuda y sale
--collector-id COLLECTOR_ID
                        El ID del recolector de datos. Este ID se
                        asociará a los paquetes guardados en la BD. ej. --id 1
--organization-id ORGANIZATION_ID
                        El ID del recolector de datos. Este ID se
                        asociará a los paquetes guardados en la BD. ej. --id 1

Argumentos requeridos:

root@kitploit:~
-n NAME, --name NAME  Identificador de cadena único del recolector de datos. ej.
                    --name semtech_collector
-p PORT, --port PORT  Puerto donde escuchar paquetes UDP. --port 1702.

Ejemplo:

Grabar datos entre una puerta de enlace que envía al puerto local 1700 y un servidor de red xserver que escucha en (localhost, 1701). Guardar los datos en el directorio ./.

root@kitploit:~
    python3 PacketForwarderCollector.py --name semtech_collector --port 1700

analyzers/LafProcessData.py

Este script lee desde un archivo o archivos o stdin y ejecuta diferentes subherramientas. Dependiendo de la opción seleccionada, puedes ejecutar un análisis del tráfico LoRaWAN, intentar forzar por fuerza bruta la AppKey, o analizar todos los paquetes recibidos. Estas opciones se pueden combinar.

Argumentos opcionales:

root@kitploit:~
Este script recupera paquetes de la BD y ejecuta diferentes subherramientas.
Luego, cada subherramienta guardará los datos de salida en la BD. Consulta cada opción para
más información.

argumentos opcionales:
  -h, --help            muestra este mensaje de ayuda y sale
  -a, --analyze         Recopila y analiza diferentes aspectos del tráfico. Si
			el forzador por fuerza bruta (-b) está activado, los resultados se
			correlacionarán
  -b, --bforce          Intenta forzar por fuerza bruta las AppKeys con JoinRequests y
			JoinAccepts payloads
  -k KEYS, --keys KEYS  [Forzador por fuerza bruta] Ruta del archivo de claves. Si no se proporciona,
			se usará "bruteForcer/keys.txt"
  --no-gen              [Forzador por fuerza bruta] No generar claves, solo intentar claves desde
			archivos
  -p, --parse           Analizar el PHYPayload en información legible
  --from-id FROM_ID     ID del paquete desde donde comenzar a procesar.
  --to-id TO_ID         Último ID de paquete a procesar.

Ejemplo:

Procesar paquetes en la BD comenzando desde el ID de paquete 1000, ejecutar un análisis de tráfico e intentar descifrar AppKeys proporcionadas en my-keys.txt, pero no generar más claves dinámicamente.

root@kitploit:~
    python3 LafProcessData.py -a -b -k my-keys.txt --no-gen --from-id 1000

analyzers/bruteforcer, analyzers/dataanalysis, analyzers/parser and analyzers/utils

Estos scripts proporcionan la funcionalidad orquestada por LafProcessData.py. A continuación, las alertas que son implementadas por LafPacketAnalysis.py y LafBruteForcer.py:

IDTítuloAnalizadorNivel de riesgoDescripciónAcción recomendada
LAF-001DevNonce repetidoLafPacketAnalysis.pyBajoLos DevNonces para cada dispositivo deberían ser suficientemente aleatorios para no colisionar. Si el mismo DevNonce se repite en muchos mensajes, se puede inferir que un dispositivo está bajo un ataque de repetición. Esto es, un atacante que capturó un JoinRequest y está intentando enviarlo nuevamente a la puerta de enlace.Verificar cómo se generan los DevNonces: la función que los genera debe implementarse utilizando una biblioteca aleatoria. Además, debes asegurarte de que el servidor verifique los DevNonces históricos (deberían persistirse en la BD) para no aceptar un JoinRequest antiguo válido enviado previamente por el dispositivo y así generar una nueva sesión.
LAF-002DevEUIs compartiendo el mismo DevAddrLafPacketAnalysis.pyInformaciónDos dispositivos diferentes podrían haber recibido la misma DevAddr. Esto no es una amenaza de seguridad.Si el dispositivo está activado por aire (OTAA): Verificar la lógica utilizada para asignar DevAddrs y asegurarse de que el servidor no asigne la misma DevAddr a diferentes dispositivos. Si el dispositivo está activado por personalización (ABP): Verificar la DevAddr configurada en el firmware de un dispositivo es única en la red LoRaWAN.
LAF-003Repetición de JoinPor hacerMedioSe detectó un paquete de solicitud de Join duplicado, lo que puede implicar que el servidor LoRaWAN está bajo un ataque de repetición. Esto es, un atacante que pudo haber capturado un paquete de solicitud de Join anterior y lo está enviando nuevamente al servidor LoRaWAN para intentar generar una nueva sesión.Verificar cómo se generan los DevNonces: la función que los genera debe implementarse utilizando una biblioteca aleatoria. Además, debes asegurarte de que el servidor verifique los DevNonces históricos (deberían persistirse en la BD) para no aceptar un JoinRequest antiguo válido enviado previamente por el dispositivo y así generar una nueva sesión.
LAF-004Repetición de paquetes de datos de enlace ascendentePor hacerMedioSe detectó un paquete de enlace ascendente duplicado, lo que puede implicar que el servidor LoRaWAN está bajo un ataque de repetición. Esto es, un atacante que pudo haber capturado un paquete de enlace ascendente (enviado por el dispositivo) y lo está enviando nuevamente al servidor LoRaWAN.En dispositivos activados por aire (OTAA): Asegurarse de que las claves de sesión se regeneren después de cada reinicio del dispositivo o desbordamiento del contador para evitar cualquier efecto de este ataque. Con dispositivos activados por personalización (ABP) de LoRaWAN v1.0.*, no se puede hacer nada para prevenir un ataque de repetición excepto cambiar el dispositivo a OTAA.

/lorawanwrapper

Este directorio proporciona un conjunto de envoltorios para la biblioteca https://github.com/brocaar/lorawan/, que está escrita en Golang. Estas funciones son implementadas por las herramientas.

/scripts

Aquí encontrarás una serie de scripts destinados a automatizar diferentes tareas. Asegúrate de darles permiso de ejecución si es necesario (chmod +x tu_script para Linux/MacOS).

/scripts/lorawan_gateway_scripts

Configura fácilmente tu puerta de enlace y cambia sus canales con fines de sniffing. Para más información sobre cómo usarlos, puedes ver el readme en este directorio.

gateway_channel_changer/LoRa-GW-Installer.sh

Este script se utiliza para instalar todos los paquetes de software necesarios en una Raspberry PI para construir una puerta de enlace LoRaWAN junto con un Concentrador LoRa conectado (iC980-SPI, RHF0M301-SPI, RAK831-SPI o cualquier otro mediante configuración manual).

gateway_channel_changer/Continuous-Channel-Switch.sh y gateway_channel_changer/LoRa-GW-Channel-Setup.sh

Dado que no es posible saber en qué frecuencias operan los dispositivos LoRa, hemos creado un script que puede cambiar los canales de las puertas de enlace de las bandas de frecuencia US915 y EU868 con fines de sniffing. Aunque existen puertas de enlace profesionales y costosas que admiten 32 o 64 canales, la mayoría de las puertas de enlace admiten hasta 8 canales. Este script está diseñado para ejecutarse en este tipo de puertas de enlace.

Al menos en la banda de frecuencia US915, los primeros 8 canales son los más utilizados. Pero hay implementaciones conocidas que utilizan otro grupo de canales, como por ejemplo The Things Networks, que utiliza el segundo grupo (8-15) de canales para la comunicación de enlace ascendente.

Actualmente no admitimos otras bandas de frecuencia, pero con algunos cambios en estos scripts podrías hacerlo por tu cuenta :).

Video de demostraciónSubimos un video de este framework en acción (el mismo escenario presentado en BlackHat 2019): https://youtu.be/Mm6A2RVNoCs. Los pasos detallados de la demo están en la descripción del video de YouTube.

Autores

  • Matias Sequeira - matiassequeira
  • Esteban Martínez Fayó - emfayo

Colaboradores

  • Sebastian Scheibe - Contribuyó con scripts/lorawan_gateway_scripts - sebascheibe

Contribuciones

TODO

Agradecimientos

  • Cliente MQTT para Python: https://github.com/iwanbk/nyamuk/
  • Librería LoRaWAN en Golang: https://github.com/brocaar/lorawan/
  • Funciones para manejar JSON en Golang https://github.com/tidwall/sjson y https://github.com/tidwall/gjson
  • La base de nuestro tcpProxy: https://gist.github.com/voorloopnul/415cb75a3e4f766dc590
  • Loracrack: bifurcado y modificado del repositorio original https://github.com/applied-risk/Loracrack

Licencia

Este proyecto está licenciado bajo la licencia BSD-3-Clause.

Descargar herramienta
LAF-005Repetición de paquetes de datos de enlace descendentePor hacerAltoSe detectó un paquete de enlace descendente duplicado. El servidor está respondiendo a un ataque de repetición o está generando tráfico atípico hacia los dispositivos.Verificar los registros del servidor y comprobar que las acciones recomendadas anteriores están implementadas.
LAF-006Posible dispositivo ABP (reinicio de contador y sin Join)LafPacketAnalysis.pyAltoSi el contador se reinició (volvió a 0), la DevAddr se mantiene igual y no se detectó ningún proceso Join previo, puede implicar que el dispositivo está activado por personalización (ABP). No se recomienda la implementación de dispositivos ABP porque no se realiza ningún proceso de Join, lo que significa que las claves de sesión se mantienen igual para siempre. Un dispositivo que no cambia sus claves de sesión es propenso a diferentes ataques como escucha o repetición.Todos los dispositivos activados por personalización (ABP) deben reemplazarse por dispositivos activados por aire (OTAA) si es posible. No se recomienda la implementación de dispositivos ABP.
LAF-007Contador recibido menor de lo esperado (distinto de 0)LafPacketAnalysis.pyMedioSi un atacante obtiene un par de claves de sesión (por haber robado la AppKey en dispositivos OTAA o la AppSKey/NwkSKey en dispositivos ABP), podría enviar datos falsos válidos al servidor. Para que el servidor acepte mensajes falsificados, se requiere que el FCnt (Contador de trama) del mensaje sea mayor que el FCnt del último mensaje enviado. En un escenario donde el dispositivo falsificado original sigue enviando mensajes, el servidor comenzaría a descartar mensajes (válidos) ya que tendrían un FCnt más pequeño. Por lo tanto, cuando se reciben mensajes con un valor de FCnt menor al esperado por el servidor LoRaWAN, es posible inferir que se estableció una sesión paralela.Si el dispositivo es activado por aire (OTAA), cambiar su AppKey porque probablemente fue comprometida. Si está activado por personalización, cambiar su AppSKey y NwkSKey. Además, asegurarse de que el servidor LoRaWAN esté actualizado y no esté aceptando mensajes duplicados.
LAF-008Contraseña descifrada con JoinRequestLafBruteforcer.pyAltoFue posible descifrar un mensaje JoinRequest utilizando una AppKey conocida.Usar AppKeys diferentes a las proporcionadas por los proveedores o usar claves más aleatorias.
LAF-009Contraseña descifradaLafBruteforcer.pyAltoLa AppKey del dispositivo se encontró probando con una cadena conocida o no aleatoria. Fue descifrada usando un par de mensajes de Join (Solicitud y Aceptación).Usar un generador de claves aleatorio para la AppKey en lugar de usar las proporcionadas por los proveedores. Además, no establecer la misma AppKey para más de un dispositivo y no generar AppKeys usando una lógica predecible (ej. valores incrementales, invertir ciertos bytes, etc.).
LAF-010Cambio de ubicación de la puerta de enlaceLafPacketAnalysis.pyMedioSi se supone que la puerta de enlace no debe cambiar su ubicación. Puede haber sido robada, movida, o una puerta de enlace falsa puede estar intentando suplantar a la puerta de enlace legítima.Asegurarse de que la puerta de enlace no haya sido manipulada, tanto física como lógicamente.