Игры с Wifi на ESP32

image

На мысль сделать карманный инструмент для анализа WiFi сетей меня подтолкнула статья https://habr.com/ru/post/477440/.
Спасибо им за идею. Мне как раз было нечем заняться.
Вся работа была выполнена в рамках хобби с целью получения удовольствия и расширения своих знаний в области сетевых технологий. Не торопясь, по 1…4 часа в неделю, с начала этого года.
Прикладное использование не планировал. Т.е. это НЕ инструмент для хакера.

На данный момент весь задуманный функционал работает. Все исходники, полностью готовые для сборки, выложены https://github.com/mmMikeKn/ESP32-WiFi-tool. Там же инструкция по сборке и пр. В данной заметке я не буду дублировать информацию, выложенную на github. Расскажу только то, что считаю нужным описать отдельно.


Мое мнение по поводу «универсального инструмента» и причина выбора ESP32.

Я не претендую на истину. Она у каждого своя. Постараюсь обосновать свой выбор «железа».

Предложенный в статье https://habr.com/ru/post/477440/ вариант использования сочетание Linux (изначально Raspberry Pi) + «периферии» в виде контроллер (STM32) + CC1110 (ядро 8051) и план впихнуть туда все что только можно (125kHz, NFC, 433mHz, USB, iButton, bluetooth, ?) показался не подходящим для меня. Впрочем, этот проект https://habr.com/ru/post/490196/ похоже так останется частным и закрытым (flipper-zero github «This organization has no public repositories.») и пошел в сторону не слишком распространенного железа.
Возможно я не прав, и в дальнейшем авторы выложат исходники ПО в открытый доступ. Но если нет, то я бы такую железку без исходников не купил бы.


Мои требования к «инструменту».

Коробочка должна быть маленькая (чем меньше, тем лучше).
Поэтому:


  • Встроенный аккумулятор не нужен. При токе > 100 mA при работе с Wifi, встроенный аккумулятор либо будет большой, либо его хватает не на долго. Поэтому пусть «коробочка» питается от стандартного power bank. Все равно power bank в кармане/машине валяется у меня всегда.
  • Держать внутри «коробочки» Linux с инструментами, написанными за много лет на всех языках при наличии мелкого экрана и скудного набора управляющих кнопок смысла нет. Результаты можно смотреть/обрабатывать и на нормальном ноутбуке с полноценной клавиатурой и экраном.
  • Компоненты должны быть легкодоступными и широко известными (доступный SDK, много примеров и документации).

В результате, для меня, выбор был очевиден — ESP32.
Под все задачи, заявленные в статье, которая подтолкнула меня к действиям, возможностей ESP32 вполне хватает. Хотя максимум что я хочу еще сделать это:


  • Поиграться с Bluetooth.
  • Поиграться с 433mHz диапазоном с простейшим hardware (только амплитудная модуляция, чего достаточно для практически надобностей).


Ложка дегтя в ESP32

  • SDK (IDF) ESP32 несколько коряв.
  • Часть функционала (стек WiFi, например) идет без исходников в виде собранных статических библиотек.
  • Не поддерживается диапазон 5gHz и есть некоторые ограничения и корявости по работе с WiFi.

Но цена/размеры вполне компенсируют эти недостатки.


Основной функционал ПО.

Коротко опишу функционал и своем мнение о…


Управление настройками и выгрузка файлов с SD.

Все внешнее управление сделано через простейшую Web страницу, запускаемую в отдельном пункте меню. ESP32 запускается в режиме WiFi AP и выдает страницу по фиксированному IP адресу.

Хотя ядра ESP32 довольно быстрые, но, как показали эксперименты, одновременное работа встроенного Web сервиса и, например, режима router не слишком сочетаются. Поэтому динамического управления нет и во всех остальных режимах страница не доступна.
Тем более, что для исследовательских целей динамическое управление не нужно.


Режим работы с Beacon пакетами.

Режимы банальные и не очень интересные. Сделаны «потому что можно». Для галочки.
Примеры есть в официальных examples примерах Espressif.
Режим сканирования списков AP.
Собственно, это умеет делать любой смартфон.
Ну и в этом режиме сохранятся список AP.
Beacon spammer.
ESP32 стартует как AP со скрытым SSID и случайным MAC и начинает слать [beacon frame] по заранее созданному списку SSID (созданному вручную или полученному ранее при сканировании списка AP)


Режим sniffing пакeтов WiFi.

Разработчики Espressif добавили возможность прикладному ПО получать через callback функцию все WiFi пакеты «пролетающие в воздухе». На самом деле не все, поскольку можно установить режим только для одного фиксированного канала.

