物联网部署持续增长,其中很大一部分由数百万个 LPWAN(低功耗广域网络)传感器组成,这些传感器部署在全球数百个城市(智慧城市)、工业场所和家庭中。最常用的 LPWAN 技术之一是 LoRa,而 LoRaWAN 是其网络标准(MAC 层)。LoRaWAN 是一种内置加密的安全协议,但实现问题和弱点影响了当前大多数部署的安全性。
本项目旨在提供一系列工具,用于构建、解析、发送、分析和破解一组 LoRaWAN 数据包,以审计或渗透测试 LoRaWAN 基础设施的安全性。
以下是此仓库的结构:
|-- 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
我们提供不同的选项来让你的 LoRaWAN 审计框架运行起来:
tools/ 目录中的渗透测试工具,我们推荐此选项,以避免 docker 端口映射问题。localhost 连接到 Postgres。请参阅下面的说明来设置 Docker。以下说明将让你在本地机器上获得项目的副本及其依赖项。以下命令适用于基于 Debian 的环境:
克隆此仓库:git clone --recurse-submodules https://github.com/IOActive/laf.git
安装 python3:
sudo apt-get updatesudo apt-get install python3.6下载并安装 python 依赖:
sudo pip3 install paho-mqtt && sudo pip3 install sqlalchemy && sudo pip3 install psycopg2-binary &&sudo pip3 install python-dateutil设置 PYTHONPATH 和 ENVIRONMENT
cd laf && export PYTHONPATH=$(pwd) && export ENVIRONMENT='DEV'安装并设置 golang:
cd ~/Downloadssudo tar -C /usr/local -xvzf YOUR_GOLANG_FILEexport PATH=$PATH:/usr/local/go/binexport GOPATH="$HOME/go"编译 go 库:
cd laf/lorawanwrapper/utilsgo build -o lorawanWrapper.so -buildmode=c-shared jsonUnmarshaler.go lorawanWrapper.go micGenerator.go sessionKeysGenerator.go hashGenerator.go根据你希望使用的数据库:
a. PostgreSQL:按照“使用 Docker 安装 LAF”的说明,直到第 3 步。
b. SQLite:
cd laf/auditing/db__init__.py,注释掉用于 Postgres 的行(DB 连接和环境变量),并取消注释用于 sqlite 的行。就是这样!
这种方法避免了处理依赖项的安装,并启动了一个 PostgreSQL 数据库,工具会将数据包和数据保存其中。 容器:
步骤:
git clone https://github.com/IOActive/laf.gitcd laf/docker-compose up --builddocker exec -ti laf_tools_1 /bin/bash你可以使用 pgAdmin 检查数据库中的数据:
首先,访问 pgAdmin:
然后,你需要添加服务器:
以下是目录及其内部工具/功能的描述。
此目录中提供的主要工具是简化对 LoRaWAN 基础设施执行渗透测试的过程。
此工具旨在发送上行链路数据包(到网络服务器或 gatewayBridge,取决于基础设施)或下行链路数据包(到 packet-forwarder)。可选地,数据包可以被模糊处理,并且可以计算有效的 MIC。
可选参数:
-h, --help 显示此帮助信息并退出
--lcl-port LCL_PORT 源端口,例如 --lcl-port=623。
--timeout TIMEOUT 每个发送数据包之间的时间间隔(秒)。默认值为
1 秒。在此期间,发送器将监听回复。
--repeat 多次发送消息
--fuzz-out FUZZ_OUT [FUZZ_OUT ...]
模糊处理发送到目标端口的数据(参见
utils/fuzzer.py 中的模糊模式),例如 --fuzz-out 1 2。
--key KEY 输入密钥(十六进制格式,共 32 个字符
/ 16 字节)以对数据包进行签名(计算并添加新的
MIC)。注意,对于 JoinRequest,它必须是 AppKey,
对于 Data 数据包,它必须是 NwkSKey。此程序无法
预先验证。例如
00112233445566778899AABBCCDDEEFF
-a DEVADDR, --devaddr DEVADDR
要冒用的设备地址,十六进制格式(共 8 个字符),例如 AABB0011。
--fcnt FCNT 要设置在给定数据包中的帧计数器。
这对 JoinRequest/JoinAccept 不起作用,因为
这些数据包没有 fCnt。
必需参数:
--dst-ip DST_IP 目标 IP,例如 --dst-ip 192.168.3.101。
--dst-port DST_PORT 目标端口,例如 --dst-port 623。
--data DATA UDP 数据包。也可以在脚本末尾的
"data" 数组中添加更多数据包。数据包必须是一个字节字符串
(你需要转义双引号)。***示例*** 使用 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=\"}]}'" ***示例*** 使用 gatevice
[GV] 格式,以即时模式发送,BW125 和
频率 902.3: "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}'"
示例:
每隔 2 秒从端口 10000 向(localhost, 10001)发送单个数据包,并随机模糊 MIC 和 FCounter:
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=\"}]}'"
此 UDP 代理主要旨在放置在一系列网关(packet_forwarders)和网络服务器或网关桥之间(取决于正在评估的基础设施)。它还提供了在所需方向(上行或下行)模糊数据的可能性。
可选参数:
-h, --help 显示此帮助信息并退出
--collector-port COLLECTOR_PORT
Packet forwarder 数据收集器端口,例如 --collector-
port 1701。参见
auditing/datacollectors/PacketForwarderCollector.py
--collector-ip COLLECTOR_IP
Packet forwarder 数据收集器 IP。默认值为
localhost。例如 --collector-ip 192.168.1.1。参见
auditing/datacollectors/PacketForwarderCollector.py
--fuzz-in FUZZ_IN [FUZZ_IN ...]
模糊处理发送到 dst-port 的数据(指定模式)(参见
utils/fuzzer.py 中的模糊模式),例如 --fuzz-in 1 2
...
--fuzz-out FUZZ_OUT [FUZZ_OUT ...]
模糊处理发送到(源)端口的数据(指定模式)
(参见 utils/fuzzer.py 中的模糊模式),例如 --fuzz-out
1 2 ...
-k KEY, --key KEY 输入设备的 AppSKey(十六进制格式,共 32 个
字符 / 16 字节)以解密其 FRMPayload 并
以纯文本形式打印。你也可以输入 AppKey
如果你想解密给定的 Join Accept。例如
00112233445566778899AABBCCDDEEFF
-p PATH, --path PATH 保存数据的文件路径。如果未给出,数据
将不会被保存。
--no-log 不将 UDP 数据包打印到控制台
--no-parse 不解析 PHYPayload。如果选择此选项,
则不会导入 /lorawanwrapper/ 中的 Golang 库
(不需要编译 golang 库)
必需参数: