Все началось с того, что однажды у нас в GS-Labs наметился проект по поиску багов и уязвимостей. Да вот только дошли слухи, что железка, где должно работать приложение, будет хитрая — нельзя поставить root, нет любимого Ethernet. «Органы управления» — только Wi-Fi да пультик управления на несколько кнопочек, а что будет передаваться по Wi-Fi — неизвестно. А хакеры, как ты знаешь, не любят неизвестности! Дома у меня валялись пара отладочных плат на основе ESP32 — ESP32-PICO-KIT, и я решил сделать свой Wi-Fi-сниффер — с блек-джеком и перспективой расширения до Bluetooth-сниффера!
ESP32-DevKitC
ESP32-DevKitC

 

Глоссарий

  • AP (access point) — точка доступа.
  • BSSID (basic service set identifier) — обычно MAC-адрес точки доступа.
  • BSS (basic service set) — группа устройств, которые успешно синхронизированы для общения с помощью 802.11.
  • DA (destination address) — MAC-адрес конечного назначения.
  • DS (distribution system) — система, объединяющая BSS и LAN.
  • ESS (extended service set) — несколько BSS, объединенных в единое целое, образующее DS.
  • MPDU (MAC protocol data unit) — фактически это фрейм 802.11.
  • MSDU (MAC service data unit) — payload, который содержит IP-пакет + данные LLC.
  • PLCP (physical layer convergence procedure) — подуровень (физический уровень PHY делится в 802.11 на две части), который отвечает за подготовку к отправке фрейма, поступившего с MAC-уровня.
  • PSDU (PLCP service data unit) — считай, то же самое, что и MPDU, только MPDU смотрим «сверху вниз» по модели OSI, PSDU — «снизу вверх» по модели OSI.
  • SA (source address) — MAC-адрес исходного отправителя.
  • STA (station) — любое устройство, поддерживающее 802.11, например твой смартфон, ноут или «малинка» (Raspberry Pi 3).

 

Техническая база

Думаю, ни для кого не секрет, что бал сегодня правят микроконтроллеры семейства STM32Fxxx (цифры и буквы на месте ххх означают класс устройства — от Ultra-low power до High Performance). Но пару лет назад появился «чудо-чип» под названием ESP32 — «старший брат» народного Wi-Fi ESP8266.

Изначально документация на этот чип была очень и очень скудна, но сейчас ситуация кардинально изменилась. Есть прекраснейший user guide, содержащий пошаговые инструкции по всем вопросам — от установки SDK и toolchain для этого микроконтроллера до описания его периферии. Все это приправлено массой примеров, выложенных на Гитхаб. Помимо этого, есть очень хороший блог, где наглядно расписывается, как работать с той или иной периферией.

Надо отдать разработчикам должное, Espressif описывает, как устанавливать toolchain для популярных платформ:


Вся документация представлена в двух вариациях:

  • ветка latest, которая включает все современные и передовые фичи SDK. Правда, они еще не оттестированы как следует;
  • ветка stable (на момент написания статьи stable был 3.1.2), которая не содержит всех новинок, но рекомендована для production purposes.

Да, забыл упомянуть их шикарный форум, где можно обсудить вопросы, связанные с ESP32. Складывается впечатление, что техподдержка Espressif отвечает достаточно шустро.

В одной из наших статей мы уже упоминали этот чип, поэтому здесь я лишь кратко перечислю основные характеристики:

  • 32-bit MCU Xtensa® single-/dual-core 32-bit LX6 microprocessor(s), который может работать в широком диапазоне частот;


  • 520 Кбайт SRAM;

  • «стандартный» набор периферии, представленный в виде UART/SPI/I2C, SDcard, Ethernet MAC (RMII), CAN2.0;
  • Wi-Fi (802.11b/g/n);
  • Bluetooth (Bluetooth v4.2 BR/EDR and BLE specifications).

Фанатам ассемблера производитель сделал царский подгон, любезно предоставив ULP (Ultra Low Power) сопроцессор, который кодится ассемблером и кушает до 150 мкА в режиме Deep-sleep (это для тех, кто хочет максимальной автономности). Да и вообще, не ленись заглянуть в даташит за деталями, там реально много интересного.

Кстати, если к этому моменту я уже внушил тебе сильное желание обзавестись данным чипом и ты уже начал вспоминать пароль от «Алиэкспресса» и адрес ближайшего отделения Почты России, то не спеши. 🙂 Удивительно, но разные варианты ESP32 можно купить у нас, причем порой это может оказаться дешевле и быстрее, чем заказывать из Китая. Например, вот такую двухсантиметровую штуку с возможностью подключения внешней антенны:


можно купить тут или тут примерно за четыре доллара.

 

Теория Wi-Fi (да, без нее не обойтись)

Возьму-ка я на себя очень амбициозную миссию: изложить три тысячи страниц стандарта в нескольких предложениях. 🙂 Думаю, что у меня получится, отступать ведь все равно поздно?

