Python脚本监听附近Wi-Fi设备并通过邮件和微信推送消息

hmpa-pi

代码地址 https://github.com/wangshub/hmpa-pi

在树莓派上,利用 Wireshark 扫描附近网络 WiFi 设备,并对扫描结果通过邮件或者微信进行推送。

临近春节回老家过年,家里没人,又不想安装摄像头监控,参考 howmanypeoplearearound 写了一个监测脚本,当有手机或其它 Wi-Fi 设备在附近时,通过邮件或者微信提醒。

特性

  • [x] Wi-Fi 设备扫描
  • [x] 邮件提醒
  • [x] 微信提醒(Server 酱)
  • [ ] 陌生设备检测

原理

在 Wi-Fi 网络中,无线网卡是以广播模式发射信号的。当无线网卡将信息广播出去后,所有的设备都可以接收到该信息。将无线网卡设置为监听模式后,就可以捕获到该网卡接收范围的所有数据包。 通过这些数据包,就可以扫描出附近 Wi-Fi 的网络内的设备与信号强度。

监听模式的网卡

一些支持监听模式的网卡

wifi-adapter-that-supports-monitor-mode

软件安装

Mac

 brew install wireshark
 brew cask install wireshark-chmodbpf

Linux 或 Raspberry Pi

sudo apt-get install tshark

run as non-root

sudo dpkg-reconfigure wireshark-common (select YES) sudo usermod -a -G wireshark ${USER:-root} newgrp wireshark

配置网卡

  • 如果是支持监听模式的网卡,可以直接运行

  • 如果刚好是 Rtl8192 + Raspberry Pi,需要先卸载 rtl8192 驱动,再加载 RTL8188 驱动

    #!/usr/bin/env bash
    uname -a
    

    disable rtl8192 driver

    sudo depmod 4.14.79-v7+ sudo rmmod 8192cu sudo modprobe rtl8192cu

    set RTL8188 monitor mode

    sudo ifconfig wlan1 down sudo iwconfig wlan1 mode monitor sudo ifconfig wlan1 up

运行代码

下载代码

git clone https://github.com/wangshub/hmpa-pi.git 
cd hmpa-pi/ && pip install -r requirements.txt

编辑配置文件

cp config/config.py.example config/config.py
vi config/config.py

参考配置

adapter = 'wlan1'

use_email = True email = {“host”: “smtp.163.com”, “port”: 465, “user”: “[email protected]”, “password”: “xxxxxxxxxx”, “to_user”: “[email protected]”}

use_wechat = True serverchan = {“sckey”: “xxxxxxxxxxxxxxxxxxxxx”}

known_devices = {“94:65:2d:xx:xx:xx”: “my cellPhone”, “dc:a4:ca:xx:xx:xx”: “my Mac”, “b8:27:eb:xx:xx:xx”: “my raspberry”}

运行

python main.py

消息推送

运行结果

2019-01-24 07:37:01.211617 一共发现了 67 台设备

Known Devices:

  • my cellPhone
  • my raspberry
  • my mac

All Devices:

  • 00:e0:70:3e:xx:xx 14 DH TECHNOLOGY
  • 94:65:2d:91:xx:xx 14 OnePlus Technology (Shenzhen) Co., Ltd
  • dc:d9:16:7e:xx:xx -12 HUAWEI TECHNOLOGIES CO.,LTD
  • b8:27:eb:12:xx:xx -20 Raspberry Pi Foundation
  • 98:01:a7:eb:xx:xx -40 Apple, Inc.
  • 20:5d:47:44:xx:xx -44 vivo Mobile Communication Co., Ltd.
  • ac:b5:7d:5f:xx:xx -46 Liteon Technology Corporation
  • 04:03:d6:1f:xx:xx -47 Nintendo Co.,Ltd
  • d4:ee:07:55:xx:xx -48 HIWIFI Co., Ltd.
  • 44:6e:e5:63:xx:xx -51 HUAWEI TECHNOLOGIES CO.,LTD
  • 14:75:90:8d:xx:xx -51 TP-LINK TECHNOLOGIES CO.,LTD.
  • 34:96:72:1d:xx:xx -56 TP-LINK TECHNOLOGIES CO.,LTD.
  • d8:cb:8a:74:xx:xx -57 Micro-Star INTL CO., LTD.
  • 40:8d:5c:21:xx:xx -57 GIGA-BYTE TECHNOLOGY CO.,LTD.
  • 6c:59:40:25:xx:xx -58 SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.

