From ae6c98a48da409d040604aeffb84a38155fb5bac Mon Sep 17 00:00:00 2001 From: Marc Date: Tue, 30 Nov 2021 22:39:26 +0000 Subject: Initial Commit Signed-off-by: Marc --- examples/parse_beacon/README.md | 65 ++++++++++++++ examples/parse_beacon/parse_beacon.c | 158 +++++++++++++++++++++++++++++++++++ 2 files changed, 223 insertions(+) create mode 100644 examples/parse_beacon/README.md create mode 100644 examples/parse_beacon/parse_beacon.c (limited to 'examples/parse_beacon') diff --git a/examples/parse_beacon/README.md b/examples/parse_beacon/README.md new file mode 100644 index 0000000..a9b085b --- /dev/null +++ b/examples/parse_beacon/README.md @@ -0,0 +1,65 @@ +# Parsing 802.11 Beacon Frames +This example shows the reader how to parse 802.11 Beacons from a pcap, outputting the SSID, BSSID, Channel, Security Information, and more to the terminal. + +# Building and Using +``` +>> cd examples/parse_beacon/ +>> make +clang -Wall -Werror -O3 -o parse_beacon -c -o parse_beacon.o parse_beacon.c +clang -Wall -Werror -O3 -o parse_beacon parse_beacon.c -lpcap -lwifi +>> ./parse_beacon --file ~/beacon.pcap [1/789] +[+] Setup Complete +ESSID: libwifi-wpa2/3 +BSSID: 7e:fc:5e:51:93:31 +Receiver: ff:ff:ff:ff:ff:ff +Transmitter: 7e:fc:5e:51:93:31 +Channel: 11 +WPS: No +Encryption: WPA3, WPA2 + Group Ciphers: CCMP128 + Pairwise Ciphers: CCMP128 + Auth Key Suites: PSK, SAE + MFP Capable: Yes +Tagged Parameters: + Tag: 0 (Size: 14) + 14 bytes of Tag Data: 6c 69 62 77 69 66 69 2d 77 70 61 32 2f 33 + Tag: 1 (Size: 8) + 8 bytes of Tag Data: 82 84 8b 96 24 30 48 6c + Tag: 3 (Size: 1) + 1 bytes of Tag Data: 0b + Tag: 5 (Size: 4) + 4 bytes of Tag Data: 00 02 00 00 + Tag: 7 (Size: 6) + 6 bytes of Tag Data: 47 42 20 01 0d 80 + Tag: 32 (Size: 1) + 1 bytes of Tag Data: 00 + Tag: 35 (Size: 2) + 2 bytes of Tag Data: 10 00 + Tag: 42 (Size: 1) + 1 bytes of Tag Data: 00 + Tag: 50 (Size: 4) + 4 bytes of Tag Data: 0c 12 18 60 + Tag: 48 (Size: 24) + 16 bytes of Tag Data: 01 00 00 0f ac 04 01 00 00 0f ac 04 02 00 00 0f + Tag: 45 (Size: 26) + 16 bytes of Tag Data: 2d 00 1b ff ff 00 00 00 00 00 00 00 00 00 00 00 + Tag: 61 (Size: 22) + 16 bytes of Tag Data: 0b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + Tag: 127 (Size: 8) + 8 bytes of Tag Data: 04 00 08 00 00 00 00 40 + Tag: 255 (Size: 28) + 16 bytes of Tag Data: 23 01 08 00 1a 00 80 20 20 02 00 0d 00 9e 00 0c + Tag: 255 (Size: 7) + 7 bytes of Tag Data: 24 04 00 00 00 fc ff + Tag: 255 (Size: 14) + 14 bytes of Tag Data: 26 00 03 a4 ff 27 a4 ff 42 43 ff 62 32 ff + Tag: 255 (Size: 4) + 4 bytes of Tag Data: 27 00 00 00 + Tag: 221 (Size: 30) + 16 bytes of Tag Data: 00 90 4c 04 08 bf 0c 32 70 81 0f fa ff 00 00 fa + Tag: 221 (Size: 10) + 10 bytes of Tag Data: 00 10 18 02 00 00 1c 00 00 00 + Tag: 221 (Size: 24) + 16 bytes of Tag Data: 00 50 f2 02 01 01 00 00 03 a4 00 00 27 a4 00 00 +>> +``` diff --git a/examples/parse_beacon/parse_beacon.c b/examples/parse_beacon/parse_beacon.c new file mode 100644 index 0000000..4e320b7 --- /dev/null +++ b/examples/parse_beacon/parse_beacon.c @@ -0,0 +1,158 @@ +#include + +#include + +#include +#include +#include + +static int has_radiotap = 0; + +int print_tag_info(unsigned char *tag_data, size_t tag_data_len) { + // Initialise a libwifi_tag_iterator + struct libwifi_tag_iterator it = {0}; + if (libwifi_tag_iterator_init(&it, tag_data, tag_data_len) != 0) { + return -1; + } + + do { + printf("\tTag: %d (Size: %d)\n", it.tag_header->tag_num, it.tag_header->tag_len); + + int max_size = 16; + if (it.tag_header->tag_len < 16) { + max_size = it.tag_header->tag_len; + } + printf("\t%d bytes of Tag Data: ", max_size); + for (size_t i = 0; i < max_size; i++) { + printf("%02x ", it.tag_data[i]); + } + printf("\n"); + } while (libwifi_tag_iterator_next(&it) != -1); + + return 0; +} + +void handle_pkt(unsigned char *args, const struct pcap_pkthdr *header, const unsigned char *packet) { + unsigned long data_len = header->caplen; + unsigned char *data = (unsigned char *) packet; + + // Initialise a libwifi_frame struct and populate it + struct libwifi_frame frame = {0}; + int ret = libwifi_get_wifi_frame(&frame, data, data_len, has_radiotap); + if (ret != 0) { + return; + } + + // Ensure the frame is a Beacon frame + if (frame.frame_control.type == TYPE_MANAGEMENT && frame.frame_control.subtype == SUBTYPE_BEACON) { + // Initalise a libwifi_bss struct and populate it with the data from the sniffed frame + struct libwifi_bss bss = {0}; + ret = libwifi_parse_beacon(&bss, &frame); + if (ret != 0) { + return; + } + + // Print basic information from the new struct + printf("ESSID: %s\n", bss.hidden ? "(hidden)" : bss.ssid); + printf("BSSID: " MACSTR "\n", MAC2STR(bss.bssid)); + printf("Receiver: " MACSTR "\n", MAC2STR(bss.receiver)); + printf("Transmitter: " MACSTR "\n", MAC2STR(bss.transmitter)); + printf("Channel: %d\n", bss.channel); + printf("WPS: %s\n", bss.wps ? "Yes" : "No"); + + // Initialse a char buffer of length LIBWIFI_SECURITY_BUF_LEN, and use libwifi to + // write the security suite (WEP, WPA, etc) to it, before printing it. + char sec_buf[LIBWIFI_SECURITY_BUF_LEN]; + libwifi_get_security_type(&bss, sec_buf); + printf("Encryption: %s\n", sec_buf); + + // We can re-use the sec_buf buffer for other security related items, since libwifi + // will take care of the memory for us. + // We'll use the same buffer to get the WPA/2/3 group ciphers from the beacon, if any. + libwifi_get_group_ciphers(&bss, sec_buf); + printf("\tGroup Ciphers: %s\n", sec_buf); + + // ... and the same for the pairwise ciphers + libwifi_get_pairwise_ciphers(&bss, sec_buf); + printf("\tPairwise Ciphers: %s\n", sec_buf); + + // ... and the same for the authentication maagement key suites + libwifi_get_auth_key_suites(&bss, sec_buf); + printf("\tAuth Key Suites: %s\n", sec_buf); + + // Check for enabled RSN Capabilities. In this example, we will check for the + // presence of Management Frame Protection (802.11w) + if (bss.rsn_info.rsn_capabilities & LIBWIFI_RSN_CAPAB_MFP_CAPABLE) { + printf("\tMFP Capable: Yes\n"); + } + if (bss.rsn_info.rsn_capabilities & LIBWIFI_RSN_CAPAB_MFP_REQUIRED) { + printf("\tMFP Required: Yes\n"); + } + + // If any tagged parameters are available for this frame, we can iterate through them + // since libwifi will automatically find them. + if (bss.tags.length) { + printf("Tagged Parameters:\n"); + print_tag_info(bss.tags.parameters, bss.tags.length); + } else { + printf("Tagged Parameters: None\n"); + } + + // Cleanup the libwifi bss + libwifi_free_bss(&bss); + } + + printf("\n"); + + // Clean up the libwifi frame + libwifi_free_wifi_frame(&frame); +} + +void helpexit() { + fprintf(stderr, "[!] Usage: ./parse_eapol --file \n"); + exit(EXIT_FAILURE); +} + +int main(int argc, char **argv) { + struct bpf_program *filter = NULL; + pcap_t *handle = NULL; + pcap_dumper_t *dumper = NULL; + char errbuf[PCAP_ERRBUF_SIZE]; + + if (argc < 2) { + helpexit(); + } + if (strcmp(argv[1], "--file") == 0) { + if ((handle = pcap_open_offline(argv[2], errbuf)) == NULL) { + fprintf(stderr, "[!] Error opening file %s (%s)\n", argv[2], errbuf); + exit(EXIT_FAILURE); + } + } else { + helpexit(); + } + + int linktype = pcap_datalink(handle); + if (linktype == DLT_IEEE802_11_RADIO) { + has_radiotap = 1; + } + if (linktype != DLT_IEEE802_11 && linktype != DLT_IEEE802_11_RADIO) { + fprintf(stderr, "[!] 802.11 and radiotap headers not provided (%d)\n", pcap_datalink(handle)); + pcap_close(handle); + exit(EXIT_FAILURE); + } + + if ((filter = malloc(sizeof(struct bpf_program))) == NULL) { + fprintf(stderr, "[!] There was an error allocating memory for the filter.\n"); + pcap_close(handle); + exit(EXIT_FAILURE); + } + + printf("[+] Setup Complete\n"); + + dumper = pcap_dump_open(handle, "/tmp/parse_beacon.pcap"); + pcap_loop(handle, -1 /*INFINITY*/, &handle_pkt, (unsigned char *) dumper); + + pcap_dump_close(dumper); + pcap_close(handle); + return 0; +} -- cgit 1.4.1