- •От издательства
- •О техническом обозревателе
- •О соавторах
- •Об авторах
- •Вступительное слово
- •Благодарности
- •Предисловие
- •Почему важна защита интернета вещей?
- •Чем защита интернета вещей отличается от традиционной ИТ-защиты?
- •Законы хакинга интернета вещей
- •Заключение
- •Моделирование угроз для интернета вещей
- •Схема моделирования угроз
- •Определение архитектуры
- •Разбивка архитектуры на компоненты
- •Выявление угроз
- •Использование деревьев атак для обнаружения угроз
- •Распространенные угрозы интернета вещей
- •Атаки с подавлением сигнала
- •Атаки с воспроизведением
- •Атаки со взломом настроек
- •Клонирование узла
- •Заключение
- •Пассивная разведка
- •Физический или аппаратный уровень
- •Периферийные интерфейсы
- •Среда загрузки
- •Блокировки
- •Предотвращение и обнаружение несанкционированного доступа
- •Прошивка
- •Интерфейсы отладки
- •Физическая устойчивость
- •Разведка
- •Атаки на сетевой протокол и службы
- •Тестирование беспроводного протокола
- •Оценка веб-приложений
- •Картирование приложений
- •Элементы управления на стороне клиента
- •Аутентификация
- •Управление сеансом
- •Проверка ввода
- •Логические ошибки
- •Сервер приложений
- •Исследование конфигурации хоста
- •Учетные записи пользователей
- •Привилегии учетной записи
- •Уровни патчей
- •Удаленное обслуживание
- •Управление доступом к файловой системе
- •Шифрование данных
- •Неверная конфигурация сервера
- •Мобильное приложение и облачное тестирование
- •Заключение
- •4. Оценка сети
- •Переход в сеть IoT
- •VLAN и сетевые коммутаторы
- •Спуфинг коммутатора
- •Двойное тегирование
- •Имитация устройств VoIP
- •Идентификация устройств IoT в сети
- •Обнаружение паролей службами снятия отпечатков
- •Атаки MQTT
- •Настройка тестовой среды
- •Написание модуля MQTT Authentication-Cracking в Ncrack
- •Тестирование модуля Ncrack на соответствие MQTT
- •Заключение
- •5. Анализ сетевых протоколов
- •Проверка сетевых протоколов
- •Сбор информации
- •Анализ
- •Создание прототипов и разработка инструментов
- •Работа с Lua
- •Общие сведения о протоколе DICOM
- •Генерация трафика DICOM
- •Включение Lua в Wireshark
- •Определение диссектора
- •Определение основной функции диссектора
- •Завершение диссектора
- •Создание диссектора C-ECHO
- •Начальная загрузка данных функции диссектора
- •Анализ полей переменной длины
- •Тестирование диссектора
- •Разработка сканера служб DICOM для механизма сценариев Nmap
- •Написание библиотеки сценариев Nmap для DICOM
- •Коды и константы DICOM
- •Написание функций создания и уничтожения сокетов
- •Создание заголовков пакетов DICOM
- •Написание запросов контекстов сообщений A-ASSOCIATE
- •Чтение аргументов скрипта в движке сценариев Nmap
- •Определение структуры запроса A-ASSOCIATE
- •Анализ ответов A-ASSOCIATE
- •Создание окончательного сценария
- •Заключение
- •6. Использование сети с нулевой конфигурацией
- •Использование UPnP
- •Стек UPnP
- •Распространенные уязвимости UPnP
- •Злоупотребление UPnP через интерфейсы WAN
- •Другие атаки UPnP
- •Использование mDNS и DNS-SD
- •Как работает mDNS
- •Как работает DNS-SD
- •Проведение разведки с помощью mDNS и DNS-SD
- •Злоупотребление на этапе проверки mDNS
- •Атаки «человек посередине» на mDNS и DNS-SD
- •Использование WS-Discovery
- •Как работает WS-Discovery
- •Подделка камер в вашей сети
- •Создание атак WS-Discovery
- •Заключение
- •UART
- •Аппаратные средства для связи с UART
- •Как найти порты UART
- •Определение скорости передачи UART
- •JTAG и SWD
- •JTAG
- •Как работает SWD
- •Аппаратные средства для взаимодействия с JTAG и SWD
- •Идентификация контактов JTAG
- •Взлом устройства с помощью UART и SWD
- •Целевое устройство STM32F103C8T6 (Black Pill)
- •Настройка среды отладки
- •Кодирование целевой программы на Arduino
- •Отладка целевого устройства
- •Заключение
- •Как работает SPI
- •Как работает I2C
- •Настройка архитектуры шины I2C типа «контроллер–периферия»
- •Заключение
- •9. Взлом прошивки
- •Прошивка и операционные системы
- •Получение доступа к микропрограмме
- •Взлом маршрутизатора Wi-Fi
- •Извлечение файловой системы
- •Статический анализ содержимого файловой системы
- •Эмуляция прошивки
- •Динамический анализ
- •Внедрение бэкдора в прошивку
- •Нацеливание на механизмы обновления микропрограмм
- •Компиляция и установка
- •Код клиента
- •Запуск службы обновления
- •Уязвимости служб обновления микропрограмм
- •Заключение
- •10. Радио ближнего действия: взлом rFID
- •Радиочастотные диапазоны
- •Пассивные и активные технологии RFID
- •Структура меток RFID
- •Низкочастотные метки RFID
- •Высокочастотные RFID-метки
- •Настройка Proxmark3
- •Обновление Proxmark3
- •Клонирование низкочастотных меток
- •Клонирование высокочастотных меток
- •Имитация RFID-метки
- •Изменение содержимого RFID-меток
- •Команды RAW для небрендированных или некоммерческих RFID-тегов
- •Подслушивание обмена данными между меткой и считывателем
- •Извлечение ключа сектора из перехваченного трафика
- •Атака путем подделки RFID
- •Автоматизация RFID-атак с помощью механизма скриптов Proxmark3
- •Пользовательские сценарии использования RFID-фаззинга
- •Заключение
- •11. Bluetooth Low Energy (BLE)
- •Как работает BLE
- •Необходимое оборудование BLE
- •BlueZ
- •Настройка интерфейсов BLE
- •Обнаружение устройств и перечисление характеристик
- •GATTTool
- •Bettercap
- •Взлом BLE
- •Настройка BLE CTF Infinity
- •Приступаем к работе
- •Заключение
- •12. Радиоканалы средней дальности: взлом Wi-Fi
- •Как работает Wi-Fi
- •Атаки Wi-Fi на беспроводные клиенты
- •Деаутентификация и атаки «отказ в обслуживании»
- •Атаки на Wi-Fi путем подключения
- •Wi-Fi Direct
- •Атаки на точки доступа Wi-Fi
- •Взлом WPA/WPA2
- •Взлом WPA/WPA2 Enterprise для сбора учетных данных
- •Методология тестирования
- •Заключение
- •13. Радио дальнего действия: LPWAN
- •Захват трафика LoRa
- •Настройка платы разработки Heltec LoRa 32
- •Настройка LoStik
- •Превращаем USB-устройство CatWAN в сниффер LoRa
- •Декодирование протокола LoRaWAN
- •Формат пакета LoRaWAN
- •Присоединение к сетям LoRaWAN
- •Атаки на LoRaWAN
- •Атаки с заменой битов
- •Генерация ключей и управление ими
- •Атаки воспроизведения
- •Подслушивание
- •Подмена ACK
- •Атаки, специфичные для приложений
- •Заключение
- •14. Взлом мобильных приложений
- •Разбивка архитектуры на компоненты
- •Выявление угроз
- •Защита данных и зашифрованная файловая система
- •Подписи приложений
- •Аутентификация пользователя
- •Управление изолированными аппаратными компонентами и ключами
- •Проверенная и безопасная загрузка
- •Анализ приложений iOS
- •Подготовка среды тестирования
- •Статический анализ
- •Динамический анализ
- •Атаки путем инъекции
- •Хранилище связки ключей
- •Реверс-инжиниринг двоичного кода
- •Перехват и изучение сетевого трафика
- •Анализ приложений Android
- •Подготовка тестовой среды
- •Извлечение файла APK
- •Статический анализ
- •Обратная конвертация двоичных исполняемых файлов
- •Динамический анализ
- •Перехват и анализ сетевого трафика
- •Утечки по побочным каналам
- •Заключение
- •15. Взлом умного дома
- •Физический доступ в здание
- •Клонирование RFID-метки умного дверного замка
- •Глушение беспроводной сигнализации
- •Воспроизведение потока с IP-камеры
- •Общие сведения о протоколах потоковой передачи
- •Анализ сетевого трафика IP-камеры
- •Извлечение видеопотока
- •Атака на умную беговую дорожку
- •Перехват управления интеллектуальной беговой дорожкой на базе Android
- •Заключение
- •Инструменты для взлома интернета вещей
- •Предметный указатель
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|||
|
|
|
X |
|
|
|
|
|
|
|||
|
|
- |
|
|
|
|
|
d |
|
|||
|
|
F |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
|
t |
|
||
|
P |
D |
|
|
|
|
|
|
|
|
o |
|
|
|
|
|
|
NOW! |
r |
||||||
|
|
|
|
|
|
BUY |
|
|
||||
Настройка LoStik |
|
|
|
|
to |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
w |
|
|
|
|
|
|
|
|
|
m |
||
w Click |
|
|
|
|
|
|
o |
|||||
|
|
w |
|
|
|
|
|
|
|
|
|
|
|
|
. |
|
|
|
|
|
|
.c |
|
||
|
|
|
p |
df |
|
|
|
|
e |
|
||
|
|
|
|
|
|
g |
|
|
|
|||
|
|
|
|
|
|
n |
|
|
|
|
||
|
|
|
|
|
-x cha |
|
|
|
|
|
||
Чтобы получать пакеты от платы Heltec, мы настроим LoStik как |
|
|
|
|
|
|
|
приемник LoRa (рис. 13.5). Мы использовали версию LoStik RN2903 (США),котораяохватываетСША,КанадуиЮжнуюАмерику.Советуем вамознакомитьсясоследующейкартой,накоторойпоказанычастот- ные планы и правила LoRaWAN (и LoRa) по странам в проекте The Things Network: https://www.thethingsnetwork.org/docs/lorawan/frequencies- by-country/.
Рис.13.5.LoStik поставляется в двух версиях: модули RN2903 (США) и RN2483 (ЕС) от Microchip.Убедитесь,что вы выбрали правильный вариант для вашего региона СЭ
Чтобы загрузить и поэкспериментировать с некоторыми примера- ми кода, предоставленными разработчиком LoStik, вы можете запу- стить эту строку:
$ git clone https://github.com/ronoth/LoStik.git
Для запуска примеров вам понадобится Python 3 и пакет pyserial. Можетеустановитьэтотпакет,указавдиспетчерупакетовpip нафайл requirements.txt в каталоге examples:
# pip install -r requirements.txt
ПодключивLoStikккомпьютеру,введитеследующуюкоманду,что- бы узнать, какой дескриптор файла устройства ему был назначен:
$ sudo dmesg
…
usb 1-2.1: ch341-uart converter now attached to ttyUSB0
Радио дальнего действия: LPWAN 363
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
|
X |
|
|
|
|
|
|||
|
|
- |
|
|
|
|
|
d |
|
||
|
|
F |
|
|
|
|
|
|
t |
|
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
||
|
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
BUY |
|
|
|||
Его следует назначить на /dev/ttyUSB0, если у вас нет других под- |
|
|
to |
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
m |
|||
|
w Click |
|
|
|
|
|
|
||||
|
w |
|
|
|
|
|
|
|
|
|
|
ключенных периферийных устройств. |
|
w |
|
df-x chan |
|
o |
|
||||
|
. |
.c |
|
||||||||
|
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
|
|
e |
|
Разработка кода приемника LoRa
Втекстовом редакторе,таком какVim,введите следующий скриптPy- thon, который позволяет LoStik действовать как базовый приемник LoRa.КодбудетотправлятькомандыконфигурациинарадиочипLoRa (RN2903) в LoStik через последовательный интерфейс, чтобы заста- вить его прослушивать определенные видытрафика LoRa и выводить полученные пакетные данные в терминал. В листинге 13.2 показан наш код.
Листинг 13.2. Скрипт Python, который позволяет использовать LoStik как базовый приемник LoRa
#!/usr/bin/env python3 import time
import sys import serial import argparse
from serial.threaded import LineReader, ReaderThread
parser = argparse.ArgumentParser(description='LoRa Radio mode receiver.') parser.add_argument('port', help="Serial port descriptor")
args = parser.parse_args()
class PrintLines(LineReader):
def connection_made(self, transport): print("serial port connection made") self.transport = transport self.send_cmd('mac pause') self.send_cmd('radio set wdt 0') self.send_cmd('radio set crc off') self.send_cmd('radio set sf sf7') self.send_cmd('radio rx 0')
def handle_line(self, data):
if data == "ok" or data == 'busy': return
if data == "radio_err": self.send_cmd('radio rx 0') return
if 'radio_rx' in data: print(bytes.fromhex(data[10:]).decode('utf-8', errors='ignore'))
else:
print(data)
time.sleep(.1) self.send_cmd('radio rx 0')
def connection_lost(self, exc): if exc:
print(exc) print("port closed")
364 Глава 13
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
def send_cmd(self, cmd, delay=.5): self.transport.write(('%s\r\n' % cmd).encode('UTF-8')) time.sleep(delay)
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
ser = serial.Serial(args.port, baudrate=57600) with ReaderThread(ser, PrintLines) as protocol:
while(1): pass
Сценарий Python сначала импортирует необходимые модули , включаяпоследовательныеклассыLineReaderиReaderThreadизпаке- таpyserial.Этидваклассапомогутнамреализоватьциклчтенияпосле- довательного порта с использованием потоков. Затем мы настраива- емоченьпростойсинтаксическийанализатораргументовкомандной строки , через который передаем дескриптор файла устройства для последовательного порта (например,/dev/ttyUSB0) как единственный аргумент нашей программы. Мы определяем PrintLines , подкласс serial.threaded.LineReader, который будет использовать наш объект ReaderThread. Этот класс реализует основную логику программы. Мы инициализируем все настройки радио LoStik внутри функции connection_made , потому что она вызывается при запуске потока.
Следующие пять команд настраивают радиочасть LoRa чипа RN2903. Эти шаги напоминают шаги, которые вы предприняли для настройки радио LoRa на плате Heltec. Мы советуем вам прочитать подробное объяснение этих команд в «Руководстве пользователя по командам технологического модуля RN2903 LoRa» от Microchip (https://www.microchip.com/wwwproducts/en/RN2903).
Давайте рассмотрим каждую команду:
zzmac pause – приостанавливает функционирование стека LoRa WAN, чтобы вы могли настроить радио, поэтому мы начнем с этого;
zzradio set wdt 0 –отключаетсторожевойтаймер(WatchdogTimer),
механизм, который прерывает радиоприем или передачу по ис- течении заданного количества миллисекунд;
zzradio set crc off – отключает заголовок CRC в LoRa. Параметр off – наиболее распространенный;
zzradio set sf sf7 – устанавливает коэффициент передачи. Допу- стимые параметры: sf7,sf8,sf9,sf10,sf11 или sf12.Мы устанав- ливаем коэффициентпередачитsf7,потому что узел Heltec LoRa 32, который действует как наш отправитель, находится в той же комнате, что и получатель (помните, что короткие расстояния требуют небольшого коэффициента), также имеет коэффици- ент 7. Два коэффициента должны совпадать, иначе отправитель и получатель не смогут установить связь с друг с другом;
zzradio rx 0 –переводит радио в режим непрерывного приема; это означает, что радиомодуль будет слушать эфир, пока не получит пакет.
Радио дальнего действия: LPWAN 365
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
|
X |
|
|
|
|
|
|||
|
|
- |
|
|
|
|
|
d |
|
||
|
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
|||
P |
|
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
BUY |
|
|
|||
Затем мы переопределим функцию handle_line LineReader , кото- |
|
|
|
to |
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
m |
||
w Click |
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
df-x chan |
|
o |
|
|||||
рая вызывается всякий раз,когда микросхема RN2903 получаетновую |
. |
.c |
|
||||||||
|
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
|
|
e |
|
строку из последовательного порта. Если значение строки в порядке иливозвращается«занято»,мывозвращаемся,чтобыпродолжитьпро- слушивание новых строк. Если эта строка является строкой radio_err, это,вероятно,означает,чтосторожевойтаймеротправилпрерывание. Значение сторожевого таймера по умолчанию составляет 15 000 мс, это означает, что если с начала приема приемопередатчика прошло 15 с без получения каких-либо данных,сторожевойтаймер прерывает работу радио и возвращает radio_err. Если это произойдет, мы вызы- ваем radio rx 0, чтобы снова установить радио в непрерывный режим приема. Ранее мы отключили сторожевой таймер в этом скрипте, но в любом случае рекомендуется обрабатывать это прерывание.
Если строка содержит radio rx , то она содержит новый пакет, полученный радиоприемником LoRa, и в этом случае мы пытаемся декодировать полезную нагрузку (все,начиная с байта 10 и далее,по- скольку байты 0–9 переменной данных содержат строку radio rx) как UTF-8, игнорируя любые ошибки (символы, которые не могут быть декодированы). В противном случае мы просто печатаем всю строку, потому что она, вероятно, будет содержать ответ от LoStik на некото- рую команду, которую мы ему отправили. Например, если мы отпра- вим ему команду radio get crc,он ответит строкой on или off,указав, включен ли CRC.
Мы также переопределяем метод connection_lost , который вы- зывается при закрытии последовательного порта или при заверше- нии цикла считывателя.Мы выводим на печать исключение exc,если работа программы прекращена из-за ошибки. Функция send_cmd – это просто оболочка, которая следит за тем, чтобы команды, отправ- ляемые на последовательный порт, имели правильный формат. Она проверяет, что данные закодированы в UTF-8 и что строка заканчи- вается символами возврата каретки и новой строки.
В основной части скрипта мы создаем объект Serial с именем ser, который принимает дескриптор файла последовательного пор- та в качестве аргумента и устанавливает скорость передачи (скорость передачи данных по последовательной линии). RN2903 требует ско- рости 57600.Затем мы создаем бесконечный цикл и инициализируем pyserial ReaderThread с нашим экземпляром последовательного пор- та и классом PrintLines, реализуя нашу основную логику.
Запуск приемника LoRa
Подключив LoStik к USB-порту на нашем компьютере, мы можем за- пустить наш приемник LoRa, введя следующую строку:
# ./lora_recv.py /dev/ttyUSB0
Теперь мы должны увидеть сообщения LoRa, отправленные моду-
лем Heltec:
366 Глава 13