More …

TODO

  • [ ] 美化打印信息
  • [ ] 更优雅的参数配置
  • [ ] 当发现新设备时提醒
  • [ ] 绘图统计
  • [ ] 设备距离估计

参考链接

License

  • MIT
  • 仅供学习和研究,切勿非法使用

代码地址

代码地址 https://github.com/wangshub/hmpa-pi


Python脚本监听附近Wi-Fi设备并通过邮件和微信推送消息

19 回复

nice,小星星送上


这个需求挺有意思的,我来给你一个完整的实现方案。

首先,你需要安装几个关键的库:

pip install scapy requests schedule

下面是完整的脚本代码:

import subprocess
import json
import time
import smtplib
from email.mime.text import MIMEText
from email.header import Header
import requests
import schedule
from datetime import datetime
import logging

# 配置部分
CONFIG = {
    'known_devices': ['AA:BB:CC:DD:EE:FF', '11:22:33:44:55:66'],  # 已知设备的MAC地址
    'scan_interval': 60,  # 扫描间隔(秒)
    'email': {
        'smtp_server': 'smtp.qq.com',
        'smtp_port': 587,
        'username': 'your_email@qq.com',
        'password': 'your_auth_code',  # QQ邮箱用授权码
        'sender': 'your_email@qq.com',
        'receiver': 'target_email@example.com'
    },
    'wechat': {
        'corpid': 'your_corpid',
        'corpsecret': 'your_corpsecret',
        'agentid': 'your_agentid'
    }
}

# 设置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

def scan_wifi_devices():
    """扫描附近的Wi-Fi设备"""
    try:
        # 使用arp-scan工具(Linux/macOS)
        result = subprocess.run(['sudo', 'arp-scan', '--localnet'], 
                              capture_output=True, text=True, timeout=30)
        
        devices = []
        for line in result.stdout.split('\n'):
            if '\t' in line:
                parts = line.split('\t')
                if len(parts) >= 2:
                    mac = parts[1].strip().upper()
                    ip = parts[0].strip()
                    devices.append({'mac': mac, 'ip': ip})
        
        return devices
    except Exception as e:
        logging.error(f"扫描失败: {e}")
        return []

def check_new_devices(current_devices):
    """检测新设备"""
    new_devices = []
    for device in current_devices:
        mac = device['mac']
        if mac not in CONFIG['known_devices']:
            new_devices.append(device)
    return new_devices

def send_email(subject, content):
    """发送邮件通知"""
    try:
        msg = MIMEText(content, 'plain', 'utf-8')
        msg['From'] = Header(CONFIG['email']['sender'])
        msg['To'] = Header(CONFIG['email']['receiver'])
        msg['Subject'] = Header(subject, 'utf-8')
        
        server = smtplib.SMTP(CONFIG['email']['smtp_server'], CONFIG['email']['smtp_port'])
        server.starttls()
        server.login(CONFIG['email']['username'], CONFIG['email']['password'])
        server.sendmail(CONFIG['email']['sender'], 
                       CONFIG['email']['receiver'], 
                       msg.as_string())
        server.quit()
        logging.info("邮件发送成功")
        return True
    except Exception as e:
        logging.error(f"邮件发送失败: {e}")
        return False

def get_wechat_token():
    """获取企业微信访问令牌"""
    url = f"https://qyapi.weixin.qq.com/cgi-bin/gettoken"
    params = {
        'corpid': CONFIG['wechat']['corpid'],
        'corpsecret': CONFIG['wechat']['corpsecret']
    }
    
    response = requests.get(url, params=params)
    if response.status_code == 200:
        data = response.json()
        if data['errcode'] == 0:
            return data['access_token']
    return None

