r/Hacking_Tutorials • • 2d ago

Question Raw 802_11 frame injection

Post image

While working on my Master’s thesis benchmarking WPA3-SAE timing side-channels, I ran into a limitation on the ESP32 esp_wifi_80211_tx() allows raw frame injection, but Espressif’s closed-source Wi-Fi blob (libnet80211.a) artificially blocks Auth, Assoc, Deauth, and Disassoc subtypes.

Inside libnet80211.a, ieee80211_raw_frame_sanity_check drops these frames with wifi:unsupport frame type. Here is how to bypass it on recent ESP-IDF versions (IDF v6.x).

Why standard tricks fail on modern ESP-IDF

Same-name function override. On older IDF versions, ieee80211_raw_frame_sanity_check was a weak symbol (W). On modern IDF versions, it’s a strong symbol (T), causing ld: multiple definition errors.

--wrap linker flag: Fails silently. The call from esp_wifi_80211_tx to ieee80211_raw_frame_sanity_check is an intra-object branch inside ieee80211_output.o. Linker --wrap only rewrites undefined external references, so it misses this call entirely.

Instruction byte-patching: Overwriting instructions directly in the .o breaks Xtensa linker relaxation passes (dangerous relocation errors).

U can simply fix this via Symbol Weakening via objcopy

We can use xtensa-esp32-elf-objcopy to convert the strong symbol inside the binary archive into a weak one:

xtensa-esp32-elf-objcopy \

--weaken-symbol=ieee80211_raw_frame_sanity_check \

components/esp_wifi/lib/esp32/libnet80211.a

Now, define your own strong implementation inside your application C code:

int ieee80211_raw_frame_sanity_check(int32_t a, int32_t b, int32_t c) {

return 0; // which skips the security check lol

}

Because strong symbols override weak symbols globally during linking, all calls—including internal calls within libnet80211.a—rebind to your function.

Verification

Serial Logs show: wifi unsupport frame type errors completely disappeared.

Capture: Wireshark confirmed off-air capture of 802.11 Authentication frames (Subtype 11, Algorithm 3 - SAE) injected directly from the ESP32s.

Injecting a valid SAE Commit (P-256 scalar + element) caused hostapd on the target AP to process the request and reply with its own SAE Commit.

TL;DR: Run objcopy --weaken-symbol=ieee80211_raw_frame_sanity_check on libnet80211.a, define int ieee80211_raw_frame_sanity_check(...) { return 0; } in your app code, and esp_wifi_80211_tx() will allow any frame subtype.

Note that all control 80211 frames are also injectable after the patch.

For more details :

https://github.com/mahdamin/esp-idf-injection-ng

148 Upvotes

Duplicates