• Познакомьтесь с пентестом веб-приложений на практике в нашем новом бесплатном курсе

    «Анализ защищенности веб-приложений»

    🔥 Записаться бесплатно!

  • CTF с учебными материалами Codeby Games

    Обучение кибербезопасности в игровой форме. Более 200 заданий по Active Directory, OSINT, PWN, Веб, Стеганографии, Реверс-инжинирингу, Форензике и Криптографии. Школа CTF с бесплатными курсами по всем категориям.

Статья Определяем кто дома с помощью ESP8266

Приветствую всех читателей Codeby!
Сегодня мы создадим устройство, которое будет обнаруживать устройства вокруг. Сделаем простой проект, который будет обнаруживать, кто из родственников находиться дома, для примера.

1549988406227.png


Введение.
Функция этого проекта заключается в чтении близлежащего трафика Wi-Fi.Обнаруженные пакеты сравниваются со списком MAC-адресов, которые мы хотим отслеживать, и если MAC-адрес пакета соответствует одному в списке, мы включаем определенный светодиод, который связан с пользователем, владеющим устройством(в нашем случае - член семьи).

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

1549987434936.png


Смартфоны и другие устройства с поддержкой Wi-Fi отправляют радиосигналы, называемые зондирующими(пробными) кадрами(Probe Frame), для обнаружения близлежащих беспроводных сетей, что позволяет легко отслеживать их, прослушивая их уникальный MAC-адрес.
На эту тему было мною было написано несколько статей
- Пассивная слежка через WIFI с помощью Probequest
- Детектор деаутентификации (диссоциации) клиентов. Часть 2

Чтобы показать, как работает этот вид отслеживания, мы можем запрограммировать NodeMCU Arduino на прослушивание пакетов любого устройства, которое мы хотим отслеживать, включая светодиод, когда он обнаруживается поблизости.
Широкое отслеживание представляет собой серьезную проблему конфиденциальности, побуждая большинство производителей применять такие меры безопасности, как рандомизация MAC-адресов, которая защищает от произвольного мониторинга MAC-адресов.

Проблема рандомизиции MAC-адресов.

1549983484004.png


Рандомизация MAC-адресов полезна для предотвращения некоторых типов отслеживания, но в тестах на различных телефонах Android было выясненно, что рандомизация MAC-адресов далека от совершенства. Существует несколько условий, при которых телефон возвращается к своему реальному MAC-адресу.
После обнаружения знакомой сети, сохраненной в списке предпочтительных сетей, устройство попытается подключиться к сети и может стать доступным для отслеживания.

Помимо просмотра сети Wi-Fi в списке предпочтительных сетей, активное подключение к сети устройство также будет активно показывать(палить) свой постоянный MAC-адрес. Это означает, что если вы захотите отследить кого-то, приходящего домой или проходящего мимо кафе с общим именем сети, рандомизация MAC-адресов не помешает вам это сделать.

К сожалению, большинство Android устройств генерируют пакеты тестовых кадров, используя реальный MAC-адрес, каждый раз, когда вы включаете Wi-Fi или открываете меню выбора сети Wi-Fi.

Отслеживание с помощью Arduino.
Чтобы показать, как легко отслеживать устройства,мы будем использовать Arduino, который использует встроенный чип Wi-Fi для отслеживания MAC-адресов.
На самом деле уже существует проект - Friend Detector.
Этот удивительный проект берет любой MAC-адрес, который вы хотите отслеживать, и прослушивает пакеты, содержащие этот адрес. Это действительно круто, потому что Friend Detector просматривает типы пакетов, которые отправляют смартфоны как при подключении, так и при отключении от сети Wi-Fi, что облегчает обнаружение устройства в любом состоянии.

Чтобы сделать этот проект более наглядным и обеспечить легкий способ обнаружения, когда ваше устройство передает свой реальный MAC-адрес, я решил изменить код, включив в него несколько светодиодов и возможность отслеживать столько MAC-адресов, сколько имеется доступных контактов для управления светодиодами.
В нашем случае будем отслеживать 4 устройства.

Есть некоторые проблемы, которые нам нужно преодолеть при использовании светодиода, например, тот факт, что использование задержки для удержания светодиода в течение достаточно долгого времени, чтобы его можно было заметить, что таймер приводил к сбою в работе светодиодов(далее будет объяснена проблема).

Чтобы решить эту проблему, я добавил таймер, который включал бы светодиод при обнаружении пакета с совпадающим MAC-адресом и оставлял его включенным до тех пор, пока не будет обнаружено установленное количество пакетов, которые не соответствуют искомому MAC-адресу; Это позволяет нам легко изменять продолжительность работы светодиода.

Шаг 1. Поиск MAC-адреса устройства.
Сперва стоит определить какие устройства мы будем обнаруживать, для этого получим их MAC-адреса.
Лучший способ это подключиться к сети, в которой есть устройство, которое вы хотите отслеживать, и затем запустить сканирование сети с помощью Fing или Nmap.
Я лично поступил по старинке и заглянул в аренду DCHP адресов в настройках роутера.

1549984770799.png


Шаг 2. Необходимое оборудование.
После того, как мы получим необходимые MAC-адреса, нужно определиться что нам необходимо для построение “чудо-устройства”.
А нам необходимо иметь:
  • NodeMCU ESP8266.
  • Кабель Micro-USB.
  • Макетная плата.
  • Четырехконтактный трехцветный светодиод или столько светодиодов, сколько их требуется.
  • Компьютер с установленной Arduino IDE для программирования и прошивки.
  • Резистор(можно без него).

Шаг 3. Настройка IDE Arduino.
Прежде чем мы приступим к написанию кода, нам нужно настроить Arduino IDE для работы с NodeMCU. Для этого скопируйте следующий URL-адрес и вставьте его в поле - Файл - Настройки - Дополнительные ссылки для Менеджера плат:
  • , ,
Все эти ссылки необходимо вставить в поле Дополнительные ссылки для Менеджера плат.

1549985423131.png


Далее вам нужно добавить NodeMCU в Boards Manager .
Для этого вам нужно нажать «Инструменты», а затем навести курсор на раздел «Плата», чтобы увидеть раскрывающийся список поддерживаемых плат. Вверху нажмите «Менеджер плат», чтобы открыть окно, которое позволит нам добавить больше плат.
Когда откроется окно Boards Manager, введите «esp8266» в строку поиска. Выберите «esp8266» от «ESP8266 Community» и установите его, чтобы добавить поддержку NodeMCU в вашу Arduino IDE. Затем нужно выбрать «NodeMCU 1.0.».

1549985554367.png


1549985622441.png


Шаг 4. Скачиваем проект Friend Detector.
Затем мы можем скачать код для Friend Detector на GitHub , в форке оригинального проекта.
Ссылка: skickar/FriendDetector

Шаг 5. Смотрим код.
Чтобы понять, что делает этот код, давайте заглянем внутрь.
Первый раздел кода устанавливает переменные. Здесь мы определяем размер списка MAC-адресов, которые мы отслеживаем, фактические MAC-адреса в списке и имена целей, связанных с MAC-адресами в списке.

C-подобный:
uint8_t friendmac[LIST_SIZE][ESPPL_MAC_LEN] = {
  {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA} //blue
  , {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA} //green
  , {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA} //red
  , {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA} //yelow
};
/*
   This is your friend's name list
   put them in the same order as the MAC addresses
*/
String friendname[LIST_SIZE] = {
  "Sharp aquos s2" //blue
  , "Nexus 5" //green
  , "HTC" //red
  , "Onda" //yellow
};

Затем у нас есть раздел настроек, в котором мы устанавливаем выводы D5, D6, D7 и D8 для вывода, чтобы мы могли использовать их для управления светодиодами.

C-подобный:
pinMode(D5, OUTPUT);
pinMode(D6, OUTPUT);
pinMode(D7, OUTPUT);
pinMode(D8, OUTPUT);