def send_wechat_message(content):
    """发送企业微信消息"""
    try:
        token = get_wechat_token()
        if not token:
            logging.error("获取微信token失败")
            return False
        
        url = f"https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={token}"
        
        message = {
            "touser": "@all",
            "msgtype": "text",
            "agentid": CONFIG['wechat']['agentid'],
            "text": {
                "content": content
            },
            "safe": 0
        }
        
        response = requests.post(url, json=message)
        if response.status_code == 200:
            result = response.json()
            if result['errcode'] == 0:
                logging.info("微信消息发送成功")
                return True
        logging.error(f"微信消息发送失败: {response.text}")
        return False
    except Exception as e:
        logging.error(f"微信消息发送异常: {e}")
        return False

def monitor_scan():
    """执行监控扫描"""
    logging.info("开始扫描Wi-Fi设备...")
    
    # 扫描设备
    current_devices = scan_wifi_devices()
    
    if not current_devices:
        logging.warning("未扫描到任何设备")
        return
    
    # 检测新设备
    new_devices = check_new_devices(current_devices)
    
    if new_devices:
        # 构建通知内容
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        subject = f"发现新Wi-Fi设备 - {timestamp}"
        
        content = f"发现 {len(new_devices)} 个新设备:\n\n"
        for device in new_devices:
            content += f"MAC地址: {device['mac']}\n"
            content += f"IP地址: {device['ip']}\n"
            content += f"发现时间: {timestamp}\n"
            content += "-" * 30 + "\n"
        
        # 发送通知
        email_sent = send_email(subject, content)
        wechat_sent = send_wechat_message(f"发现新Wi-Fi设备:\n{content}")
        
        if email_sent or wechat_sent:
            # 将新设备添加到已知设备列表
            for device in new_devices:
                if device['mac'] not in CONFIG['known_devices']:
                    CONFIG['known_devices'].append(device['mac'])
            logging.info(f"发现{len(new_devices)}个新设备并已通知")
    else:
        logging.info("未发现新设备")

def main():
    """主函数"""
    logging.info("Wi-Fi设备监控脚本启动")
    
    # 设置定时任务
    schedule.every(CONFIG['scan_interval']).seconds.do(monitor_scan)
    
    # 立即执行一次
    monitor_scan()
    
    # 保持运行
    while True:
        schedule.run_pending()
        time.sleep(1)

if __name__ == "__main__":
    main()

使用说明:

  1. 安装依赖:脚本需要arp-scan工具,在Ubuntu上安装:sudo apt-get install arp-scan

  2. 配置修改

    • known_devices中添加你已知设备的MAC地址
    • 配置邮件参数(推荐使用QQ邮箱,需要开启SMTP和获取授权码)
    • 配置企业微信参数(需要注册企业微信并创建应用)
  3. 运行权限:由于需要扫描网络,需要sudo权限运行:sudo python wifi_monitor.py

  4. 企业微信配置

    • 注册企业微信
    • 创建应用获取AgentId
    • 在应用设置中获取Secret

这个脚本会定时扫描局域网内的设备,发现新设备时通过邮件和企业微信发送通知。你可以根据自己的需求调整扫描频率和通知方式。

一句话建议:记得先配置好邮件和微信的参数再运行。

我能说我以前写过一个类似的么😂😂😂

谢谢 🥰

感觉挺好玩儿的 😂

这是重新发明了 WIFI 探针吗?去年公司拿来一块给我研究了一下,连上网就能自己向配置好点地址 push 附近设备的 Mac 地址

看着蛮 6 的,硬件需求具体是啥?

1 个树莓派或者 Mac/Linux,1 个支持监听模式的 USB wifi 模块

那个小路由器刷好 openwrt 感觉更方便

好办法,应该可以找到类似 wireshark 这种扫描软件的 *.ipk 安装包

以前还写过类似局域网炸弹的东西😅😅

Love and Peace 😂

注意保护个人隐私,在公共场所

- 不要随意访问 Wi-Fi,还是用流量好
- 关闭 Wi-Fi

这样弄成本高了些,找个闲置路由器把程序刷进去就行了

探针都是这样,即使不连热点,都能扫出这些,所以不是用不用公共 wifi 的问题,是做不做坏事的问题,要做坏事用流量基站那边也一样有记录

为啥不用 airodump 呢

楼主问哈 图例中你用的是哪款 usb 网卡 树莓派免驱不~ 谢谢了~

型号 RT3070,树莓派直接免驱能用,淘宝上很便宜

我准备只带个大钳子去你家

回到顶部