Mac address sniffer only finds some mobile phone macs

Hi I'm using esp32 wroom With Arduino and platformio to find Mac address of near devices. the problem is it only finds some Mac addresses . for example my phone which is a Xiaomi red me note 11 pro. But it doesn't find Mac address of my co-worker's mobile phone which is a Samsung note 3. Here is my code. I didn't copy the initializations for summerizing. what might be the problem ?

void setup(void)
{
	Serial.begin(115200);
	Serial.println("[+] Startup...");
	Serial.println("[!] Starting sniffing task...");
	int sleep_time = CONFIG_SNIFFING_TIME*1000;

	Serial.println("[SNIFFER] Sniffer task created");

	Serial.println("[SNIFFER] Starting sniffing mode...");
	for (int i=1;i<13;i++)
	{
		CONFIG_CHANNEL=i;
	wifi_sniffer_init();
	Serial.printf("[SNIFFER] Started. Sniffing on channel %d",i);
	delay(10);
	}
}
void loop()
{
  
}



static void initialize_sntp()
{
    sntp_setoperatingmode(SNTP_OPMODE_POLL); //automatically request time after 1h
    sntp_setservername(0, "pool.ntp.org");
    sntp_init();
}





static void wifi_sniffer_init()
{
	// tcpip_adapter_init();

	wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
	ESP_ERROR_CHECK(esp_wifi_init(&cfg)); //allocate resource for WiFi driver

	const wifi_country_t wifi_country = {
			.cc = "CN",
			.schan = 1,
			.nchan = 13,
			.policy = WIFI_COUNTRY_POLICY_AUTO
	};
	ESP_ERROR_CHECK(esp_wifi_set_country(&wifi_country)); //set country for channel range [1, 13]
	ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
	ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_NULL));
	ESP_ERROR_CHECK(esp_wifi_start());

	const wifi_promiscuous_filter_t filt = {
			.filter_mask = WIFI_EVENT_MASK_AP_PROBEREQRECVED
	};
	ESP_ERROR_CHECK(esp_wifi_set_promiscuous_filter(&filt)); //set filter mask
	ESP_ERROR_CHECK(esp_wifi_set_promiscuous_rx_cb(wifi_sniffer_packet_handler)); //callback function
	ESP_ERROR_CHECK(esp_wifi_set_promiscuous(true)); //set 'true' the promiscuous mode

	esp_wifi_set_channel(CONFIG_CHANNEL, WIFI_SECOND_CHAN_NONE); //only set the primary channel
}

static void wifi_sniffer_deinit()
{
	ESP_ERROR_CHECK(esp_wifi_set_promiscuous(false)); //set as 'false' the promiscuous mode
	ESP_ERROR_CHECK(esp_wifi_stop()); //it stop soft-AP and free soft-AP control block
	ESP_ERROR_CHECK(esp_wifi_deinit()); //free all resource allocated in esp_wifi_init() and stop WiFi task
}

static void wifi_sniffer_packet_handler(void* buff, wifi_promiscuous_pkt_type_t type)
{
	int pkt_len, fc, sn=0;
	char ssid[SSID_MAX_LEN] = "\0", hash[MD5_LEN] = "\0", htci[5] = "\0";
	uint8_t ssid_len;
	time_t ts;

	wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t *)buff;
	wifi_mgmt_hdr *mgmt = (wifi_mgmt_hdr *)pkt->payload;

	fc = ntohs(mgmt->fctl);

	if((fc & 0xFF00) == 0x4000){ //only look for probe request packets
		time(&ts);

		ssid_len = pkt->payload[25];
		if(ssid_len > 0)
			get_ssid(pkt->payload, ssid, ssid_len);

		pkt_len = pkt->rx_ctrl.sig_len;
	

		sn = get_sn(pkt->payload);

		get_ht_capabilites_info(pkt->payload, htci, pkt_len, ssid_len);

		sprintf(MAC_STRING, "ADDR=%02x:%02x:%02x:%02x:%02x:%02x, "
				"SSID=%s, "
				"TIMESTAMP=%d, "
				"RSSI=%02d, "
				"SN=%d, "
				"HT CAP. INFO=%s",
				mgmt->sa[0], mgmt->sa[1], mgmt->sa[2], mgmt->sa[3], mgmt->sa[4], mgmt->sa[5],
				ssid,
				(int)ts,
				pkt->rx_ctrl.rssi,
				sn,
				htci);
				Serial.println("ALL DATA:");
                       Serial.println(MAC_STRING);
	}
}

static void get_ssid(unsigned char *data, char ssid[SSID_MAX_LEN], uint8_t ssid_len)
{
	int i, j;

	for(i=26, j=0; i<26+ssid_len; i++, j++){
		ssid[j] = data[i];
	}

	ssid[j] = '\0';
}

static int get_sn(unsigned char *data)
{
	int sn;
    char num[5] = "\0";

	sprintf(num, "%02x%02x", data[22], data[23]);
    sscanf(num, "%x", &sn);

    return sn;
}

static void get_ht_capabilites_info(unsigned char *data, char htci[5], int pkt_len, int ssid_len)
{
	int ht_start = 25+ssid_len+19;

	/* 1) data[ht_start-1] is the byte that says if HT Capabilities is present or not (tag length).
	 * 2) I need to check also that i'm not outside the payload: if HT Capabilities is not present in the packet,
	 * for this reason i'm considering the ht_start must be lower than the total length of the packet less the last 4 bytes of FCS */

	if(data[ht_start-1]>0 && ht_start<pkt_len-4){ //HT capabilities is present
		if(data[ht_start-4] == 1) //DSSS parameter is set -> need to shift of three bytes
			sprintf(htci, "%02x%02x", data[ht_start+3], data[ht_start+1+3]);
		else
			sprintf(htci, "%02x%02x", data[ht_start], data[ht_start+1]);
	}
}

how long did you leave it running?

maybe your friend's phone just didn't do anything for the sniffer to see in the time that it was looking?

also, some phones use "randomised" MAC addresses - as a security feature, to protect against scans such as yours ...

https://source.android.com/docs/core/connect/wifi-mac-randomization-behavior

Apple uses randomisation too

1 Like

-it was running for Several minutes.
-no my co-worker's phone was connected to a wifi ssid
-I think randomized Mac is only used in new phones my co-worker's phone is old.

It depends on the OS version.

Also as your friend’s phone was already connected to a possibly preferred WiFi network, the OS might have decided to not perform a Wi-Fi scan at all and as such not being viewed by your code.

My problem is solved my code can now sniffs Mac addresses of any mobiles around I still don't know what was the problem! ? I have other questions about this project but I will ask them in another topic

well, may be you got in at the right time and your friend's device ran a check to see if there was a better network around. it sees devices that are looking for a WiFi network to connect to.

just remember that it might "sniff" false Mac addresses so you can't really track anything with this.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.