esp8266利用wifi探针统计附近wifi设备
我们的wifi设备每隔一定时间(几十毫秒到几秒不等)向周围的sta和AP广播beacon帧,利用这个特点我们就可以使用esp8266来抓取其它设备发送的beacon帧,这里我们使用定时器,AP模式和STATION模式进行来回切换,AP模式下将探测到的数据存到flash当中,STATION模式,把数据读取出来并且传到服务器。因为esp8266没法同时启用ap和station,只能使用来回切换的形式来上传数据!每次获取的数据会有重复的,这需要在服务器进行一下重复的数据验证,不将重复的数据写入数据库。还有一点就是现在新的智能设备基本都有反探针的功能,开起了随机mac地址!也就是你无法获取到真实的mac,只有当它链接到wifi获取的mac才是固定的,但是这个mac也不是机器本身的mac,只要用户默认开启了随机mac基本都无法获取到真实mac地址,这一切都因为有些人利用wifi探针做大数据精准推送广告,获取用户隐私!
今年成都疫情听到的新词汇“时空伴随者”应该和这个原理差不多,只不过它是基于手机基站来判断,这个只有运营商才能看得到!如果手机mac地址不是随机的,那么理论上是可行的。
下面放出代码:
#include <ESP8266WiFi.h> #include "./sniffer.h" #include <ESP8266HTTPClient.h> #include <WiFiClient.h> #define disable 0 #define CHANNEL 1 #define BAUD_RATE 115200 #define CHANNEL_HOPPING true //if true it will scan on all channels #define MAX_CHANNEL 13 //(only necessary if channelHopping is true) #define HOP_INTERVAL 800//214 //in ms (only necessary if channelHopping is true) // Channel to perform deauth #define STASSID "********" #define STAPSK "***********" const char* ssid = STASSID; const char* password = STAPSK; bool tingzhi=true; bool yici=false; uint32_t read_timeA = 0; uint32_t read_timeB = 0; String juli; //d = 10^(A-(abs(rssi)) / (10 * n)) 信号强度 #define N 45 //N = 10 * n ,其中n为环境衰减因子,3.25-4.5 #define A -35 //接收机和发射机间隔1m时的信号强度 String mactemp ; int ch = CHANNEL; unsigned long lastChannelChange = 0; uint8_t channel = 1; // Access point MAC to deauth uint8_t ap[6] = {0x00,0x01,0x02,0x03,0x04,0x05}; // Client MAC to deauth uint8_t client[6] = {0xc4, 0x6a, 0xb7, 0x9f, 0xcc, 0x34}; // Sequence number of a packet from AP to client uint16_t seq_n = 0; // Packet buffer uint8_t packet_buffer[64]; uint8_t temp_mac[6] = {0xc4, 0x6a, 0xb7, 0x9f, 0xcc, 0x34}; extern "C" { #include "user_interface.h" } void sniffe(uint8_t*buf, uint16_t len){ Serial.println(buf[4]); } void promisc_cb(uint8_t *buf, uint16_t len) { if (len == 12){ struct RxControl *sniffer = (struct RxControl*) buf; } else if (len == 128) { struct sniffer_buf2 *sniffer = (struct sniffer_buf2*) buf; } else { struct sniffer_buf *sniffer = (struct sniffer_buf*) buf; int i=0; // Check MACs // 如果MAC地址和上一次一样就返回 if(0==memcmp(temp_mac, &sniffer->buf[10], 6)){ return; } // 缓存上次的MAC,避免重复打印 for (i=0; i<6; i++){ temp_mac[i] = sniffer->buf[i+10]; } #if SNIFFER_TEST Serial.printf("-> %3d: %d", wifi_get_channel(), len); printmac(sniffer->buf, 4); printmac(sniffer->buf, 10); Serial.printf("\n"); juli=String(rssiTodis(sniffer->rx_ctrl.rssi)); mactemp+=MactoString(sniffer->buf)+"|"+juli+"|"; #endif // 判断client for (i=0; i<6; i++) if (sniffer->buf[i+4] != client[i]) return; printmac(sniffer->buf, 4); Serial.printf("\r\n"); Serial.printf("\trssi:%d\r\n", sniffer->rx_ctrl.rssi); Serial.printf("\tchannel:%d\r\n", sniffer->rx_ctrl.channel); Serial.printf("\trate:%d\r\n", sniffer->rx_ctrl.rate); Serial.printf("\tsig_mode:%d\r\n",sniffer->rx_ctrl.sig_mode); // 判断AP for (i=0; i<6; i++) if (sniffer->buf[i+10] != ap[i]) return; printmac(sniffer->buf, 10); //os_timer_disarm(&channelHop_timer); // Update sequence number #if DEAUTH_ENABLE seq_n = sniffer->buf[23] * 0xFF + sniffer->buf[22]; #endif } } String MactoString(uint8_t *adress) { String value = ""; for (int i = 0; i < 6; i++) { if (adress[i+10] < 0x10) { value += "0"; } value += String(adress[i+10], HEX); if (i < 5) value += ":"; } return value; } void setup() { wifi_set_opmode_current(0x01); Serial.begin(BAUD_RATE); delay(2000); Serial.println(); // prepare GPIO2 pinMode(2, OUTPUT); digitalWrite(2, 0); } float rssiTodis(int RSSI) { float iu, distance; iu = (float)(A-RSSI ) / (float)N; distance = powf(10.0, iu);//计算以x为底数的y次幂 功能与pow一致,只是输入与输出皆为浮点数 Serial.print("distance:---"); Serial.println(distance); return distance; } void getmac(){ if(yici){ wifi_set_opmode(STATION_MODE); delay(10); wifi_promiscuous_enable(0); WiFi.disconnect(); wifi_set_promiscuous_rx_cb(promisc_cb); // Set up promiscuous callback delay(10); wifi_set_channel(channel); wifi_promiscuous_enable(1); yici=false; } /* Channel Hopping */ if(CHANNEL_HOPPING){ unsigned long currentTime = millis(); if(currentTime - lastChannelChange >= HOP_INTERVAL){ lastChannelChange = currentTime; ch++; //increase channel if(ch > MAX_CHANNEL) { ch = 1; tingzhi=true; } wifi_set_channel(ch); //switch to new channel } } } void gethttp(){ if ((WiFi.status() == WL_CONNECTED)) { WiFiClient client; HTTPClient http; Serial.println("allmac"+mactemp); Serial.print("[HTTP] begin...\n"); bool contentweb=http.begin(client, "http://www.xxxxxx.com/TEMP/esp8266/add.php?mac="+mactemp); if (contentweb) { // HTTP Serial.print("[HTTP] GET...\n"); // start connection and send HTTP header int httpCode = http.GET(); Serial.printf("[HTTP] GET... code: %d\n", httpCode); // httpCode will be negative on error if (httpCode == 200) { // HTTP header has been send and Server response header has been handled Serial.printf("[HTTP] GET... code: %d\n", httpCode); // file found at server if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) { String payload = http.getString(); Serial.println(payload); delay(1000); mactemp=""; tingzhi=false; yici=true; read_timeA=0; } } else { read_timeA++; Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); delay(1000); WiFi.disconnect(); } Serial.println("closing connection"); http.end(); client.flush(); client.stop(); }else{ WiFi.disconnect();}}else{ wifi_promiscuous_enable(0); WiFi.begin(STASSID, STAPSK); while (WiFi.status() != WL_CONNECTED) { Serial.flush(); delay(500); Serial.print("."); } Serial.println(""); Serial.print("Connected! IP address: "); Serial.println(WiFi.localIP()); }} void loop() { if(!tingzhi){ getmac(); }else{ gethttp(); } if(read_timeA >=5){ ESP.restart(); } // Serial.printf("--------- %d\n",read_timeA); delay(10); }
sniffer.h
/* * sniffer.h */ #ifndef SNIFFER_DEMO_INCLUDE_SNIFFER_H_ #define SNIFFER_DEMO_INCLUDE_SNIFFER_H_ #include "ets_sys.h" #include "os_type.h" #define SNIFFER_TEST 1 /* ʹ��DEAUTH */ #define DEAUTH_ENABLE 0 /* ÿ��x����channel */ #define HOP_JUMP_ENABLE 1 #define CHANNEL_HOP_INTERVAL 3000 extern void ICACHE_FLASH_ATTR sniffer_init(void); extern void ICACHE_FLASH_ATTR sniffer_init_in_system_init_done(void); struct RxControl { signed rssi:8; // signal intensity of packet unsigned rate:4; unsigned is_group:1; unsigned:1; unsigned sig_mode:2; // 0:is 11n packet; 1:is not 11n packet; unsigned legacy_length:12; // if not 11n packet, shows length of packet. unsigned damatch0:1; unsigned damatch1:1; unsigned bssidmatch0:1; unsigned bssidmatch1:1; unsigned MCS:7; // if is 11n packet, shows the modulation // and code used (range from 0 to 76) unsigned CWB:1; // if is 11n packet, shows if is HT40 packet or not unsigned HT_length:16; // if is 11n packet, shows length of packet. unsigned Smoothing:1; unsigned Not_Sounding:1; unsigned:1; unsigned Aggregation:1; unsigned STBC:2; unsigned FEC_CODING:1; // if is 11n packet, shows if is LDPC packet or not. unsigned SGI:1; unsigned rxend_state:8; unsigned ampdu_cnt:8; unsigned channel:4; // which channel this packet in. unsigned:12; }; struct LenSeq { uint16_t length; uint16_t seq; uint8_t address3[6]; }; struct sniffer_buf { struct RxControl rx_ctrl; uint8_t buf[36]; uint16_t cnt; struct LenSeq lenseq[1]; }; struct sniffer_buf2{ struct RxControl rx_ctrl; uint8_t buf[112]; uint16_t cnt; uint16_t len; }; #define printmac(buf, i) Serial.printf("\t%02X:%02X:%02X:%02X:%02X:%02X", buf[i+0], buf[i+1], buf[i+2], \ buf[i+3], buf[i+4], buf[i+5]) #define user_procTaskPrio 0 #define user_procTaskQueueLen 1 os_event_t user_procTaskQueue[user_procTaskQueueLen]; #endif /* SNIFFER_DEMO_INCLUDE_SNIFFER_H_ */
扫描二维码推送至手机访问。
本サイト上に掲載の文章、画像、写真などを無断で複製することは法律で禁じられています。全ての著作権はGAMESHに帰属します。