
이 프로젝트는 LoRaWAN 인프라의 보안을 감사하거나 침투 테스트하기 위해 일련의 LoRaWAN 패킷을 제작, 구문 분석, 전송, 분석 및 크랙할 수 있는 도구 모음을 제공하는 것을 목표로 합니다.
IoT 배포는 계속해서 성장하고 있으며, 그 상당한 성장의 일부는 전 세계 수백 개 도시(스마트 시티), 산업 및 가정에 배포된 수백만 개의 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.6Python 종속성을 다운로드하여 설치합니다:
sudo pip3 install paho-mqtt && sudo pip3 install sqlalchemy && sudo pip3 install psycopg2-binary &&sudo pip3 install python-dateutilPYTHONPATH 및 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사용하려는 DB에 따라:
a. PostgreSQL: 'Docker를 사용하여 LAF 설치'의 3단계까지 따릅니다.
b. 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/bashpgAdmin을 사용하여 DB의 데이터를 확인할 수 있습니다:
먼저, pgAdmin에 접속합니다:
그런 다음, 서버를 추가해야 합니다:
다음은 디렉토리와 그 안에 있는 도구/기능에 대한 설명입니다.
이 디렉토리에 제공된 도구의 주요 목적은 LoRaWAN 인프라에 대한 침투 테스트 실행을 용이하게 하는 것입니다.
이 도구는 업링크 패킷(인프라에 따라 네트워크 서버 또는 게이트웨이 브리지로) 또는 다운링크 패킷(패킷-포워더로)을 전송하기 위한 것입니다. 선택적으로 패킷을 퍼징하거나 유효한 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 패킷에 서명하기 위해 키를 입력합니다(16진수 형식, 총 32자
/ 16바이트). JoinRequest의 경우 AppKey여야 하며,
데이터 패킷의 경우 NwkSKey여야 합니다. 이는 이 프로그램에서
사전에 검증할 수 없습니다. 예:
00112233445566778899AABBCCDDEEFF
-a DEVADDR, --devaddr DEVADDR
가장할 장치 주소를 16진수 형식으로 입력합니다(8자
총), 예: AABB0011.
--fcnt FCNT 주어진 데이터 패킷에 설정할 프레임 카운터입니다.
이 패킷에는 fCnt가 없으므로 JoinRequest/JoinAccept에서는 작동하지 않습니다.
필수 인수:
--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초마다 (localhost, 10001)로 포트 10000에서 단일 패킷을 보내고, 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)와 네트워크 서버 또는 게이트웨이 브리지 사이에 배치되도록 설계되었습니다. 또한 원하는 방향(업링크 또는 다운링크)으로 데이터 퍼징 기능을 제공합니다.
선택적 인수: