From 973189a127c7ec4b2fcbf477653a82bb02e4954c Mon Sep 17 00:00:00 2001 From: Sam Denty Date: Wed, 9 Aug 2017 17:36:13 +0100 Subject: [PATCH 1/4] Add Cache-control headers to Javascript & CSS Every time a page is (re)loaded, the ESP8266 has to send the stylesheet and javascript before the page loads. Although this is minimal (20ms in dev tools Networks pane), it can improve page load speeds when the client device is spamming network connectivity check requests. Adding the `Cache-Control` headers makes the browser store these files in memory (for 300 seconds, could be increased). The same could be done for the HTML files, but that would allow the pages to load even when not connected to the ESP8266. --- esp8266_deauther/esp8266_deauther.ino | 1425 +++++++++++++------------ 1 file changed, 716 insertions(+), 709 deletions(-) diff --git a/esp8266_deauther/esp8266_deauther.ino b/esp8266_deauther/esp8266_deauther.ino index 69f607f..80bee61 100644 --- a/esp8266_deauther/esp8266_deauther.ino +++ b/esp8266_deauther/esp8266_deauther.ino @@ -1,710 +1,717 @@ -/* - =========================================== - Copyright (c) 2017 Stefan Kremser - github.com/spacehuhn - =========================================== -*/ - -// Including some libraries we need // -#include - -#include -#include -#include - - -// Settings // - -//#define USE_DISPLAY /* <-- uncomment that if you want to use the display */ -#define resetPin 4 /* <-- comment out or change if you need GPIO 4 for other purposes */ -#define USE_LED16 /* <-- for the Pocket ESP8266 which has a LED on GPIO 16 to indicate if it's running */ - - -// Including everything for the OLED // -#ifdef USE_DISPLAY - #include - - //include the library you need - #include "SSD1306.h" - #include "SH1106.h" - - //create display(Adr, SDA-pin, SCL-pin) - SSD1306 display(0x3c, 5, 4); //GPIO 5 = D1, GPIO 4 = D2 - //SH1106 display(0x3c, 5, 4); - - //button pins - #define upBtn 12 //GPIO 12 = D6 - #define downBtn 13 //GPIO 13 = D7 - #define selectBtn 14 //GPIO 14 = D5 - #define displayBtn 0 //GPIO 0 = FLASH BUTTON - - //render settings - #define fontSize 8 - #define rowsPerSite 8 - - int rows = 4; - int curRow = 0; - int sites = 1; - int curSite = 1; - int lrow = 0; - - int menu = 0; //0 = Main Menu, 1 = APs, 2 = Stations, 3 = Attacks, 4 = Monitor - - bool canBtnPress = true; - int buttonPressed = 0; //0 = UP, 1 = DOWN, 2 = SELECT, 3 = DISPLAY - bool displayOn = true; -#endif - -// More Includes! // -extern "C" { - #include "user_interface.h" -} - -ESP8266WebServer server(80); - -#include -#include "data.h" -#include "NameList.h" -#include "APScan.h" -#include "ClientScan.h" -#include "Attack.h" -#include "Settings.h" -#include "SSIDList.h" - -/* ========== DEBUG ========== */ -const bool debug = true; -/* ========== DEBUG ========== */ - -// Run-Time Variables // -String wifiMode = ""; -String attackMode_deauth = ""; -String attackMode_beacon = ""; -String scanMode = "SCAN"; - -bool warning = true; - -NameList nameList; - -APScan apScan; -ClientScan clientScan; -Attack attack; -Settings settings; -SSIDList ssidList; - -void sniffer(uint8_t *buf, uint16_t len) { - clientScan.packetSniffer(buf, len); -} - -#ifdef USE_DISPLAY -void drawInterface() { - if(displayOn){ - - display.clear(); - - int _lrow = 0; - for (int i = curSite * rowsPerSite - rowsPerSite; i < curSite * rowsPerSite; i++) { - if (i == 0) display.drawString(3, i * fontSize, "-> WiFi " + wifiMode); - else if (i == 1) display.drawString(3, i * fontSize, "-> " + scanMode); - else if (i == 2) display.drawString(3, i * fontSize, "-> " + attackMode_deauth + " deauth"); - else if (i == 3) display.drawString(3, i * fontSize, "-> " + attackMode_beacon + " beacon flood"); - else if (i - 4 < apScan.results) { - display.drawString(4, _lrow * fontSize, apScan.getAPName(i - 4)); - if (apScan.isSelected(i - 4)) { - display.drawVerticalLine(1, _lrow * fontSize, fontSize); - display.drawVerticalLine(2, _lrow * fontSize, fontSize); - } - } - if (_lrow == lrow) display.drawVerticalLine(0, _lrow * fontSize, fontSize); - _lrow++; - } - - display.display(); - } -} -#endif - -void startWifi() { - Serial.println("\nStarting WiFi AP:"); - WiFi.mode(WIFI_STA); - wifi_set_promiscuous_rx_cb(sniffer); - WiFi.softAP((const char*)settings.ssid.c_str(), (const char*)settings.password.c_str(), settings.apChannel, settings.ssidHidden); //for an open network without a password change to: WiFi.softAP(ssid); - Serial.println("SSID : '" + settings.ssid+"'"); - Serial.println("Password : '" + settings.password+"'"); - Serial.println("-----------------------------------------------"); - if (settings.password.length() < 8) Serial.println("WARNING: password must have at least 8 characters!"); - if (settings.ssid.length() < 1 || settings.ssid.length() > 32) Serial.println("WARNING: SSID length must be between 1 and 32 characters!"); - wifiMode = "ON"; -} - -void stopWifi() { - Serial.println("stopping WiFi AP"); - Serial.println("-----------------------------------------------"); - WiFi.disconnect(); - wifi_set_opmode(STATION_MODE); - wifiMode = "OFF"; -} - -void loadIndexHTML() { - if(warning){ - sendFile(200, "text/html", data_indexHTML, sizeof(data_indexHTML)); - }else{ - sendFile(200, "text/html", data_apscanHTML, sizeof(data_apscanHTML)); - } -} -void loadAPScanHTML() { - warning = false; - sendFile(200, "text/html", data_apscanHTML, sizeof(data_apscanHTML)); -} -void loadStationsHTML() { - sendFile(200, "text/html", data_stationsHTML, sizeof(data_stationsHTML)); -} -void loadAttackHTML() { - sendFile(200, "text/html", data_attackHTML, sizeof(data_attackHTML)); -} -void loadSettingsHTML() { - sendFile(200, "text/html", data_settingsHTML, sizeof(data_settingsHTML)); -} -void load404() { - sendFile(200, "text/html", data_errorHTML, sizeof(data_errorHTML)); -} -void loadInfoHTML(){ - sendFile(200, "text/html", data_infoHTML, sizeof(data_infoHTML)); -} -void loadLicense(){ - sendFile(200, "text/plain", data_license, sizeof(data_license)); -} - -void loadFunctionsJS() { - sendFile(200, "text/javascript", data_js_functionsJS, sizeof(data_js_functionsJS)); -} -void loadAPScanJS() { - sendFile(200, "text/javascript", data_js_apscanJS, sizeof(data_js_apscanJS)); -} -void loadStationsJS() { - sendFile(200, "text/javascript", data_js_stationsJS, sizeof(data_js_stationsJS)); -} -void loadAttackJS() { - attack.ssidChange = true; - sendFile(200, "text/javascript", data_js_attackJS, sizeof(data_js_attackJS)); -} -void loadSettingsJS() { - sendFile(200, "text/javascript", data_js_settingsJS, sizeof(data_js_settingsJS)); -} - -void loadStyle() { - sendFile(200, "text/css;charset=UTF-8", data_styleCSS, sizeof(data_styleCSS)); -} - - -void startWiFi(bool start) { - if (start) startWifi(); - else stopWifi(); - clientScan.clearList(); -} - -//==========AP-Scan========== -void startAPScan() { - scanMode = "scanning..."; -#ifdef USE_DISPLAY - drawInterface(); -#endif - if (apScan.start()) { - -#ifdef USE_DISPLAY - apScan.sort(); - rows = 4; - rows += apScan.results; - sites = rows / rowsPerSite; - if (rows % rowsPerSite > 0) sites++; -#endif - - server.send ( 200, "text/json", "true"); - attack.stopAll(); - scanMode = "SCAN"; - } -} - -void sendAPResults() { - apScan.sendResults(); -} - -void selectAP() { - if (server.hasArg("num")) { - apScan.select(server.arg("num").toInt()); - server.send( 200, "text/json", "true"); - attack.stopAll(); - } -} - -//==========Client-Scan========== -void startClientScan() { - if (server.hasArg("time") && apScan.getFirstTarget() > -1 && !clientScan.sniffing) { - server.send(200, "text/json", "true"); - clientScan.start(server.arg("time").toInt()); - attack.stopAll(); - } else server.send( 200, "text/json", "Error: no selected access point"); -} - -void sendClientResults() { - clientScan.send(); -} -void sendClientScanTime() { - server.send( 200, "text/json", (String)settings.clientScanTime ); -} - -void selectClient() { - if (server.hasArg("num")) { - clientScan.select(server.arg("num").toInt()); - attack.stop(0); - server.send( 200, "text/json", "true"); - } -} - -void addClientFromList(){ - if(server.hasArg("num")) { - int _num = server.arg("num").toInt(); - clientScan.add(nameList.getMac(_num)); - - server.send( 200, "text/json", "true"); - }else server.send( 200, "text/json", "false"); -} - -void setClientName() { - if (server.hasArg("id") && server.hasArg("name")) { - if(server.arg("name").length()>0){ - nameList.add(clientScan.getClientMac(server.arg("id").toInt()), server.arg("name")); - server.send( 200, "text/json", "true"); - } - else server.send( 200, "text/json", "false"); - } -} - -void deleteName() { - if (server.hasArg("num")) { - int _num = server.arg("num").toInt(); - nameList.remove(_num); - server.send( 200, "text/json", "true"); - }else server.send( 200, "text/json", "false"); -} - -void clearNameList() { - nameList.clear(); - server.send( 200, "text/json", "true" ); -} - -void editClientName() { - if (server.hasArg("id") && server.hasArg("name")) { - nameList.edit(server.arg("id").toInt(), server.arg("name")); - server.send( 200, "text/json", "true"); - }else server.send( 200, "text/json", "false"); -} - -void addClient(){ - if(server.hasArg("mac") && server.hasArg("name")){ - String macStr = server.arg("mac"); - macStr.replace(":",""); - Serial.println("add "+macStr+" - "+server.arg("name")); - if(macStr.length() < 12 || macStr.length() > 12) server.send( 200, "text/json", "false"); - else{ - Mac _newClient; - for(int i=0;i<6;i++){ - const char* val = macStr.substring(i*2,i*2+2).c_str(); - uint8_t valByte = strtoul(val, NULL, 16); - Serial.print(valByte,HEX); - Serial.print(":"); - _newClient.setAt(valByte,i); - } - Serial.println(); - nameList.add(_newClient,server.arg("name")); - server.send( 200, "text/json", "true"); - } - } -} - -//==========Attack========== -void sendAttackInfo() { - attack.sendResults(); -} - -void startAttack() { - if (server.hasArg("num")) { - int _attackNum = server.arg("num").toInt(); - if (apScan.getFirstTarget() > -1 || _attackNum == 1 || _attackNum == 2) { - attack.start(server.arg("num").toInt()); - server.send ( 200, "text/json", "true"); - } else server.send( 200, "text/json", "false"); - } -} - -void addSSID() { - if(server.hasArg("ssid") && server.hasArg("num") && server.hasArg("enc")){ - int num = server.arg("num").toInt(); - if(num > 0){ - ssidList.addClone(server.arg("ssid"),num, server.arg("enc") == "true"); - }else{ - ssidList.add(server.arg("ssid"), server.arg("enc") == "true" || server.arg("enc") == "1"); - } - attack.ssidChange = true; - server.send( 200, "text/json", "true"); - }else server.send( 200, "text/json", "false"); -} - -void cloneSelected(){ - if(apScan.selectedSum > 0){ - int clonesPerSSID = 48/apScan.selectedSum; - ssidList.clear(); - for(int i=0;i= 1 && server.arg("apChannel").toInt() <= 14) { - settings.apChannel = server.arg("apChannel").toInt(); - } - } - if (server.hasArg("macAp")) { - String macStr = server.arg("macAp"); - macStr.replace(":",""); - Mac tempMac; - if(macStr.length() == 12){ - for(int i=0;i<6;i++){ - const char* val = macStr.substring(i*2,i*2+2).c_str(); - uint8_t valByte = strtoul(val, NULL, 16); - tempMac.setAt(valByte,i); - } - if(tempMac.valid()) settings.macAP.set(tempMac); - } else if(macStr.length() == 0){ - settings.macAP.set(settings.defaultMacAP); - } - } - if (server.hasArg("randMacAp")) { - if (server.arg("randMacAp") == "false") settings.isMacAPRand = false; - else settings.isMacAPRand = true; - } - if (server.hasArg("scanTime")) settings.clientScanTime = server.arg("scanTime").toInt(); - if (server.hasArg("timeout")) settings.attackTimeout = server.arg("timeout").toInt(); - if (server.hasArg("deauthReason")) settings.deauthReason = server.arg("deauthReason").toInt(); - if (server.hasArg("packetRate")) settings.attackPacketRate = server.arg("packetRate").toInt(); - if (server.hasArg("apScanHidden")) { - if (server.arg("apScanHidden") == "false") settings.apScanHidden = false; - else settings.apScanHidden = true; - } - if (server.hasArg("beaconInterval")) { - if (server.arg("beaconInterval") == "false") settings.beaconInterval = false; - else settings.beaconInterval = true; - } - if (server.hasArg("useLed")) { - if (server.arg("useLed") == "false") settings.useLed = false; - else settings.useLed = true; - attack.refreshLed(); - } - if (server.hasArg("channelHop")) { - if (server.arg("channelHop") == "false") settings.channelHop = false; - else settings.channelHop = true; - } - if (server.hasArg("multiAPs")) { - if (server.arg("multiAPs") == "false") settings.multiAPs = false; - else settings.multiAPs = true; - } - if (server.hasArg("multiAttacks")) { - if (server.arg("multiAttacks") == "false") settings.multiAttacks = false; - else settings.multiAttacks = true; - } - - if (server.hasArg("ledPin")) settings.setLedPin(server.arg("ledPin").toInt()); - if(server.hasArg("macInterval")) settings.macInterval = server.arg("macInterval").toInt(); - - settings.save(); - server.send( 200, "text/json", "true" ); -} - -void resetSettings() { - settings.reset(); - server.send( 200, "text/json", "true" ); -} - -void setup() { - - randomSeed(os_random()); - -#ifdef USE_LED16 - pinMode(16, OUTPUT); - digitalWrite(16, LOW); -#endif - - Serial.begin(115200); - - attackMode_deauth = "START"; - attackMode_beacon = "START"; - - EEPROM.begin(4096); - SPIFFS.begin(); - - settings.load(); - if (debug) settings.info(); - settings.syncMacInterface(); - nameList.load(); - ssidList.load(); - - attack.refreshLed(); - - delay(500); // Prevent bssid leak - - startWifi(); - attack.stopAll(); - attack.generate(); - - /* ========== Web Server ========== */ - - /* HTML */ - server.onNotFound(load404); - - server.on("/", loadIndexHTML); - server.on("/index.html", loadIndexHTML); - server.on("/apscan.html", loadAPScanHTML); - server.on("/stations.html", loadStationsHTML); - server.on("/attack.html", loadAttackHTML); - server.on("/settings.html", loadSettingsHTML); - server.on("/info.html", loadInfoHTML); - server.on("/license", loadLicense); - - /* JS */ - server.on("/js/apscan.js", loadAPScanJS); - server.on("/js/stations.js", loadStationsJS); - server.on("/js/attack.js", loadAttackJS); - server.on("/js/settings.js", loadSettingsJS); - server.on("/js/functions.js", loadFunctionsJS); - - /* CSS */ - server.on ("/style.css", loadStyle); - - /* JSON */ - server.on("/APScanResults.json", sendAPResults); - server.on("/APScan.json", startAPScan); - server.on("/APSelect.json", selectAP); - server.on("/ClientScan.json", startClientScan); - server.on("/ClientScanResults.json", sendClientResults); - server.on("/ClientScanTime.json", sendClientScanTime); - server.on("/clientSelect.json", selectClient); - server.on("/setName.json", setClientName); - server.on("/addClientFromList.json", addClientFromList); - server.on("/attackInfo.json", sendAttackInfo); - server.on("/attackStart.json", startAttack); - server.on("/settings.json", getSettings); - server.on("/settingsSave.json", saveSettings); - server.on("/settingsReset.json", resetSettings); - server.on("/deleteName.json", deleteName); - server.on("/clearNameList.json", clearNameList); - server.on("/editNameList.json", editClientName); - server.on("/addSSID.json", addSSID); - server.on("/cloneSelected.json", cloneSelected); - server.on("/deleteSSID.json", deleteSSID); - server.on("/randomSSID.json", randomSSID); - server.on("/clearSSID.json", clearSSID); - server.on("/resetSSID.json", resetSSID); - server.on("/saveSSID.json", saveSSID); - server.on("/restartESP.json", restartESP); - server.on("/addClient.json",addClient); - server.on("/enableRandom.json",enableRandom); - - server.begin(); - -#ifdef USE_DISPLAY - display.init(); - display.flipScreenVertically(); - pinMode(upBtn, INPUT_PULLUP); - pinMode(downBtn, INPUT_PULLUP); - pinMode(selectBtn, INPUT_PULLUP); - if(displayBtn == 0) pinMode(displayBtn, INPUT); - else pinMode(displayBtn, INPUT_PULLUP); - - display.clear(); - display.setFont(ArialMT_Plain_16); - display.drawString(0, 0, "ESP8266"); - display.setFont(ArialMT_Plain_24); - display.drawString(0, 16, "Deauther"); - display.setFont(ArialMT_Plain_10); - display.drawString(100, 28, "v"); - display.setFont(ArialMT_Plain_16); - display.drawString(104, 24, "1.6"); - display.setFont(ArialMT_Plain_10); - display.drawString(0, 40, "Copyright (c) 2017"); - display.drawString(0, 50, "Stefan Kremser"); - display.display(); - - display.setFont(Roboto_Mono_8); - - delay(1600); -#endif - -#ifdef resetPin - pinMode(resetPin, INPUT_PULLUP); - if(digitalRead(resetPin) == LOW) settings.reset(); -#endif - - if(debug){ - Serial.println("\nStarting...\n"); -#ifndef USE_DISPLAY - delay(1600); -#endif - } -} - -void loop() { - if (clientScan.sniffing) { - if (clientScan.stop()) startWifi(); - } else { - server.handleClient(); - attack.run(); - } - - if(Serial.available()){ - String input = Serial.readString(); - if(input == "reset" || input == "reset\n" || input == "reset\r" || input == "reset\r\n"){ - settings.reset(); - } - } - -#ifdef USE_DISPLAY - - if (digitalRead(upBtn) == LOW || digitalRead(downBtn) == LOW || digitalRead(selectBtn) == LOW || digitalRead(displayBtn) == LOW){ - if(canBtnPress){ - if(digitalRead(upBtn) == LOW) buttonPressed = 0; - else if(digitalRead(downBtn) == LOW) buttonPressed = 1; - else if(digitalRead(selectBtn) == LOW) buttonPressed = 2; - else if(digitalRead(displayBtn) == LOW) buttonPressed = 3; - canBtnPress = false; - } - }else if(!canBtnPress){ - canBtnPress = true; - - // ===== UP ===== - if (buttonPressed == 0 && curRow > 0) { - curRow--; - if (lrow - 1 < 0) { - lrow = rowsPerSite - 1; - curSite--; - } else lrow--; - - // ===== DOWN ===== - } else if (buttonPressed == 1 && curRow < rows - 1) { - curRow++; - if (lrow + 1 >= rowsPerSite) { - lrow = 0; - curSite++; - } else lrow++; - - // ===== SELECT ===== - } else if (buttonPressed == 2) { - - // ===== WIFI on/off ===== - if (curRow == 0) { - if (wifiMode == "ON") stopWifi(); - else startWifi(); - - // ===== scan for APs ===== - } else if (curRow == 1) { - startAPScan(); - drawInterface(); - - // ===== start,stop deauth attack ===== - } else if (curRow == 2) { - if (attackMode_deauth == "START" && apScan.getFirstTarget() > -1) attack.start(0); - else if (attackMode_deauth == "STOP") attack.stop(0); - - // ===== start,stop beacon attack ===== - } else if (curRow == 3) { - if (attackMode_beacon == "START"){ - - //clone all selected SSIDs - if(apScan.selectedSum > 0){ - int clonesPerSSID = 48/apScan.selectedSum; - ssidList.clear(); - for(int i=0;i= 4) { - attack.stop(0); - apScan.select(curRow - 4); - } - } - // ===== DISPLAY ===== - else if (buttonPressed == 3) { - displayOn = !displayOn; - display.clear(); - display.display(); - } - } - drawInterface(); -#endif - +/* + =========================================== + Copyright (c) 2017 Stefan Kremser + github.com/spacehuhn + =========================================== +*/ + +// Including some libraries we need // +#include + +#include +#include +#include + + +// Settings // + +//#define USE_DISPLAY /* <-- uncomment that if you want to use the display */ +#define resetPin 4 /* <-- comment out or change if you need GPIO 4 for other purposes */ +#define USE_LED16 /* <-- for the Pocket ESP8266 which has a LED on GPIO 16 to indicate if it's running */ + + +// Including everything for the OLED // +#ifdef USE_DISPLAY + #include + + //include the library you need + #include "SSD1306.h" + #include "SH1106.h" + + //create display(Adr, SDA-pin, SCL-pin) + SSD1306 display(0x3c, 5, 4); //GPIO 5 = D1, GPIO 4 = D2 + //SH1106 display(0x3c, 5, 4); + + //button pins + #define upBtn 12 //GPIO 12 = D6 + #define downBtn 13 //GPIO 13 = D7 + #define selectBtn 14 //GPIO 14 = D5 + #define displayBtn 0 //GPIO 0 = FLASH BUTTON + + //render settings + #define fontSize 8 + #define rowsPerSite 8 + + int rows = 4; + int curRow = 0; + int sites = 1; + int curSite = 1; + int lrow = 0; + + int menu = 0; //0 = Main Menu, 1 = APs, 2 = Stations, 3 = Attacks, 4 = Monitor + + bool canBtnPress = true; + int buttonPressed = 0; //0 = UP, 1 = DOWN, 2 = SELECT, 3 = DISPLAY + bool displayOn = true; +#endif + +// More Includes! // +extern "C" { + #include "user_interface.h" +} + +ESP8266WebServer server(80); + +#include +#include "data.h" +#include "NameList.h" +#include "APScan.h" +#include "ClientScan.h" +#include "Attack.h" +#include "Settings.h" +#include "SSIDList.h" + +/* ========== DEBUG ========== */ +const bool debug = true; +/* ========== DEBUG ========== */ + +// Run-Time Variables // +String wifiMode = ""; +String attackMode_deauth = ""; +String attackMode_beacon = ""; +String scanMode = "SCAN"; + +bool warning = true; + +NameList nameList; + +APScan apScan; +ClientScan clientScan; +Attack attack; +Settings settings; +SSIDList ssidList; + +void sniffer(uint8_t *buf, uint16_t len) { + clientScan.packetSniffer(buf, len); +} + +#ifdef USE_DISPLAY +void drawInterface() { + if(displayOn){ + + display.clear(); + + int _lrow = 0; + for (int i = curSite * rowsPerSite - rowsPerSite; i < curSite * rowsPerSite; i++) { + if (i == 0) display.drawString(3, i * fontSize, "-> WiFi " + wifiMode); + else if (i == 1) display.drawString(3, i * fontSize, "-> " + scanMode); + else if (i == 2) display.drawString(3, i * fontSize, "-> " + attackMode_deauth + " deauth"); + else if (i == 3) display.drawString(3, i * fontSize, "-> " + attackMode_beacon + " beacon flood"); + else if (i - 4 < apScan.results) { + display.drawString(4, _lrow * fontSize, apScan.getAPName(i - 4)); + if (apScan.isSelected(i - 4)) { + display.drawVerticalLine(1, _lrow * fontSize, fontSize); + display.drawVerticalLine(2, _lrow * fontSize, fontSize); + } + } + if (_lrow == lrow) display.drawVerticalLine(0, _lrow * fontSize, fontSize); + _lrow++; + } + + display.display(); + } +} +#endif + +void startWifi() { + Serial.println("\nStarting WiFi AP:"); + WiFi.mode(WIFI_STA); + wifi_set_promiscuous_rx_cb(sniffer); + WiFi.softAP((const char*)settings.ssid.c_str(), (const char*)settings.password.c_str(), settings.apChannel, settings.ssidHidden); //for an open network without a password change to: WiFi.softAP(ssid); + Serial.println("SSID : '" + settings.ssid+"'"); + Serial.println("Password : '" + settings.password+"'"); + Serial.println("-----------------------------------------------"); + if (settings.password.length() < 8) Serial.println("WARNING: password must have at least 8 characters!"); + if (settings.ssid.length() < 1 || settings.ssid.length() > 32) Serial.println("WARNING: SSID length must be between 1 and 32 characters!"); + wifiMode = "ON"; +} + +void stopWifi() { + Serial.println("stopping WiFi AP"); + Serial.println("-----------------------------------------------"); + WiFi.disconnect(); + wifi_set_opmode(STATION_MODE); + wifiMode = "OFF"; +} + +void loadIndexHTML() { + if(warning){ + sendFile(200, "text/html", data_indexHTML, sizeof(data_indexHTML)); + }else{ + sendFile(200, "text/html", data_apscanHTML, sizeof(data_apscanHTML)); + } +} +void loadAPScanHTML() { + warning = false; + sendFile(200, "text/html", data_apscanHTML, sizeof(data_apscanHTML)); +} +void loadStationsHTML() { + sendFile(200, "text/html", data_stationsHTML, sizeof(data_stationsHTML)); +} +void loadAttackHTML() { + sendFile(200, "text/html", data_attackHTML, sizeof(data_attackHTML)); +} +void loadSettingsHTML() { + sendFile(200, "text/html", data_settingsHTML, sizeof(data_settingsHTML)); +} +void load404() { + sendFile(200, "text/html", data_errorHTML, sizeof(data_errorHTML)); +} +void loadInfoHTML(){ + sendFile(200, "text/html", data_infoHTML, sizeof(data_infoHTML)); +} +void loadLicense(){ + server.sendHeader("Cache-Control", "max-age=1000"); + sendFile(200, "text/plain", data_license, sizeof(data_license)); +} + +void loadFunctionsJS() { + server.sendHeader("Cache-Control", "max-age=300"); + sendFile(200, "text/javascript", data_js_functionsJS, sizeof(data_js_functionsJS)); +} +void loadAPScanJS() { + server.sendHeader("Cache-Control", "max-age=300"); + sendFile(200, "text/javascript", data_js_apscanJS, sizeof(data_js_apscanJS)); +} +void loadStationsJS() { + server.sendHeader("Cache-Control", "max-age=300"); + sendFile(200, "text/javascript", data_js_stationsJS, sizeof(data_js_stationsJS)); +} +void loadAttackJS() { + attack.ssidChange = true; + server.sendHeader("Cache-Control", "max-age=300"); + sendFile(200, "text/javascript", data_js_attackJS, sizeof(data_js_attackJS)); +} +void loadSettingsJS() { + server.sendHeader("Cache-Control", "max-age=300"); + sendFile(200, "text/javascript", data_js_settingsJS, sizeof(data_js_settingsJS)); +} + +void loadStyle() { + server.sendHeader("Cache-Control", "max-age=300"); + sendFile(200, "text/css;charset=UTF-8", data_styleCSS, sizeof(data_styleCSS)); +} + + +void startWiFi(bool start) { + if (start) startWifi(); + else stopWifi(); + clientScan.clearList(); +} + +//==========AP-Scan========== +void startAPScan() { + scanMode = "scanning..."; +#ifdef USE_DISPLAY + drawInterface(); +#endif + if (apScan.start()) { + +#ifdef USE_DISPLAY + apScan.sort(); + rows = 4; + rows += apScan.results; + sites = rows / rowsPerSite; + if (rows % rowsPerSite > 0) sites++; +#endif + + server.send ( 200, "text/json", "true"); + attack.stopAll(); + scanMode = "SCAN"; + } +} + +void sendAPResults() { + apScan.sendResults(); +} + +void selectAP() { + if (server.hasArg("num")) { + apScan.select(server.arg("num").toInt()); + server.send( 200, "text/json", "true"); + attack.stopAll(); + } +} + +//==========Client-Scan========== +void startClientScan() { + if (server.hasArg("time") && apScan.getFirstTarget() > -1 && !clientScan.sniffing) { + server.send(200, "text/json", "true"); + clientScan.start(server.arg("time").toInt()); + attack.stopAll(); + } else server.send( 200, "text/json", "Error: no selected access point"); +} + +void sendClientResults() { + clientScan.send(); +} +void sendClientScanTime() { + server.send( 200, "text/json", (String)settings.clientScanTime ); +} + +void selectClient() { + if (server.hasArg("num")) { + clientScan.select(server.arg("num").toInt()); + attack.stop(0); + server.send( 200, "text/json", "true"); + } +} + +void addClientFromList(){ + if(server.hasArg("num")) { + int _num = server.arg("num").toInt(); + clientScan.add(nameList.getMac(_num)); + + server.send( 200, "text/json", "true"); + }else server.send( 200, "text/json", "false"); +} + +void setClientName() { + if (server.hasArg("id") && server.hasArg("name")) { + if(server.arg("name").length()>0){ + nameList.add(clientScan.getClientMac(server.arg("id").toInt()), server.arg("name")); + server.send( 200, "text/json", "true"); + } + else server.send( 200, "text/json", "false"); + } +} + +void deleteName() { + if (server.hasArg("num")) { + int _num = server.arg("num").toInt(); + nameList.remove(_num); + server.send( 200, "text/json", "true"); + }else server.send( 200, "text/json", "false"); +} + +void clearNameList() { + nameList.clear(); + server.send( 200, "text/json", "true" ); +} + +void editClientName() { + if (server.hasArg("id") && server.hasArg("name")) { + nameList.edit(server.arg("id").toInt(), server.arg("name")); + server.send( 200, "text/json", "true"); + }else server.send( 200, "text/json", "false"); +} + +void addClient(){ + if(server.hasArg("mac") && server.hasArg("name")){ + String macStr = server.arg("mac"); + macStr.replace(":",""); + Serial.println("add "+macStr+" - "+server.arg("name")); + if(macStr.length() < 12 || macStr.length() > 12) server.send( 200, "text/json", "false"); + else{ + Mac _newClient; + for(int i=0;i<6;i++){ + const char* val = macStr.substring(i*2,i*2+2).c_str(); + uint8_t valByte = strtoul(val, NULL, 16); + Serial.print(valByte,HEX); + Serial.print(":"); + _newClient.setAt(valByte,i); + } + Serial.println(); + nameList.add(_newClient,server.arg("name")); + server.send( 200, "text/json", "true"); + } + } +} + +//==========Attack========== +void sendAttackInfo() { + attack.sendResults(); +} + +void startAttack() { + if (server.hasArg("num")) { + int _attackNum = server.arg("num").toInt(); + if (apScan.getFirstTarget() > -1 || _attackNum == 1 || _attackNum == 2) { + attack.start(server.arg("num").toInt()); + server.send ( 200, "text/json", "true"); + } else server.send( 200, "text/json", "false"); + } +} + +void addSSID() { + if(server.hasArg("ssid") && server.hasArg("num") && server.hasArg("enc")){ + int num = server.arg("num").toInt(); + if(num > 0){ + ssidList.addClone(server.arg("ssid"),num, server.arg("enc") == "true"); + }else{ + ssidList.add(server.arg("ssid"), server.arg("enc") == "true" || server.arg("enc") == "1"); + } + attack.ssidChange = true; + server.send( 200, "text/json", "true"); + }else server.send( 200, "text/json", "false"); +} + +void cloneSelected(){ + if(apScan.selectedSum > 0){ + int clonesPerSSID = 48/apScan.selectedSum; + ssidList.clear(); + for(int i=0;i= 1 && server.arg("apChannel").toInt() <= 14) { + settings.apChannel = server.arg("apChannel").toInt(); + } + } + if (server.hasArg("macAp")) { + String macStr = server.arg("macAp"); + macStr.replace(":",""); + Mac tempMac; + if(macStr.length() == 12){ + for(int i=0;i<6;i++){ + const char* val = macStr.substring(i*2,i*2+2).c_str(); + uint8_t valByte = strtoul(val, NULL, 16); + tempMac.setAt(valByte,i); + } + if(tempMac.valid()) settings.macAP.set(tempMac); + } else if(macStr.length() == 0){ + settings.macAP.set(settings.defaultMacAP); + } + } + if (server.hasArg("randMacAp")) { + if (server.arg("randMacAp") == "false") settings.isMacAPRand = false; + else settings.isMacAPRand = true; + } + if (server.hasArg("scanTime")) settings.clientScanTime = server.arg("scanTime").toInt(); + if (server.hasArg("timeout")) settings.attackTimeout = server.arg("timeout").toInt(); + if (server.hasArg("deauthReason")) settings.deauthReason = server.arg("deauthReason").toInt(); + if (server.hasArg("packetRate")) settings.attackPacketRate = server.arg("packetRate").toInt(); + if (server.hasArg("apScanHidden")) { + if (server.arg("apScanHidden") == "false") settings.apScanHidden = false; + else settings.apScanHidden = true; + } + if (server.hasArg("beaconInterval")) { + if (server.arg("beaconInterval") == "false") settings.beaconInterval = false; + else settings.beaconInterval = true; + } + if (server.hasArg("useLed")) { + if (server.arg("useLed") == "false") settings.useLed = false; + else settings.useLed = true; + attack.refreshLed(); + } + if (server.hasArg("channelHop")) { + if (server.arg("channelHop") == "false") settings.channelHop = false; + else settings.channelHop = true; + } + if (server.hasArg("multiAPs")) { + if (server.arg("multiAPs") == "false") settings.multiAPs = false; + else settings.multiAPs = true; + } + if (server.hasArg("multiAttacks")) { + if (server.arg("multiAttacks") == "false") settings.multiAttacks = false; + else settings.multiAttacks = true; + } + + if (server.hasArg("ledPin")) settings.setLedPin(server.arg("ledPin").toInt()); + if(server.hasArg("macInterval")) settings.macInterval = server.arg("macInterval").toInt(); + + settings.save(); + server.send( 200, "text/json", "true" ); +} + +void resetSettings() { + settings.reset(); + server.send( 200, "text/json", "true" ); +} + +void setup() { + + randomSeed(os_random()); + +#ifdef USE_LED16 + pinMode(16, OUTPUT); + digitalWrite(16, LOW); +#endif + + Serial.begin(115200); + + attackMode_deauth = "START"; + attackMode_beacon = "START"; + + EEPROM.begin(4096); + SPIFFS.begin(); + + settings.load(); + if (debug) settings.info(); + settings.syncMacInterface(); + nameList.load(); + ssidList.load(); + + attack.refreshLed(); + + delay(500); // Prevent bssid leak + + startWifi(); + attack.stopAll(); + attack.generate(); + + /* ========== Web Server ========== */ + + /* HTML */ + server.onNotFound(load404); + + server.on("/", loadIndexHTML); + server.on("/index.html", loadIndexHTML); + server.on("/apscan.html", loadAPScanHTML); + server.on("/stations.html", loadStationsHTML); + server.on("/attack.html", loadAttackHTML); + server.on("/settings.html", loadSettingsHTML); + server.on("/info.html", loadInfoHTML); + server.on("/license", loadLicense); + + /* JS */ + server.on("/js/apscan.js", loadAPScanJS); + server.on("/js/stations.js", loadStationsJS); + server.on("/js/attack.js", loadAttackJS); + server.on("/js/settings.js", loadSettingsJS); + server.on("/js/functions.js", loadFunctionsJS); + + /* CSS */ + server.on ("/style.css", loadStyle); + + /* JSON */ + server.on("/APScanResults.json", sendAPResults); + server.on("/APScan.json", startAPScan); + server.on("/APSelect.json", selectAP); + server.on("/ClientScan.json", startClientScan); + server.on("/ClientScanResults.json", sendClientResults); + server.on("/ClientScanTime.json", sendClientScanTime); + server.on("/clientSelect.json", selectClient); + server.on("/setName.json", setClientName); + server.on("/addClientFromList.json", addClientFromList); + server.on("/attackInfo.json", sendAttackInfo); + server.on("/attackStart.json", startAttack); + server.on("/settings.json", getSettings); + server.on("/settingsSave.json", saveSettings); + server.on("/settingsReset.json", resetSettings); + server.on("/deleteName.json", deleteName); + server.on("/clearNameList.json", clearNameList); + server.on("/editNameList.json", editClientName); + server.on("/addSSID.json", addSSID); + server.on("/cloneSelected.json", cloneSelected); + server.on("/deleteSSID.json", deleteSSID); + server.on("/randomSSID.json", randomSSID); + server.on("/clearSSID.json", clearSSID); + server.on("/resetSSID.json", resetSSID); + server.on("/saveSSID.json", saveSSID); + server.on("/restartESP.json", restartESP); + server.on("/addClient.json",addClient); + server.on("/enableRandom.json",enableRandom); + + server.begin(); + +#ifdef USE_DISPLAY + display.init(); + display.flipScreenVertically(); + pinMode(upBtn, INPUT_PULLUP); + pinMode(downBtn, INPUT_PULLUP); + pinMode(selectBtn, INPUT_PULLUP); + if(displayBtn == 0) pinMode(displayBtn, INPUT); + else pinMode(displayBtn, INPUT_PULLUP); + + display.clear(); + display.setFont(ArialMT_Plain_16); + display.drawString(0, 0, "ESP8266"); + display.setFont(ArialMT_Plain_24); + display.drawString(0, 16, "Deauther"); + display.setFont(ArialMT_Plain_10); + display.drawString(100, 28, "v"); + display.setFont(ArialMT_Plain_16); + display.drawString(104, 24, "1.6"); + display.setFont(ArialMT_Plain_10); + display.drawString(0, 40, "Copyright (c) 2017"); + display.drawString(0, 50, "Stefan Kremser"); + display.display(); + + display.setFont(Roboto_Mono_8); + + delay(1600); +#endif + +#ifdef resetPin + pinMode(resetPin, INPUT_PULLUP); + if(digitalRead(resetPin) == LOW) settings.reset(); +#endif + + if(debug){ + Serial.println("\nStarting...\n"); +#ifndef USE_DISPLAY + delay(1600); +#endif + } +} + +void loop() { + if (clientScan.sniffing) { + if (clientScan.stop()) startWifi(); + } else { + server.handleClient(); + attack.run(); + } + + if(Serial.available()){ + String input = Serial.readString(); + if(input == "reset" || input == "reset\n" || input == "reset\r" || input == "reset\r\n"){ + settings.reset(); + } + } + +#ifdef USE_DISPLAY + + if (digitalRead(upBtn) == LOW || digitalRead(downBtn) == LOW || digitalRead(selectBtn) == LOW || digitalRead(displayBtn) == LOW){ + if(canBtnPress){ + if(digitalRead(upBtn) == LOW) buttonPressed = 0; + else if(digitalRead(downBtn) == LOW) buttonPressed = 1; + else if(digitalRead(selectBtn) == LOW) buttonPressed = 2; + else if(digitalRead(displayBtn) == LOW) buttonPressed = 3; + canBtnPress = false; + } + }else if(!canBtnPress){ + canBtnPress = true; + + // ===== UP ===== + if (buttonPressed == 0 && curRow > 0) { + curRow--; + if (lrow - 1 < 0) { + lrow = rowsPerSite - 1; + curSite--; + } else lrow--; + + // ===== DOWN ===== + } else if (buttonPressed == 1 && curRow < rows - 1) { + curRow++; + if (lrow + 1 >= rowsPerSite) { + lrow = 0; + curSite++; + } else lrow++; + + // ===== SELECT ===== + } else if (buttonPressed == 2) { + + // ===== WIFI on/off ===== + if (curRow == 0) { + if (wifiMode == "ON") stopWifi(); + else startWifi(); + + // ===== scan for APs ===== + } else if (curRow == 1) { + startAPScan(); + drawInterface(); + + // ===== start,stop deauth attack ===== + } else if (curRow == 2) { + if (attackMode_deauth == "START" && apScan.getFirstTarget() > -1) attack.start(0); + else if (attackMode_deauth == "STOP") attack.stop(0); + + // ===== start,stop beacon attack ===== + } else if (curRow == 3) { + if (attackMode_beacon == "START"){ + + //clone all selected SSIDs + if(apScan.selectedSum > 0){ + int clonesPerSSID = 48/apScan.selectedSum; + ssidList.clear(); + for(int i=0;i= 4) { + attack.stop(0); + apScan.select(curRow - 4); + } + } + // ===== DISPLAY ===== + else if (buttonPressed == 3) { + displayOn = !displayOn; + display.clear(); + display.display(); + } + } + drawInterface(); +#endif + } From 5c9edbd23d9bab5521e26aa2c767a35432d9542e Mon Sep 17 00:00:00 2001 From: Sam Denty Date: Wed, 9 Aug 2017 21:22:44 +0100 Subject: [PATCH 2/4] Removed changes from .ino --- esp8266_deauther/esp8266_deauther.ino | 7 ------- 1 file changed, 7 deletions(-) diff --git a/esp8266_deauther/esp8266_deauther.ino b/esp8266_deauther/esp8266_deauther.ino index 80bee61..f9ecd3c 100644 --- a/esp8266_deauther/esp8266_deauther.ino +++ b/esp8266_deauther/esp8266_deauther.ino @@ -171,34 +171,27 @@ void loadInfoHTML(){ sendFile(200, "text/html", data_infoHTML, sizeof(data_infoHTML)); } void loadLicense(){ - server.sendHeader("Cache-Control", "max-age=1000"); sendFile(200, "text/plain", data_license, sizeof(data_license)); } void loadFunctionsJS() { - server.sendHeader("Cache-Control", "max-age=300"); sendFile(200, "text/javascript", data_js_functionsJS, sizeof(data_js_functionsJS)); } void loadAPScanJS() { - server.sendHeader("Cache-Control", "max-age=300"); sendFile(200, "text/javascript", data_js_apscanJS, sizeof(data_js_apscanJS)); } void loadStationsJS() { - server.sendHeader("Cache-Control", "max-age=300"); sendFile(200, "text/javascript", data_js_stationsJS, sizeof(data_js_stationsJS)); } void loadAttackJS() { attack.ssidChange = true; - server.sendHeader("Cache-Control", "max-age=300"); sendFile(200, "text/javascript", data_js_attackJS, sizeof(data_js_attackJS)); } void loadSettingsJS() { - server.sendHeader("Cache-Control", "max-age=300"); sendFile(200, "text/javascript", data_js_settingsJS, sizeof(data_js_settingsJS)); } void loadStyle() { - server.sendHeader("Cache-Control", "max-age=300"); sendFile(200, "text/css;charset=UTF-8", data_styleCSS, sizeof(data_styleCSS)); } From 952b467a41b4e82fae24c0b1931e9e21093234a8 Mon Sep 17 00:00:00 2001 From: samdenty99 Date: Wed, 9 Aug 2017 21:36:48 +0100 Subject: [PATCH 3/4] Added changes to Data.h --- esp8266_deauther/data.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/esp8266_deauther/data.h b/esp8266_deauther/data.h index 060e1c4..b05cbd5 100644 --- a/esp8266_deauther/data.h +++ b/esp8266_deauther/data.h @@ -63,6 +63,7 @@ void sendHeader(int code, String type, size_t _size) { } void sendFile(int code, String type, const char* adr, size_t len) { + if (type != "text/json") server.sendHeader("Cache-Control", "max-age=400"); sendHeader(code,type,len); /* int runs = len/bufSize; @@ -23484,4 +23485,4 @@ const char Roboto_Mono_8[] PROGMEM = { -#endif +#endif From 6de99a6a1dc7962211099dcb910917d4f120c8d2 Mon Sep 17 00:00:00 2001 From: samdenty99 Date: Wed, 9 Aug 2017 21:43:24 +0100 Subject: [PATCH 4/4] Removed if statement --- esp8266_deauther/data.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esp8266_deauther/data.h b/esp8266_deauther/data.h index b05cbd5..d9a771a 100644 --- a/esp8266_deauther/data.h +++ b/esp8266_deauther/data.h @@ -63,7 +63,7 @@ void sendHeader(int code, String type, size_t _size) { } void sendFile(int code, String type, const char* adr, size_t len) { - if (type != "text/json") server.sendHeader("Cache-Control", "max-age=400"); + server.sendHeader("Cache-Control", "max-age=400"); sendHeader(code,type,len); /* int runs = len/bufSize;