IoT 배포는 계속 성장하고 있으며 그 중대한 성장의 일부는 산업 및 가정에서 전 세계 수백 개의 도시 (스마트 도시)에 배포 된 수백만의 LPWAN (저전력 와이드 지역 네트워크) 센서로 구성됩니다. 가장 많이 사용되는 LPWAN 기술 중 하나는 Lora가 네트워크 표준 (Mac Layer) 인 Lora입니다. 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/ DIR에 위치한 Pentesting Tools를 사용하는 것이 주요 목표라면이 옵션을 권장합니다.localhost 통해 Postgres에 연결하려고합니다. Docker를 설정하려면 아래 지침을 참조하십시오.이 지침은 프로젝트 사본과 로컬 컴퓨터의 종속성을 얻게됩니다. 아래 명령은 데비안 기반 환경을위한 것입니다.
복제이 저장소 : git clone --recurse-submodules https://github.com/IOActive/laf.git
Python3 설치 :
sudo apt-get updatesudo apt-get install python3.6파이썬 종속성 다운로드 및 설치 :
sudo pip3 install paho-mqtt && sudo pip3 install sqlalchemy && sudo pip3 install psycopg2-binary &&sudo pip3 install python-dateutilPythonpath 및 환경을 설정하십시오
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사용하려는 DB에 따라
에이. postresql : 3 단계까지 'docker를 사용하여 LAF 설치'지침을 따르십시오.
비. sqlite :
cd laf/auditing/db__init__.py 수정하고 Postgres (DB 연결 및 환경 변수)와 함께 사용할 라인을 SQLITE와 함께 사용할 라인을 댓글을 달아주십시오.그리고 그게 다야!
이 접근법은 종속성 설치를 처리하지 않고 도구가 패킷과 데이터를 저장하는 PostgreSQL DB를 시작합니다. 컨테이너 :
단계 :
git clone https://github.com/IOActive/laf.gitcd laf/docker-compose up --builddocker exec -ti laf_tools_1 /bin/bash 에 도구를 사용하려면pgadmin을 사용하여 DB의 데이터를 확인할 수 있습니다.
첫째, pgadmin에 대한 액세스 :
그런 다음 서버를 추가해야합니다.
다음은 디렉토리와 그 안에 도구 / 기능에 대한 설명입니다.
이 디렉토리에 제공된 도구의 주요 목적은 로라완 인프라에 대한 침투 테스트의 실행을 용이하게하는 것입니다.
이 도구는 업 링크 패킷 (인프라에 따라 네트워크 서버 또는 게이트웨이 브리지로) 또는 다운 링크 패킷 (패킷 포워드)을 보내도록 고안되었습니다. 선택적으로 패킷은 퍼지 될 수 있고 유효한 마이크를 계산할 수 있습니다.
선택적 인수 :
-h, --help show this help message and exit
--lcl-port LCL_PORT Source port, eg. --lcl-port=623.
--timeout TIMEOUT Time in seconds between every packet sent. Default is
1s. In this time, the sender will listen for replies.
--repeat Send message/s multiple times
--fuzz-out FUZZ_OUT [FUZZ_OUT ...]
Fuzz data sent to dest port (see fuzzing modes in
utils/fuzzer.py), eg. --fuzz-out 1 2.
--key KEY Enter the key (in hex format, a total of 32 characters
/ 16 bytes) to sign packets (calculate and add a new
MIC). Note that for JoinRequests it must be the
AppKey, and the NwkSKey for Data packets. This cannot
be validated beforehand by this program. eg.
00112233445566778899AABBCCDDEEFF
-a DEVADDR, --devaddr DEVADDR
DeviceAddress to impersonate, given in hex format (8
characters total), eg. AABB0011.
--fcnt FCNT The frame counter to be set in the given data packet.
This wouldn't work in a JoinRequest/JoinAccept since
this packets don't have a fCnt
필수 주장 :
--dst-ip DST_IP Destination ip, eg. --dst-ip 192.168.3.101.
--dst-port DST_PORT Destination port, eg. --dst-port 623.
--data DATA UDP packet. It can also be added more packets in
"data" array at the end of this script. The packet
must be a byte string (you will have to escape double
quotes). ***EXAMPLE*** with the packet_forwarder
format: --data "b'x02xe67x00xb8'xebxffxfezx80
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="}]}'" ***EXAMPLE*** using the gatevice
[GV] format sending in inmediate mode, in BW125 and
freq 902.3 is "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}'"
예:
포트 10000 퍼지에서 마이크와 fcounter에서 2 초마다 (LocalHost, 10001)까지 단일 패킷을 보내려면 :
python3 UdpSender.py --lcl-port 10000 --dst-ip 127.0.0.1 --dst-port 10001 --timeout 2 --fuzz-out 4 5 --data "b'x02xe67x00xb8'xebxffxfezx80xdb{"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 show this help message and exit
--collector-port COLLECTOR_PORT
Packet forwarder data collector port, eg. --collector-
port 1701. See
auditing/datacollectors/PacketForwarderCollector.py
--collector-ip COLLECTOR_IP
Packet forwarder data collector ip. Default is
localhost. eg. --collector-ip 192.168.1.1. See
auditing/datacollectors/PacketForwarderCollector.py
--fuzz-in FUZZ_IN [FUZZ_IN ...]
Fuzz data sent to dst-port in the given modes (see
fuzzing modes in utils/fuzzer.py), eg. --fuzz-in 1 2
...
--fuzz-out FUZZ_OUT [FUZZ_OUT ...]
Fuzz data sent to (source) port in the given modes
(see fuzzing modes in utils/fuzzer.py), eg. --fuzz-out
1 2 ...
-k KEY, --key KEY Enter a device AppSKey (in hex format, a total of 32
characters / 16 bytes) to decrypt its FRMPayload and
print it in plain text. You can also enter the AppKey
if you wish to decrypt a given Join Accept. eg.
00112233445566778899AABBCCDDEEFF
-p PATH, --path PATH Filepath where to save the data. If not given, data
will not be saved.
--no-log Do not print UDP packages into console
--no-parse Do not parse PHYPayload. If this option is selected,
Golang librarys from /lorawanwrapper/ won't be
imported (golang libs compiling is not required)
필수 주장 :
--port PORT The local port to listen, eg. --port 623.
--dst-ip DST_IP Destination host ip, eg. --dst-ip 192.168.3.101.
--dst-port DST_PORT Destination host port, eg. --dst-port 623.
예:
포트 1234에서 수신 된 패킷을 (LocalHost, 1235) 및 Vicecersa로 보냅니다. 항구에서받은 패킷은 퍼지 (Devnonce)가 랜도리로 바뀌고 (LocalHost, 1235)로 전달됩니다.
python3 UdpProxy.py --port 1234 --dst-ip 127.0.0.1 --dst-port 1235 --fuzz-in 9
이 TCP 프록시는 주로 네트워크 서버와 MQTT 브로커 사이에 배치됩니다. 또한 데이터에 대한 적절성을 제공합니다.
선택적 인수 :
-h, --help show this help message and exit
--fuzz-in FUZZ_IN [FUZZ_IN ...]
Fuzz data sent to dst-port in the given modes (see
fuzzing modes in utils/fuzzer.py)
필수 주장 :
--lcl-port LCL_PORT The local port to listen, eg. --lcl-port=623.
--dst-ip DST_IP Destination host ip, eg. --dst-ip=192.168.3.101.
--dst-port DST_PORT Destination host port, eg. --dst-port=623.
예:
(LocalHost, 1884) 및 (LocalHost, 1883)에서 데이터를 보내고받습니다.
python3 TcpProxy.py --lcl-port 1884 --dst-ip 127.0.0.1 --dst-port 1883
이 디렉토리에는 구문 분석, 공예, Bruteforcer 등의 일련의 스크립트가 포함되어 있습니다. Lorawan A 패킷.
이 스크립트는 Base64에서 JoinAccept 또는 JoinRequest를 수신하며 파일로 제공하거나 즉시 생성 할 수있는 가능한 키 세트와 AppKey를 해독하려고합니다.
선택적 인수 :
-h, --help show this help message and exit
-k KEYS, --keys KEYS File containing a list of keys, separated by n. Will
use /auditing/analyzers/bruteForcer/keys.txt by
default
--dont-generate Select this options if you don't want to generate keys
on the fly with the following combinations: 1- Combine
the first byte and the last fifteeen bytes. eg.
AABBBBBBBBBBBBBBBBBBBBBBBBBBBBBB 2- Combine even and
odd bytes position equally. eg.
AABBAABBAABBAABBAABBAABBAABBAABB 3- The first 14 bytes
in 00 and combine the last 2. eg.
0000000000000000000000000000BA01
필수 주장 :
-a ACCEPT, --accept ACCEPT
Join Accept in Base64 format to be bruteforced. eg. -a
IHvAP4MXo5Qo6tdV+Yfk08o=
-r REQUEST, --request REQUEST
Join Request in Base64 format to be bruteforced. eg.
-r AMQAAAAAhQAAAgAAAAAAAADcYldcgbc=
예:
my-keys.txt의 키 세트로 JoinRequest를 깨고 Aprox도 생성하십시오. 200000 더 많은 Dinamically.
python3 BruteForcer.py -a IHvAP4MXo5Qo6tdV+Yfk08o= -r AMQAAAAAhQAAAgAAAAAAAADcYldcgbc= -k ./my-keys.txt
이 스크립트는 Base64의 PhypayLoad 패킷과 패킷 유형에 따라 AppKey의 NWKSKey가 될 수있는 키를 수신하고 새 마이크를 생성합니다.
선택적 인수 :
-h, --help show this help message and exit
--jakey JAKEY [JoinAccept ONLY]. Enter the key used to encrypt the
JoinAccept previously (in hex format, a total of 32
characters / 16 bytes). This cannot be validated
beforehand by this program. eg.
00112233445566778899AABBCCDDEEFF. A valid key sample
for the JoinAccept "IB1scNmwJRA32RfMbvwe3oI=" is
"f5a3b185dfe452c8edca3499abcd0341"
필수 주장 :
-d DATA, --data DATA Base64 data to be signed. eg. -d
AE0jb3GsOdJVAwD1HInrJ7i3yXAFxKU=
-k KEY, --key KEY Enter the new key (in hex format, a total of 32
characters / 16 bytes) to sign packets (calculate and
add a new MIC). Note that for JoinRequest/JoinAccept
it must be the AppKey, and the NwkSKey for Data
packets. This cannot be validated beforehand by this
program. eg. 00112233445566778899AABBCCDDEEFF
예:
appkey 001122233445556678999aabbccddeeff와 함께 주어진 phypayload에 서명하십시오.
python3 MicGenerator.py -d AE0jb3GsOdJVAwD1HInrJ7i3yXAFxKU= -k 00112233445566778899AABBCCDDEEFF
이 스크립트는 Lorawan JSON 패킷을 수신하여 Base64로 추적합니다. PacketParser.py로 역전되므로 해당 스크립트의 출력을 여기에서 사용하고 그 반대로 사용할 수 있습니다.
선택적 인수 :
-h, --help show this help message and exit
-k KEY, --key KEY Enter a device AppSKey or AppKey (in hex format, a
total of 32 characters / 16 bytes) to encrypt the
FRMPayload or a Join Accept. eg.
F5A3B185DFE452C8EDCA3499ABCD0341
--nwkskey NWKSKEY Enter the network session key if you'd like to
generate a data packet with a valid MIC.
필수 주장 :
-j JSON, --json JSON JSON object to parse. eg. -j '{"mhdr":
{"mType":"JoinRequest","major":"LoRaWANR1"},"macPayloa
d":{"joinEUI":"55d239ac716f234d","devEUI":"b827eb891cf
50003","devNonce":51639},"mic":"7005c4a5"}'
예:
JSON에 주어진 값과 함께 Base64에서 joinRequest phypayLoad를 얻습니다.
python3 PacketCrafter.py -j '{"mhdr":{"mType":"JoinRequest","major":"LoRaWANR1"},"macPayload":{"joinEUI":"55d239ac716f234d","devEUI":"b827eb891cf50003","devNonce":51639},"mic":"7005c4a5"}'
이 스크립트는 Base64에서 단일 Lorawan PhypayLoad 데이터를 파르즈 및 인쇄합니다. 그것은 packetcrafter.py로 역전되므로 해당 스크립트의 출력을 여기에서 사용하고 그 반대로 사용할 수 있습니다.
선택적 인수 :
-h, --help show this help message and exit
-k KEY, --key KEY Enter a device AppKey or AppSKey depending on the
packet to be decrypted (join accept or data packet).
Must be in hex format, a total of 32 characters / 16
bytes. eg. 00112233445566778899AABBCCDDEEFF
필수 주장 :
-d DATA, --data DATA Base64 data to be parsed. eg. -d
AE0jb3GsOdJVAwD1HInrJ7i3yXAFxKU=
예:
위의 예에서 JSON 형식의 JOinRequest를 얻으십시오.
python3 PacketParser.py -d AE0jb3GsOdJVAwD1HInrJ7i3yXAFxKU=
이 스크립트는 Base64의 JoinAccept 및 JoinRequest를 수신하고 세션 키를 생성하는 AppKey를 수신합니다. 사용의 예 :
선택적 인수 :
-h, --help show this help message and exit
필수 주장 :
-a JACCEPT, --jaccept JACCEPT
JoinAccept payload in base64
-r JREQUEST, --jrequest JREQUEST
JoinRequest payload in base64
-k KEY, --key KEY Enter a device AppKey (in hex format, a total of 32
characters / 16 bytes). eg.
00112233445566778899AABBCCDDEEFF
예:
다음과 결합 데이터를 사용하여 AppSkey 및 NWKSKey를 얻으십시오.
python3 SessionKeysGenerator.py -r AE0jb3GsOdJVAwD1HInrJ7i3yXAFxKU= -a IB1scNmwJRA32RfMbvwe3oI= -k f5a3b185dfe452c8edca3499abcd0341
이들은 UdpSender.py 및 UdpProxy.py 에서 사용하는 보조 기능입니다. Fuzzer.py 에서는 퍼징 모드가 구현 될 수 있습니다.
이 디렉토리의 일반적인 목적은 Lorawan 패킷을 수집하고 트래픽의 다양한 측면을 분석하고 Appkey를 크게 강화하기 위해 열쇠 세트를 시도하는 것입니다.
이 디렉토리에는 다른 소스 (예 : 게이트웨이 Packet_forwarder, Things Network 등)에서 Lorawan 패킷을 수신하고 표준 형식의 파일에 저장하는 스크립트 세트가 포함되어 있습니다. 이 파일은 나중에 스크립트 /auditing/analyzers/LafProcessData.py 에 의해 가져와 다른 하위 Tools를 실행해야합니다.
이 스크립트는 MQQT 브로커에 연결하고 모든 주제를 검색하고 지정된 필드의 파일에 메시지를 저장합니다. 파일 이름은이 스크립트가 시작된 날짜로 구성됩니다.
선택적 인수 :
-h, --help show this help message and exit
--collector-id COLLECTOR_ID
The ID of the dataCollector. This ID will be
associated to the packets saved into DB. eg. --id 1
--organization-id ORGANIZATION_ID
The ID of the dataCollector. This ID will be
associated to the packets saved into DB. eg. --id 1
--topics TOPICS [TOPICS ...]
List the topic(s) you want to suscribe separated by
spaces. If nothing given, default will be "#.
필수 주장 :
--ip IP MQTT broker ip, eg. --ip 192.168.3.101.
--port PORT MQTT broker port, eg. --port 623.
예:
기본 포트 (1883)에서 IP 200.200.200.200으로 브로커를 MQTT에 연결하십시오.
python3 GenericMqttCollector.py --ip 200.200.200.200 --port 1883
이 스크립트는 Loraserver.io MQQT 브로커에 연결하여 DB에 메시지를 저장합니다. 고유 한 CollectorId를 지정해야하며 원하는 주제를 지정할 수 있습니다.
선택적 인수 :
-h, --help show this help message and exit
--port PORT MQTT broker port, eg. --port 623. Default 1883.
--collector-id COLLECTOR_ID
The ID of the dataCollector. This ID will be
associated to the packets saved into DB. eg. --id 1
--organization-id ORGANIZATION_ID
The ID of the dataCollector. This ID will be
associated to the packets saved into DB. eg. --id 1
--topics TOPICS [TOPICS ...]
List the topic(s) you want to suscribe separated by
spaces. If nothing given, default will be "#.
필수 주장 :
--ip IP MQTT broker ip, eg. --ip 192.168.3.101.
이 스크립트는 Gateway Packet_Forwarder 형식의 UDP 프록시에서 UDP 패킷을 수신하여 유지합니다.
선택적 인수 :
-h, --help show this help message and exit
--collector-id COLLECTOR_ID
The ID of the dataCollector. This ID will be
associated to the packets saved into DB. eg. --id 1
--organization-id ORGANIZATION_ID
The ID of the dataCollector. This ID will be
associated to the packets saved into DB. eg. --id 1
필수 주장 :
-n NAME, --name NAME Unique string identifier of the Data Collector. eg.
--name semtech_collector
-p PORT, --port PORT Port where to listen for UDP packets. --port 1702.
예:
로컬 포트 1700으로 전송하는 게이트웨이와 네트워크 Xserver (LocalHost, 1701) 사이의 데이터를 기록합니다. 데이터를 ./ 디렉토리에 저장하십시오.
python3 PacketForwarderCollector.py --name semtech_collector --port 1700
이 스크립트는 파일 또는 파일 또는 stdin에서 A를 읽고 다른 하위 툴을 실행합니다. 선택한 옵션에 따라 Lorawan 트래픽 분석을 실행하거나 AppKey를 크게 강화하거나받은 모든 패킷을 구문 분석 할 수 있습니다. 이러한 옵션을 결합 할 수 있습니다.
선택적 인수 :
This script reads retrieves packets from DB and executes different sub-tools.
Then, each sub-tool will save output data into the DB. See each option for
more information.
optional arguments:
-h, --help show this help message and exit
-a, --analyze Collect and analyze different aspects from traffic. If
Bruteforcer (-b) is activated, results will be
corelated
-b, --bforce Try to bruteforce the AppKeys with JoinRequests and
JoinAccepts payloads
-k KEYS, --keys KEYS [Bruteforcer] Filepath to keys file. If not provided,
"bruteForcer/keys.txt" will be used
--no-gen [Bruteforcer] Don't generate keys, only try keys from
files
-p, --parse Parse the PHYPayload into readable information
--from-id FROM_ID Packet ID from where to start processing.
--to-id TO_ID Last packet ID to be processed.
예:
Packet ID 1000에서 시작하여 DB의 프로세스 패킷은 트래픽 분석을 실행하고 my-keys.txt에 제공된 앱 키를 깨뜨 리려고하지만 더 많은 키를 생성하지는 않습니다.
python3 LafProcessData.py -a -b -k my-keys.txt --no-gen --from-id 1000
이 스크립트는 lafprocessdata.py가 조율 한 기능을 제공합니다. 아래에서 LafPacketAnalysis.py 및 LafBruteForcer.py 에 의해 구현 된 경고 :
| ID | 제목 | 분석기 | 위험 수준 | 설명 | 권장 조치 |
|---|---|---|---|---|---|
| LAF-001 | Devnonce는 반복되었습니다 | lafpacketanalysis.py | 낮은 | 각 장치의 Devnonces는 충돌하지 않을 정도로 무작위 여야합니다. 많은 메시지에서 동일한 Devnonce가 반복 된 경우 장치가 재생 공격을 받고 있다고 추론 할 수 있습니다. 이것은 joinrequest를 포착하여 게이트웨이로 다시 보내려고하는 공격자입니다. | Devnonces가 생성되는 방법을 확인하십시오 : 생성하는 기능은 랜덤 라이브러리를 사용하여 구현해야합니다. 또한, 서버가 이전에 기기가 보낸 이전의 유효한 조인 요청을 수락하지 않으려면 서버가 과거의 devnonces (db로 지속되어야 함)를 점검하고 새 세션을 생성하는지 확인해야합니다. |
| LAF-002 | Deveuis는 동일한 Devaddr를 공유합니다 | lafpacketanalysis.py | 정보 | 두 개의 다른 장치에 동일한 DevADDR이 할당되었을 수 있습니다. 이것은 보안 위협이 아닙니다. | 장치가 공기를 초과하는 경우 (OTAA) : DevAddrs를 할당하는 데 사용되는 논리를 확인하고 서버가 다른 장치에 동일한 DevADDR을 할당하지 않도록하십시오. 개인화 (ABP)에 의해 장치가 활성화 된 경우 : 장치의 펌웨어에서 구성된 DevADDR이 Lorawan 네트워크에서 고유한지 확인하십시오. |
| LAF-003 | 재생에 가입하십시오 | TODO | 중간 | 복제 된 조인 요청 패킷이 감지되었으며 로라완 서버가 재생 공격을 받고 있음을 의미 할 수 있습니다. 이것은 이전 조인 요청 패킷을 캡처하고 새 세션을 생성하기 위해 Lorawan 서버로 다시 전송하는 공격자입니다. | Devnonces가 생성되는 방법을 확인하십시오 : 생성하는 기능은 랜덤 라이브러리를 사용하여 구현해야합니다. 또한, 서버가 이전에 기기가 보낸 이전의 유효한 조인 요청을 수락하지 않으려면 서버가 과거의 devnonces (db로 지속되어야 함)를 점검하고 새 세션을 생성하는지 확인해야합니다. |
| LAF-004 | 업 링크 데이터 패킷이 재생됩니다 | TODO | 중간 | 복제 된 업 링크 패킷이 감지되었으며 로라완 서버가 재생 공격을 받고 있음을 의미 할 수 있습니다. 이것은 업 링크 패킷 (장치에서 전송)을 캡처하고 Lorawan 서버로 다시 보내는 공격자입니다. | Over the Air 활성화 (OTAA) 장치 :이 공격의 영향을 피하기 위해 모든 장치 재설정 또는 카운터 오버 플로우 후 세션 키가 다시 생성되도록하십시오. Lorawan v1.0.*의 개인화 (ABP) 장치에 의해 활성화되면 장치를 OTAA로 전환하는 것 외에는 재생 공격을 방지하기 위해 아무 일도 할 수 없습니다. |
| LAF-005 | 다운 링크 데이터 패킷이 재생됩니다 | TODO | 높은 | 복제 된 다운 링크 패킷이 감지되었습니다. 서버는 재생 공격에 응답하거나 장치에 비정형 트래픽을 생성하고 있습니다. | 서버의 로그를 확인하고 이전 권장 조치가 구현되었는지 확인하십시오. |
| LAF-006 | 가능한 ABP 장치 (카운터 리셋 및 조인 없음) | lafpacketanalysis.py | 높은 | 카운터가 재설정 된 경우 (0으로 돌아 왔음) DevADDR은 동일하게 유지되고 이전 조인 프로세스가 감지되지 않았으며, 개인화 (ABP)에 의해 장치가 활성화되었음을 암시 할 수 있습니다. 조인 프로세스가 수행되지 않기 때문에 ABP 장치 구현은 권장되지 않으므로 세션 키는 영원히 동일하게 유지됩니다. 세션 키를 변경하지 않는 장치는 Eaveasdrop 또는 Replay와 같은 다른 공격이 발생하기 쉽습니다. | 개인화 (ABP) 장치에 의해 활성화 된 모든 공기 활성화 (OTAA) 장치로 교체해야합니다. ABP 장치의 구현은 권장되지 않습니다. |
| LAF-007 | 예상보다 작은 카운터를 받았습니다 (0) | lafpacketanalysis.py | 중간 | 공격자가 한 쌍의 세션 키를 얻는 경우 (OTAA 장치 또는 APP 장치에서 AppSkey/Nwkskey에서 AppKey를 도난당한 경우) 가짜 유효한 데이터를 서버에 보낼 수 있습니다. 서버가 스푸핑 된 메시지를 수락하기 위해서는 메시지의 FCNT (프레임 카운터)가 마지막 메시지의 FCNT보다 높아야합니다. 원래 스푸핑 된 장치가 메시지를 계속 보내는 시나리오에서 서버는 FCNT가 더 작은 메시지를 폐기하기 시작합니다. 따라서 Lorawan 서버에서 예상보다 FCNT 값이 작은 메시지가 수신되면 병렬 세션이 설정되었다고 추론 할 수 있습니다. | 장치가 공기 활성화 장치 (OTAA)를 초과하는 경우 AppKey가 손상되었으므로 변경하십시오. 개인화에 의해 활성화되면 AppSkey와 Nwkskey를 변경하십시오. 또한 Lorawan 서버가 업데이트되었으며 복제 된 메시지를 수락하지 않도록하십시오. |
| LAF-008 | joinRequest로 비밀번호가 금이 간다 | lafbruteforcer.py | 높은 | 알려진 AppKey를 사용하여 JoinRequest 메시지를 해독 할 수있었습니다. | 공급 업체가 제공 한 것과 다른 appkey를 사용하거나 더 많은 임의의 키를 사용하십시오. |
| LAF-009 | 비밀번호 금이 간다 | lafbruteforcer.py | 높은 | 장치의 appkey는 잘 알려진 또는 비 랜덤 스트링으로 시도한 것으로 나타났습니다. 한 쌍의 조인 메시지 (요청 및 수락)를 사용하여 해독되었습니다. | 공급 업체가 제공 한 것 대신 appkey에 임의의 키 생성기를 사용하십시오. 또한 동일한 appkey를 하나 이상의 장치에 설정하지 말고 예측 가능한 논리 (예 : 증분 값, 특정 바이트 등을 플립 등)를 사용하여 Appkeys를 생성하지 마십시오. |
| LAF-010 | 게이트웨이는 위치를 변경했습니다 | lafpacketanalysis.py | 중간 | 게이트웨이가 위치를 변경하지 않아야하는 경우. 도난 당하거나 이동했거나 가짜 게이트웨이가 합법적 인 게이트웨이를 가장하려고 할 수도 있습니다. | 게이트웨이가 육체적으로나 논리적으로 변조되지 않았는지 확인하십시오. |
이 디렉토리는 Golang으로 작성된 라이브러리 https://github.com/brocaar/lorawan/에 대한 포장지 세트를 제공합니다. 이러한 기능은 도구에 의해 구현됩니다.
여기에는 다양한 작업을 자동화하기위한 일련의 스크립트가 있습니다. 필요한 경우 실행 권한을 부여하십시오 (Linux/MacOS의 경우 chmod +x your_script ).
스니핑 목적으로 게이트웨이를 쉽게 설정하고 채널을 전환하십시오. 사용 방법에 대한 자세한 내용은이 디렉토리에서 readme를 참조하십시오.
이 스크립트는 연결된 LORA 농축기 (IC980-SPI, RHF0M301-SPI, RAK831-SPI 또는 수동 설정)와 함께 Lorawan Gateway를 구축하기 위해 Raspberry Pi에 필요한 모든 소프트웨어 패키지를 설치하는 데 사용됩니다.
어떤 주파수 LORA 장치가 작동하는지 알 수 없으므로 스니핑 목적으로 US915 및 EU868 주파수 대역 에서 게이트웨이 채널을 전환 할 수있는 스크립트를 만들었습니다. 32 또는 64 채널을 지원하는 전문적이고 비싼 게이트웨이가 있지만 대부분의 게이트웨이는 최대 8 개의 채널을 지원합니다. 이 스크립트는 이런 종류의 게이트웨이에서 실행하기위한 것입니다.
최소한 US915 주파수 대역에서 처음 8 채널이 가장 많이 사용됩니다. 그러나 다른 그룹의 채널을 사용하는 것으로 알려진 구현이 있습니다. 예를 들어 Uplink Communication을 위해 두 번째 그룹 (8-15)을 사용하는 Things Networks와 마찬가지로.
현재 우리는 다른 주파수 대역을 지원하지 않지만이 스크립트를 거의 변경하지 않으면 서 스스로 할 수 있습니다 :).
우리는이 프레임 워크의 비디오를 작동 시켰습니다 (Blackhat 2019에 제시된 동일한 시나리오) : https://youtu.be/mm6a2rvnocs. 데모의 자세한 단계는 YouTube 비디오 설명에 있습니다.
TODO
이 프로젝트는 BSD-3-Clause 라이센스에 따라 라이센스가 부여됩니다.