Чтобы включить этот светодиод, нам просто нужно использовать функцию «digitalWrite (pin, mode)».
Наконец, у нас имеется функция под названием «turnoff ()», которые отключит все светодиоды, которые включены, если пакеты не обнаруживаются в течение достаточно долгого времени.
C-подобный:
void turnoff() {
  digitalWrite(D7, LOW), digitalWrite(D5, LOW), digitalWrite(D6, LOW), digitalWrite(D8, LOW);
}

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

Поэтому на данном этапе были добавлены свои таймеры для каждого устройства.
C-подобный:
int TimerBlue = 0;
int TimerGreen = 0;
int TimerRed = 0;
int TimerYellow = 0;

Теперь перейдем к той части кода, которая контролирует логику того, что происходит, когда мы обнаруживаем пакеты. Здесь мы видим строку, которая выглядит:
C-подобный:
for (int i=0; i<LIST_SIZE; i++) {
    if (maccmp(info->sourceaddr, friendmac[i]) || maccmp(info->receiveraddr, friendmac[i])) {

Здесь у нас имеется обычный цикл, который пытается сопоставить адреса отправителя и получателя в обнаруженном пакете с MAC-адресами в нашем списке(которые мы отслеживаем).

Вот фрагмент кода, который управляет тем, что происходит, когда мы обнаруживаем искомый MAC-адрес. Во-первых, мы видим, что мы печатаем имя устройства в последовательный порт, который вы открыть, щелкнув меню «Инструменты» в Arduino IDE, а затем выбрав опцию «Монитор последовательного порта».

1549986382583.png


C-подобный:
void cb(esppl_frame_info *info) {
  for (int i = 0; i < LIST_SIZE; i++) {
    if (maccmp(info->sourceaddr, friendmac[i]) || maccmp(info->receiveraddr, friendmac[i])) {
      Serial.printf("\n%s is here! :)", friendname[i].c_str());

Шаг 6. Настройка.
Теперь вы должны настроить некоторые настройки, а именно таймер и список MAC-адресов, которые мы будем отслеживать.
Для таймера я установил значение 100, но вы можете настроить его в зависимости от ваших потребностей.
Это означает, что каждый раз, когда мы обнаруживаем пакет с MAC, который мы ищем, светодиод будет гореть, пока не будет обнаружено 100 пакетов, которые не соответствуют ни одному из устройств в нашем списке, и при обнаружение одного из MAC остальные таймера также уменьшаются.
Я сделал это, чтобы обойти проблему с неспособностью создать задержку, чтобы держать светодиод включенным.
C-подобный:
if (i == 0) {
        TimerBlue = 1000;
        TimerGreen--;
        TimerRed--;
        TimerYellow--;
        blue();
        check();

Чтобы контролировать цвет светодиода, я использовал оператор «if», который говорит, что если мы обнаружили пакет с MAC-адресом, совпадающим с нашим в нашем списке, подсвечиваем цвет в соответствующий цвет.

Поскольку большинство списков в программировании начинаются с 0, примером может быть то, что первым MAC-адресом в списке будет индекс 0 и установлен синий цвет. Второй MAC-адрес будет индексом 1 и установлен в красный цвет. И третий будет индекс 2 и будет установлен в зеленый цвет.

1549988514468.png


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

Окончательный код должен выглядеть следующим образом:
C-подобный:
#include "./esppl_functions.h"
#include <ESP8266WiFi.h>
#define LIST_SIZE 4
/*
   This is your friend's MAC address list
  Format it by taking the mac address aa:bb:cc:dd:ee:ff
  and converting it to 0xaa,0xbb,0xcc,0xdd,0xee,0xff
*/
uint8_t friendmac[LIST_SIZE][ESPPL_MAC_LEN] = {
  {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA} //blue
  , {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA} //green
  , {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA} //red
  , {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA} //yelow
};
/*
   This is your friend's name list
   put them in the same order as the MAC addresses
*/
String friendname[LIST_SIZE] = {
  "Sharp aquos s2" //blue
  , "Nexus 5" //green
  , "HTC" //red
  , "Onda" //red
};

// start variables package - Skickar 2018 hardware LED for NodeMCU on mini breadboard //
void setup() {
  delay(500);
  pinMode(D5, OUTPUT); // sets the pins to output mode
  pinMode(D6, OUTPUT);
  pinMode(D7, OUTPUT);
  pinMode(D8, OUTPUT);
  Serial.begin(115200);
  esppl_init(cb);
}

/* You cannot use a time delay here to keep the LED on, so will need to use ratio of
  detected packets to overall packets to keep LED on for longer. If you try to use a
  delay to keep the light on for long enough to be useful, the watchdog timer kills the
  process and it dies */
int TimerBlue = 0;
int TimerGreen = 0;
int TimerRed = 0;
int TimerYellow = 0;

void red() {
  digitalWrite(D7, HIGH);
}  // Turn ON the red LED
void blue() {
  digitalWrite(D5, HIGH);
} // Turn ON the blue LED
void green() {
  digitalWrite(D6, HIGH);
} // Turn ON the green LED
void yellow(){
  digitalWrite(D8, HIGH);
}
void turnoff() {
  digitalWrite(D7, LOW), digitalWrite(D5, LOW), digitalWrite(D6, LOW), digitalWrite(D8, LOW);
}

/* end exparimental variable package */

bool maccmp(uint8_t *mac1, uint8_t *mac2) {
  for (int i = 0; i < ESPPL_MAC_LEN; i++) {
    if (mac1[i] != mac2[i]) {
      return false;
    }
  }
  return true;
}

void check(){
  if (TimerBlue > 0) {
    TimerBlue--;
  }
  if (TimerGreen > 0) {
    TimerGreen--;
  }
  if (TimerRed > 0){
    TimerRed--;
  }
  if (TimerYellow > 0){
    TimerYellow--;
  }
  if (TimerBlue <= 0){
    digitalWrite(D5, LOW);
  }
  if (TimerGreen <= 0){
    digitalWrite(D6, LOW);
  }
  if (TimerRed <= 0){
    digitalWrite(D7, LOW);
  }
  if (TimerYellow <= 0){
    digitalWrite(D8, LOW);
  }
}

void cb(esppl_frame_info *info) {
  for (int i = 0; i < LIST_SIZE; i++) {
    if (maccmp(info->sourceaddr, friendmac[i]) || maccmp(info->receiveraddr, friendmac[i])) {
      Serial.printf("\n%s is here! :)", friendname[i].c_str());
      if (i == 0) {
        TimerBlue = 1000;
        TimerGreen--;
        TimerRed--;
        TimerYellow--;
        blue();
        check();
      } // Here we turn on the blue LED until turnoff() is called
      else if(i == 1){
        TimerGreen = 1000;
        TimerBlue--;
        TimerRed--;
        TimerYellow--;
        green();
        check();
      }else if(i == 2){
        TimerRed = 1000;
        TimerBlue--;
        TimerGreen--;
        TimerYellow--;
        red();
        check();
      }else if (i ==3){
        TimerYellow = 1000;
        TimerBlue--;
        TimerGreen--;
        TimerRed--;
        yellow();
        check();
      }
    }else{
      check();
    }
  }
}


void loop() { // I didn't write this part but it sure looks fancy.
  esppl_sniffing_start();
  while (true) {
    for (int i = ESPPL_CHANNEL_MIN; i <= ESPPL_CHANNEL_MAX; i++ ) {
      esppl_set_channel(i);
      while (esppl_process_frames()) {
        //
      }
    }
  }
}

После этого мы можем скомпилировать проект нажав на галочку и замет залить наш скетч в плату NodeMCU.

1549986803032.png


Шаг 7. Сборка.
В этом коде я сохранил простоту компоновки, используя выводы D5, D6, D7 и D8 для управления светодиодами.
Если вы хотите сохранить свои светодиоды, я рекомендую вместо этого подключить выводы D5, D6, D7 и D8 к светодиоду в другом месте на плате, а затем добавить резистор (или потенциометр), чтобы уменьшить напряжение и продлить срок службы светодиодов.

1549987318071.png


Для тех кому не понятно, то черный провод соединяете с - на макетной плате и пином GND на NodeMCU.
Все остальные контакты D5, D6, D7, D8 с + светодиода.

После этого можно подключить USB-кабель и проверить работоспособность. Как только устройства из списка отслеживаемых отправит пакет, соответствующий светодиод загорится. Я лично долго тестировал и работало все на отлично.

Полный код можете получить выше.
Если у вас появятся вопросы - готов ответить, а на этом все. Спасибо за внимание.

1549988200782.png


1549988252693.png
 
A

arsof

Если честно, вообще не понимаю,зачем оно нужно? даже в доме двухэтажном можно узнать кто дома, на крайняк от оператора подключить местоположение телефона, по моему намного проще, чем брать хлам. Может мелко мыслю, поправь) Да еще и вай-фай, а если кто то принципиально пользуется орехом)
 
  • Нравится
Реакции: Super

Debug

Red Team
07.07.2017
217
445
BIT
0
Если честно, вообще не понимаю,зачем оно нужно? даже в доме двухэтажном можно узнать кто дома, на крайняк от оператора подключить местоположение телефона, по моему намного проще, чем брать хлам. Может мелко мыслю, поправь) Да еще и вай-фай, а если кто то принципиально пользуется орехом)
Здесь все очень просто, стоит учесть что NodeMCU это в первую очередь платформа для IoT, и перед нами открывается удобная возможность, например, включать чайник когда пришел глава семейства и включать аудиосистему когда пришел x человек.
 

cherubot

Green Team
08.11.2017
40
19
BIT
0
Можно глупый вопрос задам. А разве после ребута загруженный скетч не сбросится? Я думал для esp надо прошивку со скетчем собирать и прошивать. Хотя скорее всего ошибаюсь. Поправьте если не так. Игрался с esp01.
 

Debug

Red Team
07.07.2017
217
445
BIT
0
Можно глупый вопрос задам. А разве после ребута загруженный скетч не сбросится? Я думал для esp надо прошивку со скетчем собирать и прошивать. Хотя скорее всего ошибаюсь. Поправьте если не так. Игрался с esp01.
После ребута ничего не слетает, как может слитеть прошивка? Нужные MAC - адреса жёстко закодированы).
 
Последнее редактирование:

Sdr

Green Team
20.01.2016
116
59
BIT
0
Debug, а можно по такому же принципу используя такое же железо сделать немного другой проект. Может ли данное устройство посылать запросы, сканировать сети в радиусе действия устройства, по аналогу Comm View WiFi. И если в этом радиусе появляется телефон, планшет, ноут, все у чего есть мак адрес и вайфай, ранее забитый в устройство, то устройство сигнализирует светодиодом?
 

Debug

Red Team
07.07.2017
217
445
BIT
0
Debug, а можно по такому же принципу используя такое же железо сделать немного другой проект. Может ли данное устройство посылать запросы, сканировать сети в радиусе действия устройства, по аналогу Comm View WiFi. И если в этом радиусе появляется телефон, планшет, ноут, все у чего есть мак адрес и вайфай, ранее забитый в устройство, то устройство сигнализирует светодиодом?
Я не совсем понял вас, но для получение списка окружающих устройств зачем посылать какие-то запросы(максимум пакет деаутентификации, для получение Probe Frame)?

Намного проще просто сниффить все пакеты и разбирать что и кому летит.

Теперь скажу пару слов о Comm View WiFi. Этот инструмент как раз и захватывает все сетевые пакеты, передаваемые в эфире(принцип такой же). То есть по сути - это просто сниффер.
 

Sdr

Green Team
20.01.2016
116
59
BIT
0
Debug
Наверное я не совсем правильно изъяснил суть идеи) Каждое устройство wi-fi имеет свой радиус покрытия, много факторов, антенны, усиление, зеркалки от стен зданий и прочее, не суть важно. Так вот, скажем устройство №1 - смартфон, имеет свой мac. Esp8266 знает mac устройства №1 и в случае попадания самого устройства в радиус действия Esp8266, оно об этом сигнализирует. Своего рода сниффер с трекером. Второй пример. Зная маc смартфона человека которого надо найти и зная примерно его место нахождение с помощью Esp8266 можно значительно сократить радиус поиска. Я думаю смысл понятен)
 
H

hoveriron

Шикарная разработка. Также можно, наверняка, включать тревогу, если появился неизвестный MAC там, где никто не должен появляться? :)
В одном из проектов я делал запрос с веб сервера к роутеру и получал активные MAC.
 
  • Нравится
Реакции: Debug

Debug

Red Team
07.07.2017
217
445
BIT
0
Шикарная разработка. Также можно, наверняка, включать тревогу, если появился неизвестный MAC там, где никто не должен появляться? :)
В одном из проектов я делал запрос с веб сервера к роутеру и получал активные MAC.
Да можно предпринимать какие-либо действия в случае обнаружения чужого устройства и отправлять уведомление на телефон и т.п.
 
T

Taigar

Хотелось бы уточнить:
Вы не рассматривали возможность запоминать время прихода последнего пакета от устройства Х, и затем сверять время последнего пакета от устройства Х с нынешним временем, и дальше делать выбор - выключать диод или оставить его гореть.
Данный способ, как и проверка на n последних пакетов, позволяет устройству в режиме реального времени продолжать принимать пакеты.
 

Debug

Red Team
07.07.2017
217
445
BIT
0
Хотелось бы уточнить:
Вы не рассматривали возможность запоминать время прихода последнего пакета от устройства Х, и затем сверять время последнего пакета от устройства Х с нынешним временем, и дальше делать выбор - выключать диод или оставить его гореть.
Данный способ, как и проверка на n последних пакетов, позволяет устройству в режиме реального времени продолжать принимать пакеты.
Для получение информации об устройстве в реальном времени, как раз и используется таймер. К таймеру присваивается значение, которое стремиться к нулю(происходит отключение светодиода). Этот подход ничем не хуже и отображает актуальное состояние.
 
А

Александр Щемелев

Здрвствуйте, можете пожалуста мне написать кусок кода который будет просто брать все MAC адресса вокруг себя. Спасибо!
 

Debug

Red Team
07.07.2017
217
445
BIT
0
26.12.2019
1
0
BIT
0
Подскажите, а реально ли все это поднять на малине? Если да то как, если нет то что надо изменить что бы esp отправлял по http 1 когда появился нужный мак адрес.
Хочу прикрутить эту чудо возможность к умному дому Мажордомо.
 

Debug

Red Team
07.07.2017
217
445
BIT
0
Подскажите, а реально ли все это поднять на малине? Если да то как, если нет то что надо изменить что бы esp отправлял по http 1 когда появился нужный мак адрес.
Хочу прикрутить эту чудо возможность к умному дому Мажордомо.
Думаю что можно, но как реализовать с ходу не отвечу (хотя в теории должно быть легче)
 

Nubusers

Green Team
23.07.2019
55
21
BIT
0
Прикольно. Пару вопросов. Какова стоимость сее чудо? И сколько ушло времени на сборку и на то, чтобы придумать это сделать. И из личного опыта - пригодилось?
 

Debug

Red Team
07.07.2017
217
445
BIT
0
Прикольно. Пару вопросов. Какова стоимость сее чудо? И сколько ушло времени на сборку и на то, чтобы придумать это сделать. И из личного опыта - пригодилось?
Сама плата NodeMCU около 400 руб, светодиоды по 10 руб за каждый, макетная плата 100 руб.
Проект был реализован в течение двух дней и да он пригодился)
 

lvd

New member
31.12.2019
3
0
BIT
0
А по какому признаку можно понять, что frame отправлен клиентом (а не роутером)? И наоборот - клиенту?

В статье сказано, что при wlan.fc.type_subtype==4 (Probe Request) идёт запрос от клиента на поиск сетей, попробовал на своих гаджетах - ни один не отправил такой фрейм. Может ещё есть какой-то способ понять, что фрейм от клиента?
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!