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/generate_beacon/README.md | 19 ++++ examples/generate_beacon/generate_beacon.c | 80 +++++++++++++++ examples/generate_rtscts/README.md | 23 +++++ examples/generate_rtscts/generate_rtscts.c | 78 ++++++++++++++ examples/parse_beacon/README.md | 65 ++++++++++++ examples/parse_beacon/parse_beacon.c | 158 +++++++++++++++++++++++++++++ examples/parse_eapol/README.md | 74 ++++++++++++++ examples/parse_eapol/parse_eapol.c | 140 +++++++++++++++++++++++++ 8 files changed, 637 insertions(+) create mode 100644 examples/generate_beacon/README.md create mode 100644 examples/generate_beacon/generate_beacon.c create mode 100644 examples/generate_rtscts/README.md create mode 100644 examples/generate_rtscts/generate_rtscts.c create mode 100644 examples/parse_beacon/README.md create mode 100644 examples/parse_beacon/parse_beacon.c create mode 100644 examples/parse_eapol/README.md create mode 100644 examples/parse_eapol/parse_eapol.c (limited to 'examples') diff --git a/examples/generate_beacon/README.md b/examples/generate_beacon/README.md new file mode 100644 index 0000000..4b7103d --- /dev/null +++ b/examples/generate_beacon/README.md @@ -0,0 +1,19 @@ +# Generating 802.11 Beacons +This example shows the reader how to generate an 802.11 Beacon, with an SSID and Channel element. It also adds a tagged parameter with the string "libwifi-tag" inside. + +# Building and Using +``` +>> cd examples/generate_beacon/ +>> make +clang -Wall -Werror -O3 -o generate_beacon -c -o generate_beacon.o generate_beacon.c +clang -Wall -Werror -O3 -o generate_beacon generate_beacon.c -lpcap -lwifi +>> ./generate_beacon --file beacon.pcap +[+] Setup Complete +[*] Creating Beacon Frame +[*] Writing Beacon Frame to pcap +>> tshark -r beacon.pcap + 1 0.000000 ca:38:6d:6d:3f:bd → Broadcast 802.11 78 Beacon frame, SN=1383, FN=0, Flags=........, BI=100, SSID=libwifi-beacon +>> +``` +# Output +![image](https://user-images.githubusercontent.com/4153572/143600844-ce7dee11-46b0-40a5-a12c-881d79bd584d.png) diff --git a/examples/generate_beacon/generate_beacon.c b/examples/generate_beacon/generate_beacon.c new file mode 100644 index 0000000..2dad709 --- /dev/null +++ b/examples/generate_beacon/generate_beacon.c @@ -0,0 +1,80 @@ +#include + +#include + +#include +#include +#include +#include +#include +#include + +pcap_dumper_t *filedumper = NULL; + +void create_write_beacon() { + printf("[*] Creating Beacon Frame\n"); + struct libwifi_beacon beacon = {0}; + unsigned char transmitter[6] = {0}; + + libwifi_random_mac(transmitter); + unsigned char receiver[6] = "\xFF\xFF\xFF\xFF\xFF\xFF"; + + libwifi_create_beacon(&beacon, receiver, transmitter, "libwifi-beacon", 6); + libwifi_quick_add_tag(&beacon.tags, TAG_VENDOR_SPECIFIC, + (unsigned char *) "libwifi-tag", strlen("libwifi-tag")); + + unsigned char *buf = NULL; + size_t buf_len = libwifi_get_beacon_length(&beacon); + buf = malloc(buf_len); + if (buf == NULL) { + fprintf(stderr, "[!] Couldn't allocate buffer for beacon dump.\n"); + exit(EXIT_FAILURE); + } + memset(buf, 0, buf_len); + libwifi_dump_beacon(&beacon, buf, buf_len); + + printf("[*] Writing Beacon Frame to pcap\n"); + struct pcap_pkthdr pkt_hdr = {0}; + struct timeval tv = {0}; + pkt_hdr.caplen = buf_len; + pkt_hdr.len = buf_len; + gettimeofday(&tv, NULL); + pkt_hdr.ts = tv; + pcap_dump((unsigned char *) filedumper, &pkt_hdr, buf); +} + +void helpexit() { + fprintf(stderr, "[!] Usage: ./generate_beacon --file \n"); + exit(EXIT_FAILURE); +} + +int main(int argc, char **argv) { + pcap_t *handle = NULL; + char errbuf[PCAP_ERRBUF_SIZE] = {0}; + FILE *pcapfile = NULL; + + if (argc < 2) { + helpexit(); + } + if (strcmp(argv[1], "--file") == 0) { + pcapfile = fopen(argv[2], "w+"); + if ((handle = pcap_open_dead(DLT_IEEE802_11, BUFSIZ)) == NULL) { + fprintf(stderr, "[!] Error opening dead capture (%s)\n", errbuf); + exit(EXIT_FAILURE); + } + if ((filedumper = pcap_dump_fopen(handle, pcapfile)) == NULL) { + fprintf(stderr, "[!] Error opening file %s (%s)\n", argv[2], errbuf); + exit(EXIT_FAILURE); + } + } else { + helpexit(); + } + + printf("[+] Setup Complete\n"); + + create_write_beacon(); + + pcap_dump_close(filedumper); + pcap_close(handle); + return 0; +} diff --git a/examples/generate_rtscts/README.md b/examples/generate_rtscts/README.md new file mode 100644 index 0000000..a7db7c2 --- /dev/null +++ b/examples/generate_rtscts/README.md @@ -0,0 +1,23 @@ +# Generating 802.11 RTS and CTS Frames +This example shows the reader how to generate an RTS and a CTS Frame, with a random transmitter and a 32ms duration. + +# Building and Using +``` +>> cd examples/generate_rtscts/ +>> make +clang -Wall -Werror -O3 -o generate_rtscts -c -o generate_rtscts.o generate_rtscts.c +clang -Wall -Werror -O3 -o generate_rtscts generate_rtscts.c -lpcap -lwifi +>> ./generate_rtscts --file rtscts.pcap +[+] Setup Complete +[*] Creating RTS Frame +[*] Writing RTS Frame to pcap +[*] Creating CTS Frame +[*] Writing CTS Frame to pcap +>> tshark -r rtscts.pcap + 1 0.000000 J125Nati_aa:bb:cc (00:20:91:aa:bb:cc) (TA) → Broadcast (ff:ff:ff:ff:ff:ff) (RA) 802.11 16 Request-to-send, Flags=........ + 2 0.000008 → Broadcast (ff:ff:ff:ff:ff:ff) (RA) 802.11 10 Clear-to-send, Flags=........ +>> +``` + +# Output +![image](https://user-images.githubusercontent.com/4153572/143601868-da7e9c99-2534-4fe6-9608-68f5af1ad882.png) diff --git a/examples/generate_rtscts/generate_rtscts.c b/examples/generate_rtscts/generate_rtscts.c new file mode 100644 index 0000000..f449a06 --- /dev/null +++ b/examples/generate_rtscts/generate_rtscts.c @@ -0,0 +1,78 @@ +#include + +#include + +#include +#include +#include +#include +#include +#include + +pcap_dumper_t *filedumper = NULL; + +void create_write_rtscts() { + printf("[*] Creating RTS Frame\n"); + struct libwifi_rts rts = {0}; + unsigned char transmitter[6] = "\x00\x20\x91\xAA\xBB\xCC"; + unsigned char receiver[6] = "\xFF\xFF\xFF\xFF\xFF\xFF"; + libwifi_create_rts(&rts, transmitter, receiver, 32); + + printf("[*] Writing RTS Frame to pcap\n"); + struct pcap_pkthdr pkt_hdr = {0}; + struct timeval tv = {0}; + pkt_hdr.caplen = sizeof(struct libwifi_rts); + pkt_hdr.len = sizeof(struct libwifi_rts); + gettimeofday(&tv, NULL); + pkt_hdr.ts = tv; + pcap_dump((unsigned char *) filedumper, &pkt_hdr, (const unsigned char *) &rts); + + printf("[*] Creating CTS Frame\n"); + struct libwifi_cts cts = {0}; + libwifi_create_cts(&cts, receiver, 32); + + printf("[*] Writing CTS Frame to pcap\n"); + memset(&pkt_hdr, 0, sizeof(struct pcap_pkthdr)); + memset(&tv, 0, sizeof(struct timeval)); + pkt_hdr.caplen = sizeof(struct libwifi_cts); + pkt_hdr.len = sizeof(struct libwifi_cts); + gettimeofday(&tv, NULL); + pkt_hdr.ts = tv; + pcap_dump((unsigned char *) filedumper, &pkt_hdr, (const unsigned char *) &cts); +} + +void helpexit() { + fprintf(stderr, "[!] Usage: ./generate_beacon --file \n"); + exit(EXIT_FAILURE); +} + +int main(int argc, char **argv) { + pcap_t *handle = NULL; + char errbuf[PCAP_ERRBUF_SIZE] = {0}; + FILE *pcapfile = NULL; + + if (argc < 2) { + helpexit(); + } + if (strcmp(argv[1], "--file") == 0) { + pcapfile = fopen(argv[2], "w+"); + if ((handle = pcap_open_dead(DLT_IEEE802_11, BUFSIZ)) == NULL) { + fprintf(stderr, "[!] Error opening dead capture (%s)\n", errbuf); + exit(EXIT_FAILURE); + } + if ((filedumper = pcap_dump_fopen(handle, pcapfile)) == NULL) { + fprintf(stderr, "[!] Error opening file %s (%s)\n", argv[2], errbuf); + exit(EXIT_FAILURE); + } + } else { + helpexit(); + } + + printf("[+] Setup Complete\n"); + + create_write_rtscts(); + + pcap_dump_close(filedumper); + pcap_close(handle); + return 0; +} 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; +} diff --git a/examples/parse_eapol/README.md b/examples/parse_eapol/README.md new file mode 100644 index 0000000..4aa206a --- /dev/null +++ b/examples/parse_eapol/README.md @@ -0,0 +1,74 @@ +# Parsing 802.11 Handshake / EAPOL Frames +This example shows the reader how to parse 802.11 Handshakes from a pcap, outputting the EAPOL version, type, length, and data such as Nonce, IV, MIC and EAPOL Key Data. + +# Building and Using +``` +>> cd examples/parse_eapol/ +>> make +clang -Wall -Werror -O3 -o parse_eapol -c -o parse_eapol.o parse_eapol.c +clang -Wall -Werror -O3 -o parse_eapol parse_eapol.c -lpcap -lwifi +>> ./parse_eapol --file ~/libwifi-handshake.pcap +[+] Setup Complete +WPA Handshake Message: 1 (Message 1) +EAPOL: Version: 2 +EAPOL: Type: 3 +EAPOL: Length: 95 +EAPOL: Descriptor: 2 +EAPOL: Key Info: Information: 0x008a +EAPOL: Key Info: Key Length: 16 +EAPOL: Key Info: Replay Counter: 1 +EAPOL: Key Info: Nonce: 43 79 98 09 6a 0e dc 73 8d 44 3b 55 ce b5 47 2c fd 39 0c 87 51 e4 f0 77 d9 5b 5c e1 dc 59 bd 75 +EAPOL: Key Info: IV: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +EAPOL: Key Info: RSC: 00 00 00 00 00 00 00 00 +EAPOL: Key Info: ID: 00 00 00 00 00 00 00 00 +EAPOL: Key Info: MIC: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +EAPOL: Key Info: Key Data Length: 0 + +WPA Handshake Message: 2 (Message 2) +EAPOL: Version: 1 +EAPOL: Type: 3 +EAPOL: Length: 123 +EAPOL: Descriptor: 2 +EAPOL: Key Info: Information: 0x010a +EAPOL: Key Info: Key Length: 0 +EAPOL: Key Info: Replay Counter: 1 +EAPOL: Key Info: Nonce: de ed a2 79 e3 c4 96 ba 25 8b ba 84 76 0a 00 69 2e 2c 10 41 24 1a f3 6f 70 9a 4b db 5f 93 47 80 +EAPOL: Key Info: IV: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +EAPOL: Key Info: RSC: 00 00 00 00 00 00 00 00 +EAPOL: Key Info: ID: 00 00 00 00 00 00 00 00 +EAPOL: Key Info: MIC: 6c 23 fe 8d 68 35 c9 5a 77 82 25 4b 56 41 70 71 +EAPOL: Key Info: Key Data Length: 28 +EAPOL: Key Info: Key Data: 30 1a 01 00 00 0f ac 04 01 00 00 0f ac 04 01 00 00 0f ac 02 80 00 00 00 00 0f ac 06 + +WPA Handshake Message: 4 (Message 3) +EAPOL: Version: 2 +EAPOL: Type: 3 +EAPOL: Length: 183 +EAPOL: Descriptor: 2 +EAPOL: Key Info: Information: 0x13ca +EAPOL: Key Info: Key Length: 16 +EAPOL: Key Info: Replay Counter: 2 +EAPOL: Key Info: Nonce: 43 79 98 09 6a 0e dc 73 8d 44 3b 55 ce b5 47 2c fd 39 0c 87 51 e4 f0 77 d9 5b 5c e1 dc 59 bd 75 +EAPOL: Key Info: IV: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +EAPOL: Key Info: RSC: 00 00 00 00 00 00 00 00 +EAPOL: Key Info: ID: 00 00 00 00 00 00 00 00 +EAPOL: Key Info: MIC: b7 e7 f1 60 f8 cf 3f ec 8f b3 c5 29 e4 a1 d0 05 +EAPOL: Key Info: Key Data Length: 88 +EAPOL: Key Info: Key Data: 5e b1 a7 ef db 8d 55 06 d5 c8 89 e7 ca 55 ea cf f5 fa 08 18 ef 4e 46 6e b6 3e 62 d1 30 e7 e5 38 ef 2b 37 61 55 03 9e 84 31 75 3e 44 bd 87 12 9c 94 52 db fb 6a 58 4e 1f 94 e0 16 a9 e9 cb 36 48 c8 ed 20 d3 ff 37 a6 7e 12 3f 0b fc 2c a6 cb 72 c3 6a bf 01 32 b1 6e 1b + +WPA Handshake Message: 8 (Message 4) +EAPOL: Version: 1 +EAPOL: Type: 3 +EAPOL: Length: 95 +EAPOL: Descriptor: 2 +EAPOL: Key Info: Information: 0x030a +EAPOL: Key Info: Key Length: 0 +EAPOL: Key Info: Replay Counter: 2 +EAPOL: Key Info: Nonce: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +EAPOL: Key Info: IV: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +EAPOL: Key Info: RSC: 00 00 00 00 00 00 00 00 +EAPOL: Key Info: ID: 00 00 00 00 00 00 00 00 +EAPOL: Key Info: MIC: 13 6e 07 be 17 51 01 e2 03 5d 4c b1 43 e1 4b c7 +EAPOL: Key Info: Key Data Length: 0 +>> +``` diff --git a/examples/parse_eapol/parse_eapol.c b/examples/parse_eapol/parse_eapol.c new file mode 100644 index 0000000..259ee5f --- /dev/null +++ b/examples/parse_eapol/parse_eapol.c @@ -0,0 +1,140 @@ +#include + +#include + +#include +#include +#include + +static int has_radiotap = 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 parsed frame is a data frame + if (frame.frame_control.type == TYPE_DATA) { + // Ensure the parsed data frame is a WPA handshake + if (libwifi_check_wpa_handshake(&frame) > 0) { + // Use libwifi to get the EAPOL message part, and also pretty-print it + int part = libwifi_check_wpa_message(&frame); + printf("WPA Handshake Message: %d (%s)\n", part, libwifi_get_wpa_message_string(&frame)); + + // Initlaise a WPA Authentication Data struct and populate it + struct libwifi_wpa_auth_data data = {0}; + libwifi_get_wpa_data(&frame, &data); + + // Print all of the available WPA Auth data + printf("EAPOL: Version: %d\n", data.version); + printf("EAPOL: Type: %d\n", data.type); + printf("EAPOL: Length: %d\n", data.length); + printf("EAPOL: Descriptor: %d\n", data.descriptor); + printf("EAPOL: Key Info: Information: 0x%04x\n", data.key_info.information); + printf("EAPOL: Key Info: Key Length: %d\n", data.key_info.key_length); + printf("EAPOL: Key Info: Replay Counter: %lu\n", data.key_info.replay_counter); + printf("EAPOL: Key Info: Nonce: "); + for (size_t i = 0; i < sizeof(data.key_info.nonce); ++i) { + printf("%02x ", data.key_info.nonce[i]); + } + printf("\n"); + + printf("EAPOL: Key Info: IV: "); + for (size_t i = 0; i < sizeof(data.key_info.iv); ++i) { + printf("%02x ", data.key_info.iv[i]); + } + printf("\n"); + + printf("EAPOL: Key Info: RSC: "); + for (size_t i = 0; i < sizeof(data.key_info.rsc); ++i) { + printf("%02x ", data.key_info.rsc[i]); + } + printf("\n"); + + printf("EAPOL: Key Info: ID: "); + for (size_t i = 0; i < sizeof(data.key_info.id); ++i) { + printf("%02x ", data.key_info.id[i]); + } + printf("\n"); + + printf("EAPOL: Key Info: MIC: "); + for (size_t i = 0; i < sizeof(data.key_info.mic); ++i) { + printf("%02x ", data.key_info.mic[i]); + } + printf("\n"); + + printf("EAPOL: Key Info: Key Data Length: %d\n", data.key_info.key_data_length); + if (data.key_info.key_data_length) { + printf("EAPOL: Key Info: Key Data: "); + for (size_t i = 0; i < data.key_info.key_data_length; ++i) { + printf("%02x ", data.key_info.key_data[i]); + } + printf("\n"); + } + + // Cleanup the WPA Data + libwifi_free_wpa_data(&data); + + 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_eapol.pcap"); + pcap_loop(handle, -1 /*INFINITY*/, &handle_pkt, (unsigned char *) dumper); + + pcap_dump_close(dumper); + pcap_close(handle); + + return 0; +} -- cgit 1.4.1