kalanda / esp8266-sniffer

An easy experiment which uses the ESP8266 wifi module to look for near smartphones around you
The Unlicense
605 stars 118 forks source link

Only one SSID per device #6

Open Bigfoot491993 opened 6 years ago

Bigfoot491993 commented 6 years ago

Hi, whenever I run this script it only gives me one remembered SSID per device, this is a different SSID than that device is currently connected to, so it really is a saved network, however I don't know how to get more SSID's out of it. I read somewhere that Espressif limited the montioring mode in recent releases, any idea how to fix this? (I programmed it using the Arduino IDE)

alafanechere commented 6 years ago

Hello @Bigfoot491993 , from my understanding, each probe request contains one SSID. If the device wants to check presence of multiple ssids around it will send multiple probe requests.

Bigfoot491993 commented 6 years ago

Interesting, I'll test it again as soon as possible but I don't think I ever saw an other SSID for a given MAC over the course of 15 minutes. I read somewhere that esperrif limited the firmware in recent versions but I haven't managed to get an older version working with the Arduino IDE.

iCounterBOX commented 6 years ago

Hi @Bigfoot491993 , i loop the 14 Channels ( usual channel hopping ). a struct array store the detected devices ( MAC is unique ! ).. The ssid will get concatinated..within this 14 channel hop we receive several ssid string ( if they occure..) here some sniplet from a longer code:

// A Struct Array to keep the sniffed MAC devices

typedef struct  {                               
    char deviceMacAddr[18];                     //  peerMac
    char  ssid[100];                                // Some will have ssid ..some not....less memory MAX flexibility - https://hackingmajenkoblog.wordpress.com/2016/02/04/the-evils-of-arduino-strings/
    uint8 wifiChannel;                          // Channel
    signed int rssi = 0;                        // RSSI     
} deviceRecordType;
#define MACdeviceDataMAXelements  200
deviceRecordType  MACdeviceData[MACdeviceDataMAXelements];      // instead of EDB we try hier a STRUCT ARRAY
int MACdeviceDataIndex = 0;     // Index of this Struct Array

I limt the ssid! ( limitation in stack .. heap ). I adapted the showMetadata() to collect my data in this struct:

