Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
laf — 이 프로젝트는 LoRaWAN 인프라의 보안을 감사하거나 침투 테스트하기 위해 일련의 LoRaWAN 패킷을 제작, 구문 분석, 전송, 분석 및 크랙할 수 있는 도구 모음을 제공하는 것을 목표로 합니다. | Kitploit
도구/GitHubGitHub/ioactive/laf
Packet Sniffing & AnalysisIoT SecurityVulnerability AnalysisExploitationFuzzingWireless SecurityCryptographyPenetration Testing
GitHubioactive/laf

laf

이 프로젝트는 LoRaWAN 인프라의 보안을 감사하거나 침투 테스트하기 위해 일련의 LoRaWAN 패킷을 제작, 구문 분석, 전송, 분석 및 크랙할 수 있는 도구 모음을 제공하는 것을 목표로 합니다.

저장소 보기
187373년 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

LoRaWAN 감사 프레임워크 - 알파 버전

IoT 배포는 계속해서 성장하고 있으며, 그 상당한 성장의 일부는 전 세계 수백 개 도시(스마트 시티), 산업 및 가정에 배포된 수백만 개의 LPWAN(저전력 광역 네트워크) 센서로 구성됩니다. 가장 많이 사용되는 LPWAN 기술 중 하나는 LoRa이며, LoRaWAN은 네트워크 표준(MAC 계층)입니다. LoRaWAN은 내장된 암호화를 사용하는 보안 프로토콜이지만, 구현 문제와 취약점으로 인해 대부분의 현재 배포의 보안이 영향을 받습니다.

이 프로젝트는 LoRaWAN 인프라의 보안을 감사하거나 침투 테스트하기 위해 일련의 LoRaWAN 패킷을 조작, 구문 분석, 전송, 분석 및 크랙하는 도구 세트를 제공하고자 합니다.

아래는 이 저장소의 구조입니다:

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

시작하기

LoRaWAN 감사 프레임워크를 실행할 수 있는 다양한 옵션을 제공합니다:

  1. 첫 번째 옵션은 로컬에 설치하려는 사용자를 위한 것입니다. 주 목적이 tools/ 디렉토리에 있는 침투 테스트 도구를 사용하는 것이라면 Docker 포트 매핑 문제를 피하기 위해 이 옵션을 권장합니다.
  2. 다른 옵션은 Docker 컨테이너에서 실행하려는 사용자를 위한 것으로, 수동으로 종속성을 설치할 필요가 없습니다. 분석기를 사용하고 환경을 수동으로 설정할 시간이 많지 않은 경우 이 옵션을 권장합니다.
  3. 물론 LAF를 로컬에서 실행하고 Docker 컨테이너의 Postgres DB를 sqlite 대신 사용할 수도 있습니다. LAF는 localhost를 통해 Postgres에 연결을 시도합니다. Docker 설정에 대한 지침은 아래를 참조하세요.

로컬 환경에 LAF 설치

다음 지침을 통해 프로젝트와 그 종속성을 로컬 머신에 복사합니다. 아래 명령어는 Debian 기반 환경을 위한 것입니다:

  1. 이 저장소를 클론합니다: git clone --recurse-submodules https://github.com/IOActive/laf.git

  2. python3를 설치합니다:

    1. sudo apt-get update
    2. sudo apt-get install python3.6
  3. Python 종속성을 다운로드하여 설치합니다:

    1. sudo pip3 install paho-mqtt && sudo pip3 install sqlalchemy && sudo pip3 install psycopg2-binary &&sudo pip3 install python-dateutil
  4. PYTHONPATH 및 ENVIRONMENT를 설정합니다:

    1. cd laf && export PYTHONPATH=$(pwd) && export ENVIRONMENT='DEV'
  5. golang을 설치하고 설정합니다:

    1. 운영 체제에 맞게 https://golang.org/dl/에서 golang을 다운로드합니다.
    2. go 설치 프로그램이 다운로드된 폴더로 이동합니다: cd ~/Downloads
    3. 설치 프로그램의 압축을 풉니다: sudo tar -C /usr/local -xvzf YOUR_GOLANG_FILE
    4. PATH에 추가합니다: export PATH=$PATH:/usr/local/go/bin
    5. GOPATH를 설정합니다: export GOPATH="$HOME/go"

