GAMESH

游戏美术动画unity资源搬运工!

剧情党,完美控!
桐崎千棘
当前位置:首页 > 其他 > 正文内容

esp8266利用wifi探针统计附近wifi设备

admin2年前 (2021-12-09)其他41090

我们的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_ */

esp8266利用wifi探针统计附近wifi设备 esp8266 物联网 第1张

扫描二维码推送至手机访问。

本サイト上に掲載の文章、画像、写真などを無断で複製することは法律で禁じられています。全ての著作権はGAMESHに帰属します。

本文链接:https://www.pylblog.com/post/216.html

分享给朋友:

相关文章

esp8266 blinker 报错 Fatal excepeion 28

esp8266 blinker 报错 Fatal excepeion 28

最近想做物联网开发于是在淘宝买了一个esp8266 和若干个模块!由于以前从来没接触过这一行,所以很多问题都是很难解决的!最近做的这个红外线控制空调的小程序就遇到了一个棘手的问题,估计对于高手和懂编程...

制作带有气象站的小台钟

制作带有气象站的小台钟

在这个项目中,我将向您展示如何制作带有气象站的小台钟这是一篇分步文章,我将指导您完成使用 Mini LCD 显示屏、Wemos D1 Mini 微控制器、锂离子电池以及显示实时天气和时间的功能来创建您...

发表评论

访客

看不清,换一张

QQ登录
◎欢迎参与讨论,请在这里发表您的看法和观点。