تستمر عمليات نشر إنترنت الأشياء في النمو ، ويتألف جزء واحد من هذا النمو الهام من ملايين أجهزة استشعار LPWAN (شبكة منخفضة الطاقة) المنتشرة في مئات المدن (المدن الذكية) في جميع أنحاء العالم ، وأيضًا في الصناعات والمنازل. واحدة من أكثر تقنيات LPWAN المستخدمة هي Lora التي تعتبر Lorawan معيار الشبكة (طبقة MAC). 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
نحن نقدم خيارات مختلفة للحصول على إطار عمل لوروان وتشغيله:
tools/ DIR ، لتجنب مشاكل رسم خرائط منفذ Docker.localhost . انظر التعليمات أدناه لإعداد Docker.سوف تحصل هذه التعليمات على نسخة من المشروع وتبعياته في الجهاز المحلي الخاص بك. الأوامر أدناه مخصصة لبيئة تعتمد على دبيان:
استنساخ هذا المستودع: 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 والبيئة
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اعتمادًا على ديسيبل ترغب في استخدامه:
أ. POSTRESQL: اتبع الإرشادات "تثبيت LAF باستخدام Docker" حتى الخطوة الثالثة.
ب. 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يمكنك التحقق من البيانات في DB باستخدام pgadmin:
أولاً ، الوصول إلى pgadmin:
ثم ، تحتاج إلى إضافة الخادم:
فيما يلي وصف للأدلة والأدوات / الوظيفة بداخلها.
الغرض الرئيسي من الأدوات المقدمة في هذا الدليل هو تخفيف تنفيذ اختبار الاختراق إلى بنية تحتية لوروان.
تهدف هذه الأداة إلى إرسال حزم الوصلة الصاعدة (إلى خادم الشبكة أو GatewayBridge ، اعتمادًا على البنية التحتية) أو حزم الوصلة الهابطة (إلى الحزمة الموضحة). اختياريا ، يمكن أن تكون الحزم مغمورة ويمكن حساب ميكروفون صالح.
الحجج الاختيارية:
-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}'"
مثال:
لإرسال حزمة واحدة كل ثانيتين إلى (LocalHost ، 10001) من Port 10000 fuzzing بشكل عشوائي الميكروفون و fcounter:
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) وخادم الشبكة أو جسر البوابة اعتمادًا على الإدماج الذي يتم تقييمه. كما أنه يوفر إمكانية التفسير لبيانات Fuzz في الاتجاه المطلوب (الوصلة الصاعدة أو الوصلة الهابطة)
الحجج الاختيارية:
-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 ، إلخ.
يتلقى هذا البرنامج النصي JoinAccept أو JoinRequest في Base64 ويحاول فك تشفير 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=
مثال:
crack a joinrequest مع مجموعة من المفاتيح من my-keys.txt وكذلك إنشاء aprox. 200000 أكثر ديناميا.
python3 BruteForcer.py -a IHvAP4MXo5Qo6tdV+Yfk08o= -r AMQAAAAAhQAAAgAAAAAAAADcYldcgbc= -k ./my-keys.txt
تتلقى هذه البرامج النصية حزمة phypayload في base64 ومفتاح يمكن أن يكون nwkskey من appkey اعتمادا على نوع الحزمة وينشئ الميكروفون الجديد.
الحجج الاختيارية:
-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
مثال:
قم بتوقيع phypayload المعطى مع AppKey 00112233445566778999aabbccddeeff.
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"}'
مثال:
احصل على حمولة حجرية في BASE64 مع تقديمها في JSON مع تمرير القيم فيه.
python3 PacketCrafter.py -j '{"mhdr":{"mType":"JoinRequest","major":"LoRaWANR1"},"macPayload":{"joinEUI":"55d239ac716f234d","devEUI":"b827eb891cf50003","devNonce":51639},"mic":"7005c4a5"}'
هذا البرنامج النصي يطبع ويطبع بيانات تحميل لوروان واحدة في BASE64. إنه يعكس مثل 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=
مثال:
الحصول على JoinRequest في تنسيق JSON من المثال أعلاه.
python3 PacketParser.py -d AE0jb3GsOdJVAwD1HInrJ7i3yXAFxKU=
يتلقى هذا البرنامج النصي JoinAccept و JoinRequest في Base64 ، و 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.
يحتوي هذا الدليل على مجموعة من البرامج النصية التي تتلقى حزم Lorawan من مصادر مختلفة (IE Gateway Packet_Forwarder ، شبكة الأشياء ، وما إلى ذلك) وحفظها في ملفات ، بتنسيق قياسي. يجب أن يتم جلب هذه الملفات لاحقًا بواسطة البرنامج النصي /auditing/analyzers/LafProcessData.py /lafprocessdata.py لتنفيذ الأدوات الفرعية المختلفة.
يتصل هذا البرنامج النصي إلى وسيط 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.
مثال:
اتصل بـ MQTT الوسيط بـ IP 200.200.200.200 في المنفذ الافتراضي (1883).
python3 GenericMqttCollector.py --ip 200.200.200.200 --port 1883
يتصل هذا البرنامج النصي إلى وسيط loraserver.io mqqt ويحفظ الرسائل في DB. يجب عليك تحديد مجموعة فريدة من نوعها ويمكنك تحديد الموضوعات التي تريد أن تنضج عليها.
الحجج الاختيارية:
-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.
يتلقى هذا البرنامج النصي حزم UDP من وكيل UDP في تنسيق Gateway Packet_Forwarder ويستمر عليها.
الحجج الاختيارية:
-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 وينفذ الأدوات الفرعية المختلفة. اعتمادًا على الخيار المحدد ، يمكنك تنفيذ تحليل لحركة Lorawan ، ومحاولة Bruteforce 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.
مثال:
حزم المعالجة في DB بدءًا من معرف الحزمة 1000 ، وقم بتنفيذ تحليل حركة المرور ، وحاول كسر Appkeys الواردة في my-keys.txt ، ولكن لا تولد المزيد من المفاتيح.
python3 LafProcessData.py -a -b -k my-keys.txt --no-gen --from-id 1000
توفر هذه البرامج النصية الوظائف التي تفرخها LaFprocessData.py. أدناه ، التنبيهات التي يتم تنفيذها بواسطة LafPacketAnalysis.py و LafBruteForcer.py :
| بطاقة تعريف | عنوان | محلل | مستوى المخاطر | وصف | الإجراء الموصى به |
|---|---|---|---|---|---|
| LAF-001 | تكرار Devnonce | lafpacketanalysis.py | قليل | يجب أن يكون Devnonces لكل جهاز عشوائيًا بما يكفي لعدم تصادمه. إذا تم تكرار نفس devnonce في العديد من الرسائل ، فيمكن استنتاج أن الجهاز يتعرض لهجوم إعادة. هذا ، مهاجم استولى على حجارة ويحاول إرساله مرة أخرى إلى البوابة. | تحقق من كيفية إنشاء devnonces: يجب تنفيذ الوظيفة التي تنشئها باستخدام مكتبة عشوائية. علاوة على ذلك ، يجب عليك التأكد من أن الخادم يتحقق من devnonces التاريخية (يجب أن تستمر في DB) ، حتى لا تقبل حجارة قديمة صالحة تم إرسالها مسبقًا بواسطة الجهاز وبالتالي إنشاء جلسة جديدة. |
| LAF-002 | deveuis يشارك نفس devaddr | lafpacketanalysis.py | معلومات | ربما تم تعيين جهازين مختلفين نفس Devaddr. هذا ليس تهديدًا أمنيًا. | إذا كان الجهاز قد انتهى من الهواء (OTAA): تحقق من المنطق المستخدم لتعيين devaddrs ، وتأكد من أن الخادم لا يعين نفس devaddr لأجهزة مختلفة. إذا تم تنشيط الجهاز بواسطة التخصيص (ABP): تحقق من أن Devaddr المكونة في البرامج الثابتة للجهاز فريدة من نوعها في شبكة Lorawan. |
| LAF-003 | انضم إلى إعادة التشغيل | تودو | واسطة | تم الكشف عن حزمة طلب انضمام مكررة ، مما قد يعني ضمناً أن خادم لوراوان يتعرض لهجوم لإعادة التشغيل. هذا ، مهاجم قد يكون قد حصل على حزمة طلب صلة سابقة ويرسلها مرة أخرى إلى خادم Lorawan ، لمحاولة إنشاء جلسة جديدة. | تحقق من كيفية إنشاء devnonces: يجب تنفيذ الوظيفة التي تنشئها باستخدام مكتبة عشوائية. علاوة على ذلك ، يجب عليك التأكد من أن الخادم يتحقق من devnonces التاريخية (يجب أن تستمر في DB) ، حتى لا تقبل حجارة قديمة صالحة تم إرسالها مسبقًا بواسطة الجهاز وبالتالي إنشاء جلسة جديدة. |
| LAF-004 | إعادة تشغيل حزم البيانات الصاعدة | تودو | واسطة | تم اكتشاف حزمة الوصلة الصاعدة المكررة ، مما قد يعني ضمناً أن خادم Lorawan يتعرض لهجوم إعادة. هذا ، مهاجم قد يكون قد استحوذ على حزمة الوصلة الصاعدة (تم إرسالها من الجهاز) ويرسلها مرة أخرى إلى خادم Lorawan. | في أجهزة Air Air (OTAA) التي تم تنشيطها (OTAA): تأكد من إعادة توليد مفاتيح الجلسة بعد كل إعادة تعيين الجهاز أو فيضان مضاد لتجنب أي تأثير من هذا الهجوم. مع تنشيط أجهزة التخصيص (ABP) من Lorawan v1.0.*، لا يمكن القيام بأي شيء لمنع هجوم إعادة التشغيل إلا من تحويل الجهاز إلى OTAA. |
| LAF-005 | إعادة تشغيل حزم بيانات الوصلة الهابطة | تودو | عالي | تم اكتشاف حزمة الوصلة الهابطة المكررة. يستجيب الخادم لهجوم إعادة التشغيل أو يولد حركة مرور غير نمطية للأجهزة | تحقق من سجلات الخوادم وتحقق من تنفيذ الإجراءات السابقة الموصى بها |
| LAF-006 | جهاز ABP ممكن (إعادة تعيين مضاد ولا ينضم) | lafpacketanalysis.py | عالي | إذا تمت إعادة تعيين العداد (عاد إلى 0) ، يتم الاحتفاظ Devaddr كما هو ، ولم يتم اكتشاف أي عملية انضمام سابقة ، فقد تشير إلى أن الجهاز يتم تنشيطه عن طريق التخصيص (ABP). يتم تثبيط تنفيذ أجهزة ABP لأنه لا توجد عملية انضمام ، مما يعني أن مفاتيح الجلسة هي نفسها إلى الأبد. الجهاز الذي لا يغير مفاتيح الجلسة عرضة لهجمات مختلفة مثل eaveasdrop أو إعادة التشغيل. | يجب استبدال جميع أجهزة التخصيص بواسطة التخصيص (ABP) لأجهزة Air Air (OTAA) المنشطة إذا كان ذلك ممكنًا. يتم تثبيط تنفيذ أجهزة ABP. |
| LAF-007 | تلقي عداد أصغر من المتوقع (متميز عن 0) | lafpacketanalysis.py | واسطة | إذا حصل المهاجم على زوج من مفاتيح الجلسة (لسرقتها في Appkey في أجهزة OTAA أو AppSkey/Nwkskey في أجهزة ABP) ، فسيكون قادرًا على إرسال بيانات صالحة مزيفة إلى الخادم. لكي يقبل الخادم الرسائل المحوزة ، يجب أن تكون FCNT (عداد الإطار) للرسالة أعلى من FCNT للرسالة الأخيرة المرسلة. في السيناريو الذي يستمر فيه الجهاز الأصلي في إرسال الرسائل ، سيبدأ الخادم في التخلص من الرسائل (صالحة) لأنه سيكون لديهم FCNT أصغر. وبالتالي ، عندما يتم استلام الرسائل ذات قيمة FCNT أصغر مما كان متوقعًا بواسطة خادم Lorawan ، فمن الممكن أن نستنتج أن جلسة موازية تم إنشاؤها. | إذا كان الجهاز فوق الجهاز المنشط للهواء (OTAA) ، فقم بتغيير appkey لأنه قد تعرض للخطر. إذا تم تنشيطه عن طريق التخصيص ، فقم بتغيير AppSkey و Nwkskey. علاوة على ذلك ، تأكد من تحديث خادم Lorawan ولا يقبل الرسائل المكررة. |
| LAF-008 | كلمة المرور متشققة مع JoinRequest | lafbruteforcer.py | عالي | كان من الممكن فك تشفير رسالة JoinRequest باستخدام AppKey معروفة. | استخدم Appkeys المختلفة عن تلك التي يوفرها البائعون أو استخدم المزيد من المفاتيح العشوائية. |
| LAF-009 | كلمة المرور متشققة | lafbruteforcer.py | عالي | تم العثور على appkey من الجهاز يحاول مع سلسلة معروفة أو غير عشوائية. تم فك تشفيره باستخدام زوج من رسائل الانضمام (طلب وقبول). | استخدم مولد مفتاح عشوائي لـ AppKey بدلاً من استخدام تلك التي يوفرها البائعون. علاوة على ذلك ، لا تقم بتعيين نفس AppKey على أكثر من جهاز ولا تنشئ appkeys باستخدام منطق يمكن التنبؤ به (مثل القيم الإضافية ، وقلب بايت بعض ، إلخ) |
| LAF-010 | تم تغيير بوابة الموقع | lafpacketanalysis.py | واسطة | إذا لم يكن من المفترض أن تغير البوابة موقعها. ربما تكون قد سُرقت أو نقلها أو قد تحاول بوابة مزيفة انتحال شخصية البوابة المشروعة. | تأكد من أن البوابة لم يتم العبث ، جسديًا أو منطقيًا. |
يوفر هذا الدليل مجموعة من الأغلفة للمكتبة https://github.com/brocaar/lorawan/ ، التي يتم كتابتها في Golang. يتم تنفيذ هذه الوظائف بواسطة الأدوات.
ستجد هنا سلسلة من البرامج النصية تهدف إلى أتمتة المهام المختلفة. تأكد من منحهم إذن التنفيذ إذا لزم الأمر ( chmod +x your_script لـ Linux/MacOS).
قم بسهولة بإعداد البوابة الخاصة بك وتبديل قنواتها لأغراض الاستنشاق. لمزيد من المعلومات حول كيفية استخدامها ، يمكنك رؤية ReadMe في هذا الدليل.
يتم استخدام هذا البرنامج النصي لتثبيت جميع حزم البرامج اللازمة على Raspberry Pi لبناء بوابة Lorawan بالتزامن مع مركبة Lora متصلة (IC980-SPI ، RHF0M301-SPI ، RAK831-SPI أو أي شيء آخر حسب الإعداد اليدوي).
نظرًا لأنه لا يمكن معرفة أي ترددات تعمل أجهزة Lora ، فقد أنشأنا برنامجًا نصيًا يمكنه تبديل قنوات البوابات من نطاقات تردد US915 و EU868 لأغراض الاستنشاق. على الرغم من وجود بوابات احترافية ومكلفة تدعم 32 أو 64 قناة ، فإن معظم البوابات تدعم ما يصل إلى 8 قنوات. يهدف هذا البرنامج النصي إلى التشغيل في هذا النوع من البوابات.
على الأقل في نطاق التردد US915 ، فإن القنوات الثمانية الأولى هي الأكثر استخدامًا. ولكن هناك تطبيقات معروفة تستخدم مجموعة أخرى من القنوات ، على سبيل المثال شبكات الأشياء ، والتي تستخدم المجموعة الثانية (8-15) من القنوات للاتصالات الصاعدة.
حاليًا لا ندعم نطاقات التردد الأخرى ، ولكن مع وجود تغييرات قليلة على هذه البرامج النصية ، ستتمكن من القيام بذلك بنفسك :).
قمنا بتحميل مقطع فيديو لهذا الإطار في العمل (نفس السيناريو المقدم في Blackhat 2019): https://youtu.be/mm6a2rvnocs. الخطوات التفصيلية للعروض التوضيحية موجودة في وصف فيديو YouTube.
تودو
تم ترخيص هذا المشروع بموجب ترخيص BSD-3-Cause.