이상입니다!

Docker를 사용하여 LAF 설치

이 방법은 종속성 설치를 처리할 필요가 없으며, 도구가 패킷과 데이터를 저장하는 PostgreSQL DB를 시작합니다. 컨테이너:

  • Tools.
  • PostgreSQL.
  • PgAdmin4.

단계:

  1. 이 저장소를 클론합니다: git clone https://github.com/IOActive/laf.git
  2. cd laf/로 이동합니다.
  3. 컨테이너를 시작합니다: docker-compose up --build
  4. 컨테이너 내에서 도구를 사용하려면: docker exec -ti laf_tools_1 /bin/bash
  5. 즐기세요!

pgAdmin 데이터베이스 연결

pgAdmin을 사용하여 DB의 데이터를 확인할 수 있습니다:

먼저, pgAdmin에 접속합니다:

  • URL: http://localhost:5001
  • 사용자: pgadmin
  • 비밀번호: pgadmin

그런 다음, 서버를 추가해야 합니다:

  • 호스트: db
  • 포트: 5432
  • 사용자: postgres
  • 비밀번호: postgres

도구 설명

다음은 디렉토리와 그 안에 있는 도구/기능에 대한 설명입니다.

/tools

이 디렉토리에 제공된 도구의 주요 목적은 LoRaWAN 인프라에 대한 침투 테스트 실행을 용이하게 하는 것입니다.

UdpSender.py

이 도구는 업링크 패킷(인프라에 따라 네트워크 서버 또는 게이트웨이 브리지로) 또는 다운링크 패킷(패킷-포워더로)을 전송하기 위한 것입니다. 선택적으로 패킷을 퍼징하거나 유효한 MIC를 계산할 수 있습니다.

선택적 인수:

root@kitploit:~
-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에서는 작동하지 않습니다.

필수 인수:

root@kitploit:~
--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를 무작위로 퍼징합니다:

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

이 UDP 프록시는 주로 평가 중인 인프라에 따라 여러 게이트웨이(packet_forwarders)와 네트워크 서버 또는 게이트웨이 브리지 사이에 배치되도록 설계되었습니다. 또한 원하는 방향(업링크 또는 다운링크)으로 데이터 퍼징 기능을 제공합니다.

선택적 인수:

root@kitploit:~
-h, --help            도움말 메시지를 표시하고 종료합니다.
--collector-port COLLECTOR_PORT
                        패킷 포워더 데이터 수집기 포트, 예: --collector-
                        port 1701. 자세한 내용은
                        auditing/datacollectors/PacketForwarderCollector.py를 참조하세요.
--collector-ip COLLECTOR_IP
                        패킷 포워더 데이터 수집기 IP. 기본값은
                        localhost입니다. 예: --collector-ip 192.168.1.1. 자세한 내용은
                        auditing/datacollectors/PacketForwarderCollector.py를 참조하세요.