На обработку вызова callback функции накладываются очень жесткие временные ограничения. Если для режима простого сбора статистики это проблем не вызывает, то для режима записи PCAP файла на SD карту пришлось повозится, организуя запись через очередь в памяти и семафоры. С учетом особенности, что процесс, вызывающий callback крутится на одном ядре, а процесс, выполняющий запись на SD в другом.

При «зашумленном эфире» некоторые пакеты теряются (в очереди нет места и они отбрасываются), но при типичном «эфире» квартиры вечером (5…7 AP в пределах видимости) запись в PCAP успевает выполнятся без потерь пакетов.

Дополнительно, для мониторинга и записи PCAP есть режим фильтрации по списку MAC в заголовках пакетов.
Например, можно отследить появление человека в клубе/кафешке, до того, как он вообще вошел или появился в поле зрения. Мало кто отключает WiFi и автоматические соединение с известными AP. (Я теперь отключаю…)
Просматривать записанный трафик в Wireshark познавательно и интересно для понимания карт это все работает.


Режим работы с deauth пакетами.

По умолчанию, посылка этих пакетов запрещена в библиотеке libnet80211.a, которая идет без исходников. Но это несложно купировать, подправив пару байтиков. Вначале я сомневался, а стоит ли выкладывать patch. Но походив по разным местам с включенным режимом сканирования источников посылки [deauthentication frame], подумал: «какого черта». Тем более, что в esp8266 посылка этих пакетов не закрыта и сборки на github под esp8266 есть.

В очень многих местах (не буду говорить где) используется подавление нежелательных AP через этот метод. И это не «хулиганы»…

А я еще удивлялся, что это у меня раздача интернета с телефона местами не работает…

Режим отслеживание количества и RSSI таких пакетов очень полезен что бы понять «где не любят левые AP».


Режим router.

Эта функция, наверное, самая интересная из всех для исследования.

ESP32 поддерживает одновременную работу в режиме STA + SoftAP. Поэтому на нем можно реализовать классический NAT router.
Для поддержки сетевого стека Espressif использует fork (практически без изменений) библиотеки lwip.
Hо, по умолчанию, в стандартной сборке, в библиотеке esp-lwip между netif интерфейсами «ap»(SoftAP) и «st» (STA) не предусмотрен проброс.

Можно конечно сделать и без NAT, но возникает проблема с одновременным подключение двух и более STA к интерфейсу «ap» и синхронизации IP адресов от сетевого интерфейса 'st' к 'ap'. Так что сложности не стоят того и проще через NAT.
Тем более, что существует fork esp-lwip от martin-ger в котором добавленa простая реализация NAT для IP4.
Хотя у меня руки чесались ее переделать чисто косметически (по моему, проще было без fork проекта, а через LWIPHOOK функции, определяемых при сборке), но лень победила и вариант от martin-ger используется как есть.

В режиме router просматривается входящий и исходящий IP4 трафик.
В частности, из него извлекается для показа на экранчике и сбора статистики в файл:


  • Имя устройства, которое подключилось к SoftAP ESP32 (DHCP пакеты)
  • URL из DNS запросов (UDP port 53) от подключенного к SoftAP ESP32 устройства.

Дополнительно можно включить запись трафика в PCAP файл.

Данный режим весьма полезен, например, для того что бы понять, например, что ваш телефон шлет в сеть и куда при этом ходит.
Можно придумать и другие способы использования этого режима с учетом возможности полностью управлять программно входящим и исходящим трафиком SoftAP ESP32 на уровне сетевого интерфейса: Ehernet заголовок (destMAC[6]+srcMAC[6]+type[2]) + payload (IP4, IP6, DCHP, и прочее type).

В принципе, ESP32 вполне нормально справляется с функцией WiFi→WiFi роутера, пропуская через себя без особых задержек обычный трафик. Субъективно, задержки в телефоне, подключенном через router на ESP32 не заметны.

К сожалению, в API Espressif нет возможности установить фильтр по MAC подключаемым к SoftAP EPS32. В место этого предлагается говорить «до свидание» (esp_wifi_deauth_sta) уже подключенным STA, которые «не желательны».
Фильтрация по MAC для подключаемых STA пришлось сделать чрез вызов esp_wifi_deauth_sta ()


В заключение.

Хотя ничего нового в рамках работы с ESP32 я не придумал, но возможно кому то результат (исходники) будет интересен.

Хотел бы отметить, что код писал исключительно в познавательных целях. Для «взлома» и пр. он специально делался не очень удобным.

Печатную плату не делал, поскольку на то, что бы спаять проводом готовые платки ушло часа 1.5–2.
Да и если делать, то нужно не из готовых плат собирать, а из отдельных компонент. Тогда габариты будут еще меньше.

© Habrahabr.ru