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に帰属します。