--fuzz-in FUZZ_IN [FUZZ_IN ...]
                        대상 포트로 전송되는 데이터를 주어진 모드로 퍼징합니다(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를 입력합니다(16진수 형식, 총 32자
                        / 16바이트)로 FRMPayload를 복호화하고
                        일반 텍스트로 출력합니다. 또한 Join Accept를 복호화하려면
                        AppKey를 입력할 수도 있습니다. 예:
                        00112233445566778899AABBCCDDEEFF
-p PATH, --path PATH  데이터를 저장할 파일 경로. 제공되지 않으면
                        데이터가 저장되지 않습니다.
--no-log              UDP 패키지를 콘솔에 출력하지 않습니다.
--no-parse            PHYPayload를 구문 분석하지 않습니다. 이 옵션을 선택하면
                        /lorawanwrapper/의 Golang 라이브러리를 가져오지 않습니다(golang
                        라이브러리 컴파일이 필요하지 않습니다).
                    

필수 인수:

root@kitploit:~
--port PORT           수신할 로컬 포트, 예: --port 623.
--dst-ip DST_IP       대상 호스트 IP, 예: --dst-ip 192.168.3.101.
--dst-port DST_PORT   대상 호스트 포트, 예: --dst-port 623.

예제:

포트 1234에서 수신된 패킷을 (localhost, 1235)로 보내고 그 반대로 보냅니다. 포트에서 수신된 패킷은 퍼징(devNonce가 무작위로 변경됨)된 후 (localhost, 1235)로 전달됩니다.

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

TcpProxy.py

이 TCP 프록시는 주로 네트워크 서버와 MQTT 브로커 사이에 배치되도록 설계되었습니다. 또한 데이터 퍼징 기능을 제공합니다.

선택적 인수:

root@kitploit:~
-h, --help            도움말 메시지를 표시하고 종료합니다.
--fuzz-in FUZZ_IN [FUZZ_IN ...]
                    대상 포트로 전송되는 데이터를 주어진 모드로 퍼징합니다(utils/fuzzer.py의 퍼징 모드 참조).

필수 인수:

root@kitploit:~
--lcl-port LCL_PORT   수신할 로컬 포트, 예: --lcl-port=623.
--dst-ip DST_IP       대상 호스트 IP, 예: --dst-ip=192.168.3.101.
--dst-port DST_PORT   대상 호스트 포트, 예: --dst-port=623.

예제:

(localhost, 1884)와 (localhost, 1883) 간에 데이터를 송수신합니다.

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

tools/lorawan

이 디렉토리에는 LoRaWAN 패킷을 구문 분석, 조작, 무차별 대입 등 하는 스크립트 시리즈가 포함되어 있습니다.

lorawan/BruteForcer.py

이 스크립트는 Base64 형식의 JoinAccept 또는 JoinRequest를 받아 파일로 제공되거나 즉석에서 생성될 수 있는 가능한 키 세트를 사용하여 AppKey를 복호화하려고 시도합니다.

선택적 인수:

root@kitploit:~
-h, --help            도움말 메시지를 표시하고 종료합니다.
-k KEYS, --keys KEYS  키 목록을 포함하는 파일(줄바꿈으로 구분). 기본값은
                        /auditing/analyzers/bruteForcer/keys.txt를 사용합니다.
--dont-generate       이 옵션을 선택하면 다음 조합으로 키를 즉석에서 생성하지 않습니다:
                        1- 첫 번째 바이트와 마지막 15바이트를 결합합니다. 예:
                        AABBBBBBBBBBBBBBBBBBBBBBBBBBBBBB 2- 짝수 및 홀수
                        바이트 위치를 동일하게 결합합니다. 예:
                        AABBAABBAABBAABBAABBAABBAABBAABB 3- 처음 14바이트를
                        00으로 설정하고 마지막 2바이트를 결합합니다. 예:
                        0000000000000000000000000000BA01

필수 인수:

root@kitploit:~
-a ACCEPT, --accept ACCEPT
                무차별 대입할 Base64 형식의 Join Accept. 예: -a
                IHvAP4MXo5Qo6tdV+Yfk08o=
-r REQUEST, --request REQUEST
                무차별 대입할 Base64 형식의 Join Request. 예:
                -r AMQAAAAAhQAAAgAAAAAAAADcYldcgbc=

예제:

my-keys.txt의 키 세트로 JoinRequest를 크랙하고 동적으로 약 200,000개를 더 생성합니다.

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

이 스크립트는 Base64 형식의 PHYPayload 패킷과 패킷 유형에 따라 NwkSKey 또는 AppKey가 될 수 있는 키를 받아 새 MIC를 생성합니다.

선택적 인수:

root@kitploit:~
-h, --help            도움말 메시지를 표시하고 종료합니다.
--jakey JAKEY         [JoinAccept ONLY]. 이전에 JoinAccept를 암호화하는 데 사용된 키를 입력합니다(16진수 형식, 총 32자
                        / 16바이트). 이는 이 프로그램에서 사전에
                        검증할 수 없습니다. 예:
                        00112233445566778899AABBCCDDEEFF. JoinAccept "IB1scNmwJRA32RfMbvwe3oI="에 대한
                        유효한 키 샘플은 "f5a3b185dfe452c8edca3499abcd0341"입니다.

필수 인수:

root@kitploit:~
-d DATA, --data DATA  서명할 Base64 데이터. 예: -d
                        AE0jb3GsOdJVAwD1HInrJ7i3yXAFxKU=
-k KEY, --key KEY     패킷에 서명할 새 키를 입력합니다(16진수 형식, 총 32자
                        / 16바이트). JoinRequest/JoinAccept의 경우
                        AppKey여야 하며, 데이터 패킷의 경우 NwkSKey여야 합니다.
                        이는 이 프로그램에서 사전에 검증할 수 없습니다. 예:
                        00112233445566778899AABBCCDDEEFF

예제:

주어진 PHYPayload를 AppKey 00112233445566778899AABBCCDDEEFF로 서명합니다.

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

이 스크립트는 lorawan JSON 패킷을 받아 Base64로 변환합니다. packetParser.py의 역을 수행하므로 해당 스크립트의 출력을 여기서 사용할 수 있고 그 반대도 마찬가지입니다.

선택적 인수:

root@kitploit:~
-h, --help            도움말 메시지를 표시하고 종료합니다.
-k KEY, --key KEY     FRMPayload 또는 Join Accept를 암호화할 장치 AppSKey 또는 AppKey를 입력합니다(16진수 형식, 총
                        32자 / 16바이트). 예:
                        F5A3B185DFE452C8EDCA3499ABCD0341
--nwkskey NWKSKEY     유효한 MIC로 데이터 패킷을 생성하려면 네트워크 세션 키를 입력합니다.

필수 인수:

root@kitploit:~
-j JSON, --json JSON  구문 분석할 JSON 객체. 예: -j '{"mhdr":
                        {"mType":"JoinRequest","major":"LoRaWANR1"},"macPayloa
                        d":{"joinEUI":"55d239ac716f234d","devEUI":"b827eb891cf
                        50003","devNonce":51639},"mic":"7005c4a5"}'

예제:

JSON에 전달된 값을 사용하여 JoinRequest PHYPayload를 Base64로 얻습니다.

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

이 스크립트는 Base64 형식의 단일 LoRaWAN PHYPayload 데이터를 구문 분석하고 출력합니다. packetCrafter.py의 역을 수행하므로 해당 스크립트의 출력을 여기서 사용할 수 있고 그 반대도 마찬가지입니다.

선택적 인수:

root@kitploit:~
-h, --help            도움말 메시지를 표시하고 종료합니다.
-k KEY, --key KEY     복호화할 패킷(join accept 또는 데이터 패킷)에 따라 장치 AppKey 또는 AppSKey를 입력합니다.
                        16진수 형식이어야 하며, 총 32자 / 16바이트입니다. 예:
                        00112233445566778899AABBCCDDEEFF

필수 인수:

root@kitploit:~
-d DATA, --data DATA  구문 분석할 Base64 데이터. 예: -d
                    AE0jb3GsOdJVAwD1HInrJ7i3yXAFxKU=

예제:

위 예제의 JoinRequest를 JSON 형식으로 얻습니다.

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

이 스크립트는 Base64 형식의 JoinAccept와 JoinRequest, 그리고 AppKey를 받아 세션 키를 생성합니다. 사용 예:

선택적 인수:

root@kitploit:~
-h, --help            도움말 메시지를 표시하고 종료합니다.

필수 인수:

root@kitploit:~
-a JACCEPT, --jaccept JACCEPT
                    base64 형식의 JoinAccept 페이로드
-r JREQUEST, --jrequest JREQUEST
                    base64 형식의 JoinRequest 페이로드
-k KEY, --key KEY     장치 AppKey를 입력합니다(16진수 형식, 총 32자
                    / 16바이트). 예:
                    00112233445566778899AABBCCDDEEFF

예제:

다음 조인 데이터로 AppSKey와 NwkSKey를 얻습니다.

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

이것들은 UdpSender.py와 UdpProxy.py에서 사용되는 보조 함수입니다. Fuzzer.py에서 구현된 퍼징 모드를 볼 수 있습니다.

/auditing

이 디렉토리의 일반적인 목적은 LoRaWAN 패킷을 수집하고 트래픽의 다양한 측면을 분석하며, AppKey를 무차별 대입하려는 키 세트를 시도하는 것입니다.

/auditing/datacollectors

이 디렉토리에는 다양한 소스(예: 게이트웨이 packet_forwarder, The Things Network 등)에서 LoRaWAN 패킷을 수신하고 표준 형식으로 파일에 저장하는 스크립트 세트가 포함되어 있습니다. 이 파일들은 나중에 하위 도구를 실행하기 위해 스크립트 /auditing/analyzers/LafProcessData.py에 의해 가져와야 합니다.

datacollectors/GenericMqttCollector.py

이 스크립트는 MQTT 브로커에 연결하고 모든 토픽을 검색하며 메시지를 지정된 필드의 파일에 저장합니다. 파일 이름은 이 스크립트가 시작된 날짜로 구성됩니다.

선택적 인수:-h, --help 이 도움말 메시지를 표시하고 종료합니다. --collector-id COLLECTOR_ID 데이터 수집기의 ID입니다. 이 ID는 DB에 저장된 패킷과 연결됩니다. 예: --id 1 --organization-id ORGANIZATION_ID 데이터 수집기의 ID입니다. 이 ID는 DB에 저장된 패킷과 연결됩니다. 예: --id 1 --topics TOPICS [TOPICS ...] 공백으로 구분하여 구독할 토픽 목록을 입력합니다. 아무것도 입력하지 않으면 기본값은 "#"입니다.

필수 인수:

root@kitploit:~
--ip IP               MQTT 브로커 IP, 예: --ip 192.168.3.101.
--port PORT           MQTT 브로커 포트, 예: --port 623.

예시:

IP 200.200.200.200, 기본 포트(1883)의 MQTT 브로커에 연결합니다.

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

이 스크립트는 loraserver.io MQTT 브로커에 연결하여 메시지를 DB에 저장합니다. 고유한 collectorID를 지정해야 하며, 구독할 토픽을 지정할 수 있습니다.

선택적 인수:

root@kitploit:~
-h, --help            이 도움말 메시지를 표시하고 종료합니다.
--port PORT           MQTT 브로커 포트, 예: --port 623. 기본값은 1883입니다.
--collector-id COLLECTOR_ID
                        데이터 수집기의 ID입니다. 이 ID는 DB에 저장된 패킷과 연결됩니다. 예: --id 1
--organization-id ORGANIZATION_ID
                        데이터 수집기의 ID입니다. 이 ID는 DB에 저장된 패킷과 연결됩니다. 예: --id 1
--topics TOPICS [TOPICS ...]
                        공백으로 구분하여 구독할 토픽 목록을 입력합니다. 아무것도 입력하지 않으면 기본값은 "#"입니다.

필수 인수:

root@kitploit:~
--ip IP               MQTT 브로커 IP, 예: --ip 192.168.3.101.
datacollectors/PacketForwarderCollector.py

이 스크립트는 게이트웨이의 packet_forwarder 형식으로 UDP 프록시로부터 UDP 패킷을 수신하여 저장합니다.

선택적 인수:

root@kitploit:~
-h, --help            이 도움말 메시지를 표시하고 종료합니다.
--collector-id COLLECTOR_ID
                        데이터 수집기의 ID입니다. 이 ID는 DB에 저장된 패킷과 연결됩니다. 예: --id 1
--organization-id ORGANIZATION_ID
                        데이터 수집기의 ID입니다. 이 ID는 DB에 저장된 패킷과 연결됩니다. 예: --id 1

필수 인수:

root@kitploit:~
-n NAME, --name NAME  데이터 수집기의 고유 문자열 식별자입니다. 예: --name semtech_collector
-p PORT, --port PORT  UDP 패킷을 수신할 포트입니다. --port 1702.

예시:

게이트웨이(로컬 포트 1700으로 전송)와 네트워크 xserver(로컬호스트, 1701에서 수신) 간의 데이터를 기록합니다. 데이터를 ./ 디렉터리에 저장합니다.

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

analyzers/LafProcessData.py

이 스크립트는 파일이나 파일들 또는 stdin에서 데이터를 읽고 다양한 하위 도구를 실행합니다. 선택한 옵션에 따라 LoRaWAN 트래픽 분석, AppKey 무차별 대입 시도, 또는 수신된 모든 패킷 구문 분석을 실행할 수 있습니다. 이러한 옵션은 결합할 수 있습니다.

선택적 인수:

root@kitploit:~
이 스크립트는 DB에서 패킷을 검색하고 다양한 하위 도구를 실행합니다.
그런 다음 각 하위 도구는 출력 데이터를 DB에 저장합니다. 자세한 내용은 각 옵션을 참조하십시오.

선택적 인수:
  -h, --help            이 도움말 메시지를 표시하고 종료합니다.
  -a, --analyze         트래픽의 다양한 측면을 수집하고 분석합니다.
			무차별 대입기(-b)가 활성화된 경우 결과가 상호 연관됩니다.
  -b, --bforce          JoinRequest 및 JoinAccepts 페이로드를 사용하여 AppKey를 무차별 대입합니다.
  -k KEYS, --keys KEYS  [무차별 대입기] 키 파일의 경로입니다. 제공되지 않으면
			"bruteForcer/keys.txt"가 사용됩니다.
  --no-gen              [무차별 대입기] 키를 생성하지 않고 파일의 키만 시도합니다.
  -p, --parse           PHYPayload를 읽을 수 있는 정보로 구문 분석합니다.
  --from-id FROM_ID     처리를 시작할 패킷 ID입니다.
  --to-id TO_ID         처리할 마지막 패킷 ID입니다.

예시:

DB에서 패킷 ID 1000부터 시작하여 패킷을 처리하고, 트래픽 분석을 실행하며, my-keys.txt에 제공된 AppKey를 크랙하려고 시도하지만 동적으로 더 많은 키를 생성하지 않습니다.

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

이 스크립트들은 LafProcessData.py에 의해 조정되는 기능을 제공합니다. 아래는 LafPacketAnalysis.py 및 LafBruteForcer.py에 의해 구현된 경보 목록입니다:

/lorawanwrapper

이 디렉토리는 Golang으로 작성된 라이브러리 https://github.com/brocaar/lorawan/에 대한 래퍼 세트를 제공합니다. 이러한 함수들은 도구에 의해 구현됩니다.

/scripts

여기에는 다양한 작업을 자동화하기 위한 스크립트 시리즈가 있습니다. 필요한 경우 실행 권한을 부여하십시오(Linux/MacOS의 경우 chmod +x your_script).

/scripts/lorawan_gateway_scripts

게이트웨이를 쉽게 설정하고 스니핑 목적으로 채널을 전환합니다. 사용 방법에 대한 자세한 내용은 이 디렉토리의 readme를 참조하십시오.

gateway_channel_changer/LoRa-GW-Installer.sh

이 스크립트는 Raspberry PI에 연결된 LoRa 집중기(iC980-SPI, RHF0M301-SPI, RAK831-SPI 또는 수동 설정으로 다른 것)와 함께 LoRaWAN 게이트웨이를 구축하기 위해 필요한 모든 소프트웨어 패키지를 설치하는 데 사용됩니다.

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

LoRa 장치가 어떤 주파수에서 작동하는지 알 수 없기 때문에, 스니핑 목적으로 US915 및 EU868 주파수 대역의 게이트웨이 채널을 전환할 수 있는 스크립트를 만들었습니다. 32개 또는 64개 채널을 지원하는 전문적이고 비싼 게이트웨이가 있지만, 대부분의 게이트웨이는 최대 8개 채널을 지원합니다. 이 스크립트는 이러한 종류의 게이트웨이에서 실행되도록 설계되었습니다.

적어도 US915 주파수 대역에서는 처음 8개 채널이 가장 많이 사용됩니다. 그러나 The Things Networks와 같이 업링크 통신에 두 번째 그룹(8-15)의 채널을 사용하는 잘 알려진 구현도 있습니다.

현재 다른 주파수 대역은 지원하지 않지만, 이 스크립트를 약간만 수정하면 직접 할 수 있을 것입니다 :).

데모 동영상이 프레임워크의 실제 동작 영상을 업로드했습니다 (BlackHat 2019에서 발표된 시나리오와 동일): https://youtu.be/Mm6A2RVNoCs. 데모의 자세한 단계는 Youtube 동영상 설명에 나와 있습니다.

저자

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

기여자

  • Sebastian Scheibe - scripts/lorawan_gateway_scripts 스크립트로 기여 - sebascheibe

기여하기

TODO

감사의 말

  • Python용 MQTT 클라이언트: https://github.com/iwanbk/nyamuk/
  • Golang으로 작성된 LoRaWAN 라이브러리: https://github.com/brocaar/lorawan/
  • Golang의 JSON 처리 함수 https://github.com/tidwall/sjson 및 https://github.com/tidwall/gjson
  • tcpProxy의 기반: https://gist.github.com/voorloopnul/415cb75a3e4f766dc590
  • Loracrack: 원본 저장소를 포크하고 수정함 https://github.com/applied-risk/Loracrack

라이선스

이 프로젝트는 BSD-3-Clause 라이선스에 따라 라이선스가 부여됩니다.

도구 다운로드
  • 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
  • 사용하려는 DB에 따라:

    a. PostgreSQL: 'Docker를 사용하여 LAF 설치'의 3단계까지 따릅니다.

    b. SQLite:

    1. cd laf/auditing/db
    2. 선호하는 텍스트 편집기로 __init__.py를 열고 Postgres에 사용할 줄(DB 연결 및 환경 변수)을 주석 처리하고 sqlite에 사용할 줄을 주석 해제합니다.
  • ID제목분석기위험 수준설명권장 조치
    LAF-001DevNonce 반복LafPacketAnalysis.py낮음각 장치의 DevNonce는 충돌하지 않을 만큼 무작위여야 합니다. 동일한 DevNonce가 여러 메시지에서 반복된다면, 장치가 재생 공격을 받고 있다고 추론할 수 있습니다. 즉, 공격자가 JoinRequest를 캡처하여 게이트웨이에 다시 보내려고 하는 것입니다.DevNonce 생성 방식을 확인하십시오. DevNonce를 생성하는 함수는 무작위 라이브러리를 사용하여 구현되어야 합니다. 또한, 서버가 이전 DevNonce를 확인하도록(DB에 저장되어 있어야 함) 하여 이전에 장치가 보낸 유효한 JoinRequest를 수락하지 않고 새 세션을 생성하지 않도록 해야 합니다.
    LAF-002동일한 DevAddr을 공유하는 DevEUILafPacketAnalysis.py정보두 개의 다른 장치에 동일한 DevAddr이 할당되었을 수 있습니다. 이는 보안 위협이 아닙니다.OTA(Over the Air Activation) 장치: DevAddr 할당에 사용된 로직을 확인하고 서버가 다른 장치에 동일한 DevAddr을 할당하지 않도록 하십시오. ABP(Activation by Personalization) 장치: 장치 펌웨어에 구성된 DevAddr이 LoRaWAN 네트워크에서 고유한지 확인하십시오.
    LAF-003조인 재생TODO중간중복된 조인 요청 패킷이 감지되었습니다. 이는 LoRaWAN 서버가 재생 공격을 받고 있음을 의미할 수 있습니다. 즉, 공격자가 이전의 조인 요청 패킷을 캡처하여 새 세션을 생성하기 위해 LoRaWAN 서버에 다시 보내는 것입니다.DevNonce 생성 방식을 확인하십시오. DevNonce를 생성하는 함수는 무작위 라이브러리를 사용하여 구현되어야 합니다. 또한, 서버가 이전 DevNonce를 확인하도록(DB에 저장되어 있어야 함) 하여 이전에 장치가 보낸 유효한 JoinRequest를 수락하지 않고 새 세션을 생성하지 않도록 해야 합니다.
    LAF-004업링크 데이터 패킷 재생TODO중간중복된 업링크 패킷이 감지되었습니다. 이는 LoRaWAN 서버가 재생 공격을 받고 있음을 의미할 수 있습니다. 즉, 공격자가 (장치에서 보낸) 업링크 패킷을 캡처하여 LoRaWAN 서버에 다시 보내는 것입니다.OTA(Over the Air Activation) 장치: 장치 재설정 또는 카운터 오버플로우 후 세션 키가 다시 생성되어 이 공격의 영향을 방지하도록 하십시오. LoRaWAN v1.0.*의 ABP(Activation by Personalization) 장치의 경우, 장치를 OTAA로 전환하는 것 외에는 재생 공격을 방지할 수 있는 방법이 없습니다.
    LAF-005다운링크 데이터 패킷 재생TODO높음중복된 다운링크 패킷이 감지되었습니다. 서버가 재생 공격에 응답하거나 장치에 비정상적인 트래픽을 생성하고 있습니다.서버 로그를 확인하고 이전 권장 조치가 구현되었는지 확인하십시오.
    LAF-006가능한 ABP 장치(카운터 재설정 및 조인 없음)LafPacketAnalysis.py높음카운터가 재설정(0으로 돌아감)되었고 DevAddr이 동일하게 유지되며 이전 조인 프로세스가 감지되지 않은 경우, 장치가 ABP(Activation by Personalization)로 활성화되었음을 의미할 수 있습니다. ABP 장치 구현은 조인 프로세스가 수행되지 않아 세션 키가 영원히 동일하게 유지되므로 권장되지 않습니다. 세션 키를 변경하지 않는 장치는 도청 또는 재생과 같은 다양한 공격에 취약합니다.가능한 경우 모든 ABP(Activation by Personalization) 장치는 OTA(Over the Air Activation) 장치로 교체되어야 합니다. ABP 장치의 구현은 권장되지 않습니다.
    LAF-007예상보다 작은 카운터 수신(0과 다름)LafPacketAnalysis.py중간공격자가 (OTAA 장치의 AppKey 또는 ABP 장치의 AppSKey/NwkSKey를 도용하여) 세션 키 쌍을 획득한 경우, 서버에 가짜 유효 데이터를 보낼 수 있습니다. 서버가 위조된 메시지를 수락하려면 메시지의 FCnt(프레임 카운터)가 마지막으로 보낸 메시지의 FCnt보다 높아야 합니다. 원래 위조된 장치가 계속 메시지를 보내는 시나리오에서는 서버가 더 작은 FCnt를 가지므로 (유효한) 메시지를 폐기하기 시작합니다. 따라서 LoRaWAN 서버가 예상한 것보다 작은 FCnt 값을 가진 메시지가 수신될 때, 병렬 세션이 설정되었음을 추론할 수 있습니다.OTA(Over the Air Activation) 장치인 경우, AppKey가 손상되었을 가능성이 있으므로 변경하십시오. ABP(Activation by Personalization) 장치인 경우 AppSKey 및 NwkSKey를 변경하십시오. 또한 LoRaWAN 서버가 업데이트되었고 중복 메시지를 수락하지 않는지 확인하십시오.
    LAF-008JoinRequest로 비밀번호 크랙됨LafBruteforcer.py높음알려진 AppKey를 사용하여 JoinRequest 메시지를 해독할 수 있었습니다.공급업체가 제공한 것과 다른 AppKey를 사용하거나 더 무작위적인 키를 사용하십시오.
    LAF-009비밀번호 크랙됨LafBruteforcer.py높음잘 알려졌거나 무작위가 아닌 문자열로 시도하여 장치의 AppKey를 찾았습니다. 한 쌍의 조인 메시지(Request 및 Accept)를 사용하여 해독되었습니다.공급업체가 제공한 키 대신 AppKey에 무작위 키 생성기를 사용하십시오. 또한 둘 이상의 장치에 동일한 AppKey를 설정하지 말고 예측 가능한 로직(예: 증가 값, 특정 바이트 뒤집기 등)을 사용하여 AppKey를 생성하지 마십시오.
    LAF-010게이트웨이 위치 변경LafPacketAnalysis.py중간게이트웨이가 위치를 변경하지 않아야 하는 경우입니다. 도난, 이동되었거나, 가짜 게이트웨이가 합법적인 게이트웨이를 사칭하려고 할 수 있습니다.게이트웨이가 물리적으로나 논리적으로 변조되지 않았는지 확인하십시오.