Думаю, ты уже знаешь, что Wi-Fi — это «красивое» название, которое скрывает под собой целый набор стандартов 802.11. Вот лишь «некоторая часть» из них:

  • 900 МГц — 802.11ah;
  • 2,4 ГГц — 802.11b, 802.11g, 802.11n, 802.11ax;
  • 3,6 ГГц — 802.11y;
  • 4,9 ГГц — 802.11j;
  • 5 ГГц — 802.11a, 802.11n, 802.11ac, 802.11ax;
  • 5,9 ГГц — 802.11p;
  • 45 ГГц — 802.11aj;
  • 60 ГГц — 802.11aj, 802.11ay.

Поскольку для этого проекта нам нужно знание деталей, а не умение запустить magic-утилиту на wonderful-железке, давай заглянем внутрь 802.11 поглубже. Итак, согласно IEEE 802.11—2012, MAC-фрейм имеет следующую структуру:


Теперь пройдемся по каждому полю, чтобы понимать, за что оно отвечает.

Frame Control


  • Protocol version — согласно рассматриваемому стандарту, значение всегда 0. Остальные возможные значения зарезервированы.
  • Type and Subtype — описывают тип и подтип фрейма. Всего существует три типа фреймов: Management, Data, Control с подтипами.

О том, какие бывают Management-, Control- и Data-фреймы, ты прочитаешь, как только закончим рассматривать MAC-заголовок 802.11.

  • TO_DS, FROM_DS — их стоит рассматривать вместе, и они отвечают за то, как интерпретировать поля Address 1 … Address 4 из заголовка фрейма. Посмотрим на табличку ниже:


  • Source Address (SA) — MAC-адрес исходного отправителя (твой смарт или ноут, с которого выходишь в паутину).

  • Destination Address (DA) — MAC-адрес конечного назначения (тот сервак, куда ты зашел, чтобы прочитать эту статью).
  • Transmitter Address (TA) — MAC-адрес, передающий фрейм 802.11 (точка доступа, через которую ты сидишь).
  • Receiver Address (RA) — MAC-адрес, принимающий фрейм 802.11.
  • Basic Service Set Identifier (BSSID) — L2 identifier of the basic service set (BSS).

Четвертый случай (когда оба бита выставлены в единицу) наглядно пояснит вот такая картинка:


  • More Frag выставляется в единичку во всех Data- и Management-фреймах, указывающих, что есть еще фрагменты в текущем MSDU или MMPDU.
  • Retry устанавливается в единичку, когда фрейм является повторной передачей более раннего фрейма.
  • Power Mgmt устанавливается в единицу, когда клиент показывает, что находится в режиме Power Save mode; необходимо буферизировать трафик, получаемый со стороны клиента.
  • More Data выставляется в единицу, тем самым AP (точка доступа) указывает клиенту (STA), который находится в Power Save Mode, что для него есть еще данные и «ложиться спать» еще рано.
  • Protected Frame — как, думаю, ты уже догадываешься из названия, единица в этом бите указывает на то, что фрейм у нас зашифрован.
  • Order устанавливается в любом non-QOS Data-фрейме, когда приложение требует, чтобы данные были отправлены строго упорядоченно.

Duration/ID

Несколько загадочное поле, поскольку смысл, который будет в этих 16 битах, сильно зависит от того, какой у нас фрейм — Data, Control или Management. Как вариант — если у нас Control PS-Poll фрейм (об этом будет сказано дальше), то тут будет содержаться идентификатор AID. А может быть указано время в микросекундах, требуемое для передачи следующего фрагмента в Data Frame.

 

Еще одна интересная железка от Cypress

CYW43907 привлекательна тем, что поддерживает Dual Band (2,4/5 ГГц) и на борту у нее USB 2.0. И что для нас самое интересное — вроде как поддерживает неразборчивый режим. Почему говорю «вроде как» — однозначного упоминания в документации и programming user guide я не встретил, но если посмотреть сюда, то в этой ветке форума говорится, что с SDK 2.4.1 появилась функция wiced_wifi_enable_monitor_mode(), которая позволяет прослушивать эфир и фреймы capture 802.11.

Sequence Control


Как видим из картинки выше, делится, в свою очередь, на Fragment Number и Sequence Number. Sequence Number указывает порядковый номер в MSDU-, A-MSDU- или MMPDU-фреймах. Fragment Number указывает номер каждого фрагмента в MSDU- или MMPDU-фреймах. Чтобы более четко понять, как используется Sequence Number в связке с Fragment Number, посмотри на картинку ниже.


Нам надо передать данные размером в 1200 байт, но точка доступа сконфигурирована так, что размер передаваемого фрейма составляет 300 байт. Передача единого сообщения в 1200 байт будет выглядеть следующим образом.


QoS Control

Шестнадцатое поле, которое отвечает quality-of-service в Data frame.

HT Control

Последнее поле — HT Control, которое может встречаться в MAC-заголовке фрейма 802.11. Стандарт 802.11n расширяет заголовок данных полем размером в четыре байта. Присутствует только в QoS Data- и Management-фреймах и определяется Order bit из Frame Control.

Body

В поле Body «упаковываются» вышестоящие протоколы.

Продолжение доступно только участникам

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», увеличит личную накопительную скидку и позволит накапливать профессиональный рейтинг Xakep Score! Подробнее

Вариант 2. Открой один материал

Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.


Check Also

В королевстве PWN. ROP-цепочки и атака Return-to-PLT в CTF Bitterman

В этой статье мы рассмотрим особенности переполнения стека в 64-битном Linux. Сделаем мы э…

Оставить мнение