static void showMetadata(struct SnifferPacket* snifferPacket)
{
    unsigned int frameControl = ((unsigned int)snifferPacket->data[1] << 8) + snifferPacket->data[0];
    // uint8_t version      = (frameControl & 0b0000000000000011) >> 0;
    uint8_t frameType = (frameControl & 0b0000000000001100) >> 2;
    uint8_t frameSubType = (frameControl & 0b0000000011110000) >> 4;
    // uint8_t toDS         = (frameControl & 0b0000000100000000) >> 8;
    // uint8_t fromDS       = (frameControl & 0b0000001000000000) >> 9;
    // Only look for probe request packets
    if (frameType != TYPE_MANAGEMENT || frameSubType != SUBTYPE_PROBE_REQUEST)
    {
        //Serial.println("showMetadata() - bedingung nicht erfüllt: frameType != TYPE_MANAGEMENT || frameSubType != SUBTYPE_PROBE_REQUEST --- RETURN ");
        return;
    }
    // Blink the LED / pro gültigem ChannelHop und gefundenem Wert!!
    digitalWrite(LED_BLUE_MCU, ledStatus); // Write LED high/low
    ledStatus = (ledStatus == HIGH) ? LOW : HIGH;
    currentChannel = wifi_get_channel();
    // Serial.print("showMetadata() -  current promiscuous Channel:  ");  Serial.println(currentChannel);

    // get my MAC addr - USE this to unify the Transferred Data ..MY ID !!
    String myEspMAC = WiFi.macAddress();
    //Serial.print("myEspMAC: ");
    //Serial.print(myEspMAC);
    //Serial.print(" RSSI: "); Serial.print(snifferPacket->rx_ctrl.rssi, DEC);
    //Serial.print(" Ch: ");
    //Serial.print(wifi_get_channel());
    char deviceMacAddr[] = "00:00:00:00:00:00";
    getMAC(deviceMacAddr, snifferPacket->data, 10);
    //Serial.print(" Peer MAC: ");
    //Serial.print(deviceMacAddr);
    uint8_t SSID_length = snifferPacket->data[25];
    //Serial.print(" SSID: ");
    String ssid = printDataSpan(26, SSID_length, snifferPacket->data);      // ck: 26.11.17..die funktion macht kein serial.write jetzt mehr...wir nehmen das string ergebnis!! 
                                                                            //concat the result into data4RestService:
    //String adrStr(deviceMacAddr);     // char array to string...is better to compare / https://stackoverflow.com/questions/8960087/how-to-convert-a-char-array-to-a-string            
        //This Device we will store Now:
        Serial.print("myEspMAC: "); Serial.print(myEspMAC);
        Serial.print(" RSSI: "); Serial.print(snifferPacket->rx_ctrl.rssi, DEC);
        Serial.print(" Ch: ");  Serial.print(wifi_get_channel());
        Serial.print(" Peer MAC: "); Serial.print(deviceMacAddr);
        Serial.print(" SSID: "); Serial.print(ssid);
        Serial.println();
        // NEW - STRUCT DATA 
        int idx = findMACdeviceInDeviceArray(deviceMacAddr);    // FIRST we check if this MAC was Stored before within this SCAN-CYCLE ( e.g 20 SEC for 14 Cgannel ) -- Gives the Index or -1
        if (idx == -1) {        // Hurray - a NEW Wifi X-Mas-Tree
            //int nElements = sizeof MACdeviceData / sizeof MACdeviceData[0];       // ?? gab den vordefinierten wert zurück der Stuktur ?? Nicht den gerade gespeicherten Element-Count?

            if (MACdeviceDataIndex < MACdeviceDataMAXelements) {                // In MACdeviceDataMAXelements MUSS Immer der aktuelle Index stehen     
                MACdeviceData[MACdeviceDataIndex].rssi = snifferPacket->rx_ctrl.rssi;
                MACdeviceData[MACdeviceDataIndex].wifiChannel = wifi_get_channel();
                if (ssid.length() < sizeof(MACdeviceData[MACdeviceDataIndex].ssid) ) ssid.toCharArray(MACdeviceData[MACdeviceDataIndex].ssid, ssid.length() + 1);
                strncpy(MACdeviceData[MACdeviceDataIndex].deviceMacAddr, deviceMacAddr, sizeof MACdeviceData[MACdeviceDataIndex].deviceMacAddr - 1);
                //Serial.print(" INSERTed - NEW Device  in Struct-array"); Serial.println(MACdeviceData[MACdeviceDataIndex].deviceMacAddr);

                MACdeviceDataIndex += 1;
            }
            else
            {
                Serial.print(" ALERT!! - MACdeviceData / Limit Reached!!:  "); Serial.print(MACdeviceDataMAXelements);
                return;
            }           
        }
        else {                                                      //  ***  UPDATE EXISTING WiFi DEVICE
            //Serial.print("Element Found at Position: "); Serial.println( idx + 1);
            //Serial.print("  UPDATE - MAC (or better the SSID )  in Struct-Array: "); Serial.println(deviceMacAddr);           
            //MACdeviceData[ idx].rssi = snifferPacket->rx_ctrl.rssi;           // Könnten hier zb den MittelWert eintragen?                    
            if ( ssid.length() > 0 ) {                                                  // Liegt überhaupt eine neue SSID  an?
                char *stringFound = strstr(MACdeviceData[idx].ssid, ssid.c_str());      // search for string "hassasin" in buff
                if (stringFound == NULL)                                                // if successful then sfound now points at ssid
                {
                    ssid = ssid + ">" + MACdeviceData[idx].ssid;                        //  der VORHANDENE SSID STRING wird Verlängert UM die NEUE SSID                                                                                         // Use strlen to get the length of a null-terminated string.  / sizeof returns the length of the array not the string
                    const char *SSIDc = ssid.c_str();                                   // temp. char-String !! - https://stackoverflow.com/questions/10247212/how-concatenate-a-string-and-a-const-char
                    //Serial.print(" SSID update / strlen(SSIDc): "); Serial.print(strlen(SSIDc));  Serial.print(" sizeof(MACdeviceData[MACdeviceDataIndex].ssid) : "); Serial.println(sizeof(MACdeviceData[MACdeviceDataIndex].ssid));
                    if (strlen(SSIDc) < sizeof(MACdeviceData[MACdeviceDataIndex].ssid)) {
                        strncpy(MACdeviceData[idx].ssid, SSIDc, strlen(SSIDc) - 1);
                        //Serial.print(" UPDATED - SSID in Struct-array"); Serial.println(MACdeviceData[MACdeviceDataIndex].ssid);
                    }
                }
                else
                {
                    //Serial.print(" ssid.c_str() : "); Serial.print(ssid.c_str());   Serial.print(" gefunden in MACdeviceData[idx].ssid: "); Serial.println(MACdeviceData[idx].ssid);
                }
            }                                   
        }   
    // dataset for THIS CHANEL ist finished !!
}

findMACdeviceInDeviceArray(deviceMacAddr) is used to store ONLY unique MAC addr in our Buffer..

/*
Check if the NEW detected device is almost stored in the Array
Parameter:
peermac - the detected peerMAC of a device
nrElements = (sizeof MACdeviceData / sizeof MACdeviceData[0])       -- // https://stackoverflow.com/questions/1898657/result-of-sizeof-on-array-of-structs-in-c
return: gives the index of the peerMAC found in array
*/
int findMACdeviceInDeviceArray(char *peerMAC) {
    int nElements = MACdeviceDataIndex;
    //Serial.print("findMACdeviceInDeviceArray() nElements : ");    Serial.print(nElements); Serial.print(" MAC to search for : "); Serial.println(peerMAC);

    for (int i = 0; i <= nElements; i++)
    {
        if (strcmp(MACdeviceData[i].deviceMacAddr, peerMAC) == 0) {                 // the function returns 0 when the strings are equal            
            //Serial.print("findMACdeviceInDeviceArray() FOUND it : "); Serial.println(MACdeviceData[i].deviceMacAddr);
            return i;
        }
    }
    return -1;
}

Now we have all data in our Buffer..can do whatever we need with it..

for (int i = 0; i < MACdeviceDataIndex; i++) {
        Serial.print("Str/myMac: "); Serial.print(WiFi.macAddress());   Serial.print(" cha: "); Serial.print(MACdeviceData[i].wifiChannel); Serial.print(" RSSI: "); Serial.print(MACdeviceData[i].rssi);
        Serial.print(" SSID: "); Serial.print(MACdeviceData[i].ssid);   Serial.print(" MAC: "); Serial.println(MACdeviceData[i].deviceMacAddr);     
    }
    Serial.println();
Marfbuilds commented 4 years ago

Hey, I know its a long time ago now, but do you have the full code for this?

kalanda commented 4 years ago

nope