0% found this document useful (0 votes)
46 views53 pages

Hcxhashtool

This document contains header files and global variables for a C program that analyzes WiFi capture files. It includes header files for system functions, OpenSSL cryptography, CURL networking, and custom header files. It defines global variables to track statistics like the number of lines read, filter settings, and counts of different record types written to output files. Functions are declared to initialize these variables, close the program, get the vendor for a MAC address, and print a status report.

Uploaded by

Vladimir K.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
46 views53 pages

Hcxhashtool

This document contains header files and global variables for a C program that analyzes WiFi capture files. It includes header files for system functions, OpenSSL cryptography, CURL networking, and custom header files. It defines global variables to track statistics like the number of lines read, filter settings, and counts of different record types written to output files. Functions are declared to initialize these variables, close the program, get the vendor for a MAC address, and print a status report.

Uploaded by

Vladimir K.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 53

#define _GNU_SOURCE

#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <inttypes.h>
#include <libgen.h>
#include <limits.h>
#include <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#if defined (__APPLE__) || defined(__OpenBSD__)


#include <sys/socket.h>
#endif

#ifdef _WIN32
#include <winsock2.h>
#else
#include <arpa/inet.h>
#endif

#include <curl/curl.h>
#include <openssl/core.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/params.h>
#include <openssl/types.h>

#include "include/hcxhashtool.h"
#include "include/strings.c"
#include "include/fileops.c"
#include "include/ieee80211.h"
#include "include/byteops.c"

/*===========================================================================*/
/* global var */
static const char *usedoui;
static int ouicount;
static int ouilistcount;
static ouilist_t *ouilist;
static hashlist_t *hashlist;
static long int pbkdf2count;
static long int pbkdf2readerrorcount;
static long int hashlistcount;
static long int readcount;
static long int readerrorcount;
static long int pmkideapolcount;
static long int pmkidcount;
static long int eapolcount;
static long int pmkidwrittencount;
static long int eapolwrittencount;
static long int essidwrittencount;
static long int essidrawwrittencount;
static long int hccapxwrittencount;
static long int hccapwrittencount;
static long int johnpmkidwrittencount;
static long int johneapolwrittencount;

static EVP_MAC *hmac;


static EVP_MAC *cmac;
static EVP_MAC_CTX *ctxhmac;
static EVP_MAC_CTX *ctxcmac;
static OSSL_PARAM paramsmd5[3];
static OSSL_PARAM paramssha1[3];
static OSSL_PARAM paramssha256[3];
static OSSL_PARAM paramsaes128[3];

static int hashtype;


static int essidlen;
static int essidlenmin;
static int essidlenmax;
static int filteressidlen;
static char *filteressidptr;
static int filteressidpartlen;
static char *filteressidpartptr;

static char *filtervendorptr;


static char *filtervendorapptr;
static char *filtervendorclientptr;

static bool flagpsk;


static bool flagpmk;
static bool flagessidgroup;
static bool flagmacapgroup;
static bool flagmacclientgroup;
static bool flagouigroup;
static bool flagvendorout;
static bool flaghccapsingleout;
static bool caseflag;
static bool statusflag;

static bool flagfiltermacap;


static uint8_t filtermacap[6];

static bool flagfiltermacclient;


static uint8_t filtermacclient[6];

static bool flagfilterouiap;


static uint8_t filterouiap[3];

static bool flagfilterouiclient;


static uint8_t filterouiclient[3];

static bool flagfilterauthorized;


static bool flagfilterchallenge;
static bool flagfilterrcchecked;
static bool flagfilterrcnotchecked;
static bool flagfilterapless;

static int pskptrlen;


static char *pskptr;
static uint8_t pmk[32];
/*===========================================================================*/
static void closelists(void)
{
if(hashlist != NULL) free(hashlist);
if(ouilist != NULL) free(ouilist);
if(ctxhmac != NULL)
{
EVP_MAC_CTX_free(ctxhmac);
EVP_MAC_free(hmac);
}
if(ctxcmac != NULL)
{
EVP_MAC_CTX_free(ctxcmac);
EVP_MAC_free(cmac);
}
EVP_cleanup();
CRYPTO_cleanup_all_ex_data();
ERR_free_strings();
return;
}
/*===========================================================================*/
static bool initlists(void)
{
ouicount = 0;
ouilistcount = OUILIST_MAX;
hashlistcount = HASHLIST_MAX;
readcount = 0;
readerrorcount = 0;
pmkideapolcount = 0;
pmkidcount = 0;
eapolcount = 0;
pmkidwrittencount = 0;
eapolwrittencount = 0;
essidwrittencount = 0;
essidrawwrittencount = 0;
johnpmkidwrittencount = 0;
johneapolwrittencount = 0;
hccapxwrittencount = 0;
hccapwrittencount = 0;
if((hashlist = (hashlist_t*)calloc(hashlistcount, HASHLIST_SIZE)) == NULL) return
false;
if((ouilist = (ouilist_t*)calloc(ouilistcount, OUILIST_SIZE)) == NULL) return
false;

ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();

hmac = NULL;
ctxhmac = NULL;
cmac = NULL;
ctxcmac = NULL;

hmac = EVP_MAC_fetch(NULL, "hmac", NULL);


if(hmac == NULL) return false;
cmac = EVP_MAC_fetch(NULL, "cmac", NULL);
if(cmac == NULL) return false;

char md5[] = "md5";


paramsmd5[0] = OSSL_PARAM_construct_utf8_string("digest", md5, 0);
paramsmd5[1] = OSSL_PARAM_construct_end();
char sha1[] = "sha1";
paramssha1[0] = OSSL_PARAM_construct_utf8_string("digest", sha1, 0);
paramssha1[1] = OSSL_PARAM_construct_end();

char sha256[] = "sha256";


paramssha256[0] = OSSL_PARAM_construct_utf8_string("digest", sha256, 0);
paramssha256[1] = OSSL_PARAM_construct_end();

char aes[] = "aes-1280-cbc";


paramsaes128[0] = OSSL_PARAM_construct_utf8_string("cipher", aes, 0);
paramsaes128[1] = OSSL_PARAM_construct_end();

ctxhmac = EVP_MAC_CTX_new(hmac);
if(ctxhmac == NULL) return false;
ctxcmac = EVP_MAC_CTX_new(cmac);
if(ctxcmac == NULL) return false;
return true;
}
/*===========================================================================*/
static char *getvendor(uint8_t *mac)
{
static ouilist_t * zeiger;
static char unknown[] = "Unknown";

for(zeiger = ouilist; zeiger < ouilist +ouicount; zeiger++)


{
if(memcmp(zeiger->oui, mac, 3) == 0) return zeiger->vendor;
if(memcmp(zeiger->oui, mac, 3) > 0) return unknown;
}
return unknown;
}
/*===========================================================================*/
static void printstatus(void)
{
static char *vendor;

fprintf(stdout, "\nOUI information file..........: %s\n", usedoui);


if(ouicount > 0) fprintf(stdout, "OUI entries...................: %d\n",
ouicount);
if(readcount > 0) fprintf(stdout, "total lines read..............: %ld\n",
readcount);
if(flagvendorout == true)
{
fprintf(stdout, "\n");
return;
}
if(pbkdf2count > 0) fprintf(stdout, "PBKDF2
lines..................: %ld\n", pbkdf2count);
if(pbkdf2readerrorcount > 0) fprintf(stdout, "PBKDF2
errors.................: %ld\n", pbkdf2readerrorcount);
if(readerrorcount > 0) fprintf(stdout, "read
errors...................: %ld\n", readerrorcount);
if(pmkideapolcount > 0) fprintf(stdout, "valid hash
lines..............: %ld\n", pmkideapolcount);
if(pmkidcount > 0) fprintf(stdout, "PMKID hash
lines..............: %ld\n", pmkidcount);
if(eapolcount > 0) fprintf(stdout, "EAPOL hash
lines..............: %ld\n", eapolcount);
if(essidlenmin != 0) fprintf(stdout, "filter by ESSID len
min.......: %d\n", essidlenmin);
if(essidlenmax != 32) fprintf(stdout, "filter by ESSID len
max.......: %d\n", essidlenmax);
if(filteressidptr != NULL) fprintf(stdout, "filter by
ESSID...............: %s\n", filteressidptr);
if(filteressidpartptr != NULL) fprintf(stdout, "filter by part of
ESSID.......: %s\n", filteressidpartptr);
if(flagfiltermacap == true)
{
vendor = getvendor(filtermacap);
fprintf(stdout, "filter by MAC.................: %02x%02x%02x%02x%02x%02x
(%s)\n", filtermacap[0], filtermacap[1], filtermacap[2], filtermacap[3],
filtermacap[4], filtermacap[5], vendor);
}
if(flagfiltermacclient == true)
{
vendor = getvendor(filtermacclient);
fprintf(stdout, "filter by MAC.................: %02x%02x%02x%02x%02x%02x
(%s)\n", filtermacclient[0], filtermacclient[1], filtermacclient[2],
filtermacclient[3], filtermacclient[4], filtermacclient[5], vendor);
}

if(flagfilterouiap == true)
{
vendor = getvendor(filterouiap);
fprintf(stdout, "filter AP by OUI..............: %02x%02x%02x (%s)\n",
filterouiap[0], filterouiap[1], filterouiap[2], vendor);
}
if(filtervendorptr != NULL) fprintf(stdout, "filter AP and CLIENT by
VENDOR: %s\n", filtervendorptr);
if(filtervendorapptr != NULL) fprintf(stdout, "filter AP by
VENDOR...........: %s\n", filtervendorapptr);
if(filtervendorclientptr != NULL) fprintf(stdout, "filter CLIENT by
VENDOR.......: %s\n", filtervendorclientptr);
if(flagfilterouiclient == true)
{
vendor = getvendor(filterouiclient);
fprintf(stdout, "filter CLIENT by OUI..........: %02x%02x%02x (%s)\n",
filterouiclient[0], filterouiclient[1], filterouiclient[2], vendor);
}
if(flagfilterapless == true) fprintf(stdout, "filter by
M2..................: requested from client (AP-LESS)\n");
if(flagfilterrcchecked == true) fprintf(stdout, "filter by
replaycount.........: checked\n");
if(flagfilterrcnotchecked == true) fprintf(stdout, "filter by
replaycount.........: not checked\n");
if(flagfilterauthorized == true) fprintf(stdout, "filter by
status..............: authorized (M1M4, M2M3 or M3M4)\n");
if(flagfilterchallenge == true) fprintf(stdout, "filter by
status..............: challenge (M1M2)\n");
if(pmkidwrittencount > 0) fprintf(stdout, "PMKID
written.................: %ld\n", pmkidwrittencount);
if(eapolwrittencount > 0) fprintf(stdout, "EAPOL
written.................: %ld\n", eapolwrittencount);
if(johnpmkidwrittencount > 0) fprintf(stdout, "PMKID written to
john.........: %ld\n", johnpmkidwrittencount);
if(johneapolwrittencount > 0) fprintf(stdout, "EAPOL written to
john.........: %ld\n", johneapolwrittencount);
if(hccapxwrittencount > 0) fprintf(stdout, "EAPOL written to
hccapx.......: %ld\n", hccapxwrittencount);
if(hccapwrittencount > 0) fprintf(stdout, "EAPOL written to
hccap........: %ld\n", hccapwrittencount);
if(essidwrittencount > 0) fprintf(stdout, "ESSID (unique)
written........: %ld\n", essidwrittencount);
if(essidrawwrittencount > 0) fprintf(stdout, "ESSID
written.................: %ld\n", essidrawwrittencount);
fprintf(stdout, "\n");
return;
}
/*===========================================================================*/
static void testeapolpmk(hashlist_t *zeiger)
{
static int keyver;
static int p;
static wpakey_t *wpak;
static uint8_t *pkeptr;

static uint8_t eapoltmp[1024];


static uint8_t pkedata[102];

wpak = (wpakey_t*)&zeiger->eapol[EAPAUTH_SIZE];
keyver = ntohs(wpak->keyinfo) & WPA_KEY_INFO_TYPE_MASK;

if((keyver == 1) || (keyver == 2))


{
memset(&pkedata, 0, sizeof(pkedata));
pkeptr = pkedata;
memcpy(pkeptr, "Pairwise key expansion", 23);
if(memcmp(zeiger->ap, zeiger->client, 6) < 0)
{
memcpy(pkeptr +23, zeiger->ap, 6);
memcpy(pkeptr +29, zeiger->client, 6);
}
else
{
memcpy(pkeptr +23, zeiger->client, 6);
memcpy(pkeptr +29, zeiger->ap, 6);
}
if(memcmp(zeiger->nonce, wpak->nonce, 32) < 0)
{
memcpy (pkeptr +35, zeiger->nonce, 32);
memcpy (pkeptr +67, wpak->nonce, 32);
}
else
{
memcpy (pkeptr +35, wpak->nonce, 32);
memcpy (pkeptr +67, zeiger->nonce, 32);
}
if(!EVP_MAC_init(ctxhmac, pmk, 32, paramssha1)) return;
if(!EVP_MAC_update(ctxhmac, pkedata, 100)) return;
if(!EVP_MAC_final(ctxhmac, pkedata, NULL, 100)) return;
fprintf(stdout, "\n");
if(keyver == 2)
{
memset(eapoltmp, 0, 1024);
memcpy(eapoltmp, zeiger->eapol, zeiger->eapauthlen);
if(!EVP_MAC_init(ctxhmac, pkedata, 16, paramssha1)) return;
if(!EVP_MAC_update(ctxhmac, eapoltmp, zeiger->eapauthlen)) return;
if(!EVP_MAC_final(ctxhmac, eapoltmp, NULL, zeiger->eapauthlen)) return;
}
if(keyver == 1)
{
memset(eapoltmp, 0, 1024);
memcpy(eapoltmp, zeiger->eapol, zeiger->eapauthlen);
if(!EVP_MAC_init(ctxhmac, pkedata, 16, paramsmd5)) return;
if(!EVP_MAC_update(ctxhmac, eapoltmp, zeiger->eapauthlen)) return;
if(!EVP_MAC_final(ctxhmac, eapoltmp, NULL, zeiger->eapauthlen)) return;
}
}
else if(keyver == 3)
{
memset(&pkedata, 0, sizeof(pkedata));
pkedata[0] = 1;
pkedata[1] = 0;
pkeptr = pkedata +2;
memcpy(pkeptr, "Pairwise key expansion", 22);
if(memcmp(zeiger->ap, zeiger->client, 6) < 0)
{
memcpy(pkeptr +22, zeiger->ap, 6);
memcpy(pkeptr +28, zeiger->client, 6);
}
else
{
memcpy(pkeptr +22, zeiger->client, 6);
memcpy(pkeptr +28, zeiger->ap, 6);
}
if(memcmp(zeiger->nonce, wpak->nonce, 32) < 0)
{
memcpy (pkeptr +34, zeiger->nonce, 32);
memcpy (pkeptr +66, wpak->nonce, 32);
}
else
{
memcpy (pkeptr +34, wpak->nonce, 32);
memcpy (pkeptr +66, zeiger->nonce, 32);
}
pkedata[100] = 0x80;
pkedata[101] = 1;
if(!EVP_MAC_init(ctxhmac, pmk, 32, paramssha256)) return;
if(!EVP_MAC_update(ctxhmac, pkedata, 102)) return;
if(!EVP_MAC_final(ctxhmac, pkedata, NULL, 102)) return;
memset(eapoltmp, 0, 1024);
memcpy(eapoltmp, zeiger->eapol, zeiger->eapauthlen);
if(!EVP_MAC_init(ctxcmac, pkedata, 16, paramsaes128)) return;
if(!EVP_MAC_update(ctxcmac, eapoltmp, zeiger->eapauthlen)) return;
if(!EVP_MAC_final(ctxcmac, eapoltmp, NULL, zeiger->eapauthlen)) return;
}
else return;
if(memcmp(eapoltmp, zeiger->hash, 16) == 0)
{
for(p = 0; p < 6; p++) fprintf(stdout, "%02x", zeiger->client[p]);
fprintf(stdout, ":");
for(p = 0; p < 6; p++) fprintf(stdout, "%02x", zeiger->ap[p]);
if(zeiger->essidlen != 0)
{
if(ispotfilestring(zeiger->essidlen, (char*)zeiger->essid) == true)
fprintf(stdout, ":%.*s", zeiger->essidlen, zeiger->essid);
else
{
fprintf(stdout, ":$HEX[");
for(p = 0; p < zeiger->essidlen; p++) fprintf(stdout, "%02x",
zeiger->essid[p]);
fprintf(stdout, "]");
}
}
else fprintf(stdout, ":");
fprintf(stdout, ":%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x
%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
pmk[0], pmk[1], pmk[2], pmk[3], pmk[4], pmk[5], pmk[6], pmk[7],
pmk[8], pmk[9], pmk[10], pmk[11], pmk[12], pmk[13], pmk[14], pmk[15],
pmk[16], pmk[17], pmk[18], pmk[19], pmk[20], pmk[21], pmk[22], pmk[23],
pmk[24], pmk[25], pmk[26], pmk[27], pmk[28], pmk[29], pmk[30],
pmk[31]);
if(pskptr != NULL)
{
if(ispotfilestring(pskptrlen, pskptr) == true) fprintf(stdout, ":%s",
pskptr);
else
{
fprintf(stdout, ":$HEX[");
for(p = 0; p < pskptrlen; p++) fprintf(stdout, "%02x",
pskptr[p]);
fprintf(stdout, "]");
}
}
fprintf(stdout, "\n");
}
return;
}
/*===========================================================================*/
static void testpmkidpmk(hashlist_t *zeiger)
{
static int p;
static const char *pmkname = "PMK Name";
static uint8_t message[20];

memcpy(message, pmkname, 8);


memcpy(&message[8], zeiger->ap, 6);
memcpy(&message[14], zeiger->client, 6);
if(!EVP_MAC_init(ctxhmac, pmk, 32, paramssha1)) return;
if(!EVP_MAC_update(ctxhmac, message, 20)) return;
if(!EVP_MAC_final(ctxhmac, message, NULL, 20)) return;
if(memcmp(message, zeiger->hash, 16) == 0)
{
for(p = 0; p < 6; p++) fprintf(stdout, "%02x", zeiger->client[p]);
fprintf(stdout, ":");
for(p = 0; p < 6; p++) fprintf(stdout, "%02x", zeiger->ap[p]);
if(zeiger->essidlen != 0)
{
if(ispotfilestring(zeiger->essidlen, (char*)zeiger->essid) == true)
fprintf(stdout, ":%.*s", zeiger->essidlen, zeiger->essid);
else
{
fprintf(stdout, ":$HEX[");
for(p = 0; p < zeiger->essidlen; p++) fprintf(stdout, "%02x",
zeiger->essid[p]);
fprintf(stdout, "]");
}
}
else fprintf(stdout, ":");
fprintf(stdout, ":%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x
%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
pmk[0], pmk[1], pmk[2], pmk[3], pmk[4], pmk[5], pmk[6], pmk[7],
pmk[8], pmk[9], pmk[10], pmk[11], pmk[12], pmk[13], pmk[14], pmk[15],
pmk[16], pmk[17], pmk[18], pmk[19], pmk[20], pmk[21], pmk[22], pmk[23],
pmk[24], pmk[25], pmk[26], pmk[27], pmk[28], pmk[29], pmk[30],
pmk[31]);
if(pskptr != NULL)
{
if(ispotfilestring(pskptrlen, pskptr) == true) fprintf(stdout, ":%s",
pskptr);
else
{
fprintf(stdout, ":$HEX[");
for(p = 0; p < pskptrlen; p++) fprintf(stdout, "%02x",
pskptr[p]);
fprintf(stdout, "]");
}
}
fprintf(stdout, "\n");
}
return;
}
/*===========================================================================*/
static void testhashfilepmk(void)
{
static hashlist_t *zeiger;

for(zeiger = hashlist; zeiger < hashlist +pmkideapolcount; zeiger++)


{
if(zeiger->type == HCX_TYPE_PMKID) testpmkidpmk(zeiger);
else if (zeiger->type == HCX_TYPE_EAPOL) testeapolpmk(zeiger);
}
return;
}
/*===========================================================================*/
static bool dopbkdf2(int psklen, char *psk, int essidlen, uint8_t *essid)
{
if(PKCS5_PBKDF2_HMAC_SHA1(psk, psklen, essid, essidlen, 4096, 32, pmk) == 0) return
false;
return true;
}
/*===========================================================================*/
static void testhashfilepsk(void)
{
static hashlist_t *zeiger, *zeigerold;

zeigerold = hashlist;
if(dopbkdf2(pskptrlen, pskptr, zeigerold->essidlen, zeigerold->essid) == true)
{
if(zeigerold->type == HCX_TYPE_PMKID) testpmkidpmk(zeigerold);
if(zeigerold->type == HCX_TYPE_EAPOL) testeapolpmk(zeigerold);
}
for(zeiger = hashlist +1; zeiger < hashlist +pmkideapolcount; zeiger++)
{
if((zeigerold->essidlen == zeiger->essidlen) && (memcmp(zeigerold->essid,
zeiger->essid, zeigerold->essidlen) == 0))
{
if(zeiger->type == HCX_TYPE_PMKID) testpmkidpmk(zeiger);
if(zeiger->type == HCX_TYPE_EAPOL) testeapolpmk(zeiger);
}
else
{
if(dopbkdf2(pskptrlen, pskptr, zeiger->essidlen, zeiger->essid) ==
true)
{
if(zeiger->type == HCX_TYPE_PMKID) testpmkidpmk(zeiger);
if(zeiger->type == HCX_TYPE_EAPOL) testeapolpmk(zeiger);
}
}
zeigerold = zeiger;
}
return;
}
/*===========================================================================*/
static bool isoui(uint8_t *macap, uint8_t *macclient)
{
static ouilist_t *zeiger;

for(zeiger = ouilist; zeiger < ouilist +ouicount; zeiger++)


{
if(((zeiger->type &TYPE_AP) == TYPE_AP) && (memcmp(macap, zeiger->oui, 3) ==
0)) return true;
if(((zeiger->type &TYPE_CLIENT) == TYPE_CLIENT) && (memcmp(macclient, zeiger-
>oui, 3) == 0)) return true;
}
return false;
}
/*===========================================================================*/
static bool ispartof(int plen, uint8_t *pbuff, int slen, uint8_t *sbuff)
{
static int p;
static uint8_t buffers[32];
static uint8_t bufferp[32];

if(plen > slen) return false;


if(caseflag == false)
{
for(p = 0; p <= slen -plen; p++)
{
if(memcmp(&sbuff[p], pbuff, plen) == 0) return true;
}
return false;
}
else
{
memset(buffers, 0, 32);
for(p = 0; p < slen; p++)
{
if(isupper(sbuff[p])) buffers[p] = tolower(sbuff[p]);
else buffers[p] = sbuff[p];
}
memset(bufferp, 0, 32);
for(p = 0; p < plen; p++)
{
if(isupper(pbuff[p])) bufferp[p] = tolower(pbuff[p]);
else bufferp[p] = pbuff[p];
}
for(p = 0; p <= slen -plen; p++)
{
if(memcmp(&buffers[p], bufferp, plen) == 0) return true;
}
return false;
}
return false;
}
/*===========================================================================*/
static void hccap2base(unsigned char *in, unsigned char b, FILE *fh_john)
{
static const char itoa64[65] =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

fprintf(fh_john, "%c", (itoa64[in[0] >> 2]));


fprintf(fh_john, "%c", (itoa64[((in[0] & 0x03) << 4) | (in[1] >> 4)]));
if(b)
{
fprintf(fh_john, "%c", (itoa64[((in[1] & 0x0f) << 2) | (in[2] >> 6)]));
fprintf(fh_john, "%c", (itoa64[in[2] & 0x3f]));
}
else fprintf(fh_john, "%c", (itoa64[((in[1] & 0x0f) << 2)]));
return;
}
/*===========================================================================*/
static void writejohnrecord(FILE *fh_john, hashlist_t *zeiger)
{
struct hccap_s
{
char essid[36];
unsigned char ap[6];
unsigned char client[6];
unsigned char snonce[32];
unsigned char anonce[32];
unsigned char eapol[256];
int eapol_size;
int keyver;
unsigned char keymic[16];
};
typedef struct hccap_s hccap_t;
#define HCCAP_SIZE (sizeof(hccap_t))

static wpakey_t *wpak;


static int i;
static unsigned char *hcpos;
static hccap_t hccap;

if((zeiger->essidlen < essidlenmin) || (zeiger->essidlen > essidlenmax)) return;


if(((zeiger->type &hashtype) != HCX_TYPE_PMKID) && ((zeiger->type &hashtype) !=
HCX_TYPE_EAPOL)) return;
if(flagfiltermacap == true) if(memcmp(&filtermacap, zeiger->ap, 6) != 0) return;
if(flagfiltermacclient == true) if(memcmp(&filtermacclient, zeiger->client, 6) !=
0) return;
if(flagfilterouiap == true) if(memcmp(&filterouiap, zeiger->ap, 3) != 0) return;
if(flagfilterouiclient == true) if(memcmp(&filterouiclient, zeiger->client, 3) !=
0) return;
if(filteressidptr != NULL)
{
if(zeiger->essidlen != filteressidlen) return;
if(memcmp(zeiger->essid, filteressidptr, zeiger->essidlen) != 0) return;
}
if(filteressidpartptr != NULL)
{
if(ispartof(filteressidpartlen, (uint8_t*)filteressidpartptr, zeiger-
>essidlen, zeiger->essid) == false) return;
}
if((filtervendorptr != NULL) || (filtervendorapptr != NULL) ||
(filtervendorclientptr != NULL))
{
if(isoui(zeiger->ap, zeiger->client) == false) return;
}
if((flagfilterapless == true) && ((zeiger->mp &0x10) != 0x10)) return;
if((flagfilterrcchecked == true) && ((zeiger->mp &0x80) == 0x80)) return;
if((flagfilterrcnotchecked == true) && ((zeiger->mp &0x80) != 0x80)) return;
if((flagfilterauthorized == true) && ((zeiger->mp &0x07) == 0x00)) return;
if((flagfilterchallenge == true) && ((zeiger->mp &0x07) != 0x01)) return;

if(zeiger->type == HCX_TYPE_PMKID)
{
fprintf(fh_john, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x
%02x%02x*%02x%02x%02x%02x%02x%02x*%02x%02x%02x%02x%02x%02x*",
zeiger->hash[0], zeiger->hash[1], zeiger->hash[2], zeiger->hash[3],
zeiger->hash[4], zeiger->hash[5], zeiger->hash[6], zeiger->hash[7],
zeiger->hash[8], zeiger->hash[9], zeiger->hash[10], zeiger->hash[11],
zeiger->hash[12], zeiger->hash[13], zeiger->hash[14], zeiger->hash[15],
zeiger->ap[0], zeiger->ap[1], zeiger->ap[2], zeiger->ap[3], zeiger-
>ap[4], zeiger->ap[5],
zeiger->client[0], zeiger->client[1], zeiger->client[2], zeiger-
>client[3], zeiger->client[4], zeiger->client[5]);
for(i = 0; i < zeiger->essidlen; i++) fprintf(fh_john, "%02x", zeiger-
>essid[i]);
fprintf(fh_john, "\n");
johnpmkidwrittencount++;
return;
}
wpak = (wpakey_t*)(zeiger->eapol +EAPAUTH_SIZE);
memset(&hccap, 0, sizeof(hccap_t));
memcpy(&hccap.essid, zeiger->essid, zeiger->essidlen);
memcpy(&hccap.ap, zeiger->ap, 6);
memcpy(&hccap.client, zeiger->client, 6);
memcpy(&hccap.anonce, zeiger->nonce, 32);
memcpy(&hccap.snonce, wpak->nonce, 32);
memcpy(&hccap.keymic, zeiger->hash, 16);
hccap.keyver = ntohs(wpak->keyinfo) & WPA_KEY_INFO_TYPE_MASK;
hccap.eapol_size = zeiger->eapauthlen;
memcpy(&hccap.eapol, zeiger->eapol, zeiger->eapauthlen);
#ifdef BIG_ENDIAN_HOST
hccap.eapol_size = byte_swap_16(hccap.eapol_size);
#endif

fprintf(fh_john, "%.*s:$WPAPSK$%.*s#", zeiger->essidlen, zeiger->essid, zeiger-


>essidlen, zeiger->essid);
hcpos = (unsigned char*)&hccap;
for (i = 36; i + 3 < (int)HCCAP_SIZE; i += 3) hccap2base(&hcpos[i], 1, fh_john);
hccap2base(&hcpos[i], 0, fh_john);
fprintf(fh_john, ":%02x-%02x-%02x-%02x-%02x-%02x:%02x-%02x-%02x-%02x-%02x-%02x:%02x
%02x%02x%02x%02x%02x",
zeiger->client[0], zeiger->client[1], zeiger->client[2], zeiger->client[3], zeiger-
>client[4], zeiger->client[5],
zeiger->ap[0], zeiger->ap[1], zeiger->ap[2], zeiger->ap[3], zeiger->ap[4], zeiger-
>ap[5],
zeiger->ap[0], zeiger->ap[1], zeiger->ap[2], zeiger->ap[3], zeiger->ap[4], zeiger-
>ap[5]);
if(hccap.keyver == 1) fprintf(fh_john, "::WPA");
else fprintf(fh_john, "::WPA2");
if((zeiger->mp &0x7) == 0) fprintf(fh_john, ":not verified");
else fprintf(fh_john, ":verified");
fprintf(fh_john, ":converted by hcxhastool\n");
johneapolwrittencount++;
return;
}
/*===========================================================================*/
static void writejohnfile(char *johnoutname)
{
static FILE *fh_john;
static hashlist_t *zeiger;
static struct stat statinfo;

if(johnoutname != NULL)
{
if((fh_john = fopen(johnoutname, "a")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", johnoutname,
strerror(errno));
return;
}
}
for(zeiger = hashlist; zeiger < hashlist +pmkideapolcount; zeiger++)
writejohnrecord(fh_john, zeiger);
if(fh_john != NULL) fclose(fh_john);
if(johnoutname != NULL)
{
if(stat(johnoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(johnoutname);
}
}
return;
}
/*===========================================================================*/
static void writehccaprecord(FILE *fh_hccap, hashlist_t *zeiger)
{
struct hccap_s
{
char essid[36];
unsigned char ap[6];
unsigned char client[6];
unsigned char snonce[32];
unsigned char anonce[32];
unsigned char eapol[256];
int eapol_size;
int keyver;
unsigned char keymic[16];
};
typedef struct hccap_s hccap_t;
#define HCCAP_SIZE (sizeof(hccap_t))

static wpakey_t *wpak;


static hccap_t hccap;

if(zeiger->type == HCX_TYPE_PMKID) return;


if((zeiger->essidlen < essidlenmin) || (zeiger->essidlen > essidlenmax)) return;
if(((zeiger->type &hashtype) != HCX_TYPE_PMKID) && ((zeiger->type &hashtype) !=
HCX_TYPE_EAPOL)) return;
if(flagfiltermacap == true) if(memcmp(&filtermacap, zeiger->ap, 6) != 0) return;
if(flagfiltermacclient == true) if(memcmp(&filtermacclient, zeiger->client, 6) !=
0) return;
if(flagfilterouiap == true) if(memcmp(&filterouiap, zeiger->ap, 3) != 0) return;
if(flagfilterouiclient == true) if(memcmp(&filterouiclient, zeiger->client, 3) !=
0) return;
if(filteressidptr != NULL)
{
if(zeiger->essidlen != filteressidlen) return;
if(memcmp(zeiger->essid, filteressidptr, zeiger->essidlen) != 0) return;
}
if(filteressidpartptr != NULL)
{
if(ispartof(filteressidpartlen, (uint8_t*)filteressidpartptr, zeiger-
>essidlen, zeiger->essid) == false) return;
}
if((filtervendorptr != NULL) || (filtervendorapptr != NULL) ||
(filtervendorclientptr != NULL))
{
if(isoui(zeiger->ap, zeiger->client) == false) return;
}
if((flagfilterapless == true) && ((zeiger->mp &0x10) != 0x10)) return;
if((flagfilterrcchecked == true) && ((zeiger->mp &0x80) == 0x80)) return;
if((flagfilterrcnotchecked == true) && ((zeiger->mp &0x80) != 0x80)) return;
if((flagfilterauthorized == true) && ((zeiger->mp &0x07) == 0x00)) return;
if((flagfilterchallenge == true) && ((zeiger->mp &0x07) != 0x01)) return;

wpak = (wpakey_t*)(zeiger->eapol +EAPAUTH_SIZE);


memset(&hccap, 0, sizeof(hccap_t));
memcpy(&hccap.essid, zeiger->essid, zeiger->essidlen);
memcpy(&hccap.ap, zeiger->ap, 6);
memcpy(&hccap.client, zeiger->client, 6);
memcpy(&hccap.anonce, zeiger->nonce, 32);
memcpy(&hccap.snonce, wpak->nonce, 32);
memcpy(&hccap.keymic, zeiger->hash, 16);
hccap.keyver = ntohs(wpak->keyinfo) & WPA_KEY_INFO_TYPE_MASK;
hccap.eapol_size = zeiger->eapauthlen;
memcpy(&hccap.eapol, zeiger->eapol, zeiger->eapauthlen);
#ifdef BIG_ENDIAN_HOST
hccap.eapol_size = byte_swap_16(hccap.eapol_size);
#endif
fwrite(&hccap, HCCAP_SIZE, 1, fh_hccap);
hccapwrittencount++;
return;
}
/*===========================================================================*/
static void writehccapsinglefile(void)
{
static int c;
static FILE *fh_hccap;
static hashlist_t *zeiger;
static struct stat statinfo;
static char groupoutname[PATH_MAX];

for(zeiger = hashlist; zeiger < hashlist +pmkideapolcount; zeiger++)


{
c = 0;
do
{
snprintf(groupoutname, PATH_MAX -1, "%02x%02x%02x%02x%02x%02x-
%04d.hccap", zeiger->ap[0], zeiger->ap[1], zeiger->ap[2], zeiger->ap[3], zeiger-
>ap[4], zeiger->ap[5], c);
c++;
}
while (stat(groupoutname, &statinfo) == 0);
if((fh_hccap = fopen(groupoutname, "a")) == NULL) continue;
writehccaprecord(fh_hccap, zeiger);
if(fh_hccap != NULL) fclose(fh_hccap);
if(stat(groupoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(groupoutname);
}
}
return;
}
/*===========================================================================*/
static void writehccapfile(char *hccapoutname)
{
static FILE *fh_hccap;
static hashlist_t *zeiger;
static struct stat statinfo;

if(hccapoutname != NULL)
{
if((fh_hccap = fopen(hccapoutname, "a")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", hccapoutname,
strerror(errno));
return;
}
}
for(zeiger = hashlist; zeiger < hashlist +pmkideapolcount; zeiger++)
writehccaprecord(fh_hccap, zeiger);
if(fh_hccap != NULL) fclose(fh_hccap);
if(hccapoutname != NULL)
{
if(stat(hccapoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(hccapoutname);
}
}
return;
}
/*===========================================================================*/
static void writehccapxrecord(FILE *fh_hccapx, hashlist_t *zeiger)
{
struct hccapx_s
{
uint32_t signature;
#define HCCAPX_SIGNATURE 0x58504348
uint32_t version;
#define HCCAPX_VERSION 4
uint8_t message_pair;
uint8_t essid_len;
uint8_t essid[32];
uint8_t keyver;
uint8_t keymic[16];
uint8_t ap[6];
uint8_t anonce[32];
uint8_t client[6];
uint8_t snonce[32];
uint16_t eapol_len;
uint8_t eapol[256];
} __attribute__((packed));
typedef struct hccapx_s hccapx_t;
#define HCCAPX_SIZE (sizeof(hccapx_t))

static wpakey_t *wpak;


static hccapx_t hccapx;

if(zeiger->type == HCX_TYPE_PMKID) return;


if((zeiger->essidlen < essidlenmin) || (zeiger->essidlen > essidlenmax)) return;
if(((zeiger->type &hashtype) != HCX_TYPE_PMKID) && ((zeiger->type &hashtype) !=
HCX_TYPE_EAPOL)) return;
if(flagfiltermacap == true) if(memcmp(&filtermacap, zeiger->ap, 6) != 0) return;
if(flagfiltermacclient == true) if(memcmp(&filtermacclient, zeiger->client, 6) !=
0) return;
if(flagfilterouiap == true) if(memcmp(&filterouiap, zeiger->ap, 3) != 0) return;
if(flagfilterouiclient == true) if(memcmp(&filterouiclient, zeiger->client, 3) !=
0) return;
if(filteressidptr != NULL)
{
if(zeiger->essidlen != filteressidlen) return;
if(memcmp(zeiger->essid, filteressidptr, zeiger->essidlen) != 0) return;
}
if(filteressidpartptr != NULL)
{
if(ispartof(filteressidpartlen, (uint8_t*)filteressidpartptr, zeiger-
>essidlen, zeiger->essid) == false) return;
}
if((filtervendorptr != NULL) || (filtervendorapptr != NULL) ||
(filtervendorclientptr != NULL))
{
if(isoui(zeiger->ap, zeiger->client) == false) return;
}
if((flagfilterapless == true) && ((zeiger->mp &0x10) != 0x10)) return;
if((flagfilterrcchecked == true) && ((zeiger->mp &0x80) == 0x80)) return;
if((flagfilterrcnotchecked == true) && ((zeiger->mp &0x80) != 0x80)) return;
if((flagfilterauthorized == true) && ((zeiger->mp &0x07) == 0x00)) return;
if((flagfilterchallenge == true) && ((zeiger->mp &0x07) != 0x01)) return;

wpak = (wpakey_t*)(zeiger->eapol +EAPAUTH_SIZE);


memset (&hccapx, 0, sizeof(hccapx_t));
hccapx.signature = HCCAPX_SIGNATURE;
hccapx.version = HCCAPX_VERSION;
hccapx.message_pair = zeiger->mp;
hccapx.essid_len = zeiger->essidlen;
memcpy(&hccapx.essid, zeiger->essid, zeiger->essidlen);
memcpy(&hccapx.ap, zeiger->ap, 6);
memcpy(&hccapx.client, zeiger->client, 6);
memcpy(&hccapx.anonce, zeiger->nonce, 32);
memcpy(&hccapx.snonce, wpak->nonce, 32);
hccapx.eapol_len = zeiger->eapauthlen;
memcpy(&hccapx.eapol, zeiger->eapol, zeiger->eapauthlen);
hccapx.keyver = ntohs(wpak->keyinfo) & WPA_KEY_INFO_TYPE_MASK;
memcpy(&hccapx.keymic, zeiger->hash, 16);
#ifdef BIG_ENDIAN_HOST
hccapx.signature = byte_swap_32(hccapx.signature);
hccapx.version = byte_swap_32(hccapx.version);
hccapx.eapol_len = byte_swap_16(hccapx.eapol_len);
#endif
fwrite (&hccapx, sizeof(hccapx_t), 1, fh_hccapx);
hccapxwrittencount++;
return;
}
/*===========================================================================*/
static void writehccapxfile(char *hccapxoutname)
{
static FILE *fh_hccapx;
static hashlist_t *zeiger;
static struct stat statinfo;

if(hccapxoutname != NULL)
{
if((fh_hccapx = fopen(hccapxoutname, "a")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", hccapxoutname,
strerror(errno));
return;
}
}
for(zeiger = hashlist; zeiger < hashlist +pmkideapolcount; zeiger++)
writehccapxrecord(fh_hccapx, zeiger);
if(fh_hccapx != NULL) fclose(fh_hccapx);
if(hccapxoutname != NULL)
{
if(stat(hccapxoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(hccapxoutname);
}
}
return;
}
/*===========================================================================*/
static void processessidraw(char *essidrawoutname)
{
static long int pc;
static hashlist_t *zeiger;
static FILE *fh_essid;
static struct stat statinfo;

if((fh_essid = fopen(essidrawoutname, "a")) == NULL)


{
fprintf(stdout, "error opening file %s: %s\n", essidrawoutname,
strerror(errno));
return;
}
for(pc = 0; pc < pmkideapolcount; pc++)
{
zeiger = hashlist +pc;
fwriteessidstr(zeiger->essidlen, zeiger->essid, fh_essid);
essidrawwrittencount++;
}
fclose(fh_essid);
if(stat(essidrawoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(essidrawoutname);
}
return;
}
/*===========================================================================*/
static void processessid(char *essidoutname)
{
static long int pc;
static hashlist_t *zeiger, *zeigerold;
static FILE *fh_essid;
static struct stat statinfo;

if(strcmp(essidoutname, "stdout") != 0)
{
if((fh_essid = fopen(essidoutname, "a")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", essidoutname,
strerror(errno));
return;
}
zeigerold = NULL;
qsort(hashlist, pmkideapolcount, HASHLIST_SIZE, sort_hashlist_by_essid);
for(pc = 0; pc < pmkideapolcount; pc++)
{
zeiger = hashlist +pc;
if(zeigerold != NULL)
{
if(memcmp(zeiger->essid, zeigerold->essid, ESSID_LEN_MAX) == 0)
continue;
}
fwriteessidstr(zeiger->essidlen, zeiger->essid, fh_essid);
essidwrittencount++;
zeigerold = zeiger;
}
fclose(fh_essid);
if(stat(essidoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(essidoutname);
}
}
else
{
statusflag = false;
zeigerold = NULL;
qsort(hashlist, pmkideapolcount, HASHLIST_SIZE, sort_hashlist_by_essid);
for(pc = 0; pc < pmkideapolcount; pc++)
{
zeiger = hashlist +pc;
if(zeigerold != NULL)
{
if(memcmp(zeiger->essid, zeigerold->essid, ESSID_LEN_MAX) == 0)
continue;
}
fwriteessidstr(zeiger->essidlen, zeiger->essid, stdout);
essidwrittencount++;
zeigerold = zeiger;
}
}
return;
}
/*===========================================================================*/
static void writepmkideapolhashline(FILE *fh_pmkideapol, hashlist_t *zeiger)
{
static int p;

if((zeiger->essidlen < essidlenmin) || (zeiger->essidlen > essidlenmax)) return;


if(((zeiger->type &hashtype) != HCX_TYPE_PMKID) && ((zeiger->type &hashtype) !=
HCX_TYPE_EAPOL)) return;
if(flagfiltermacap == true) if(memcmp(&filtermacap, zeiger->ap, 6) != 0) return;
if(flagfiltermacclient == true) if(memcmp(&filtermacclient, zeiger->client, 6) !=
0) return;
if(flagfilterouiap == true) if(memcmp(&filterouiap, zeiger->ap, 3) != 0) return;
if(flagfilterouiclient == true) if(memcmp(&filterouiclient, zeiger->client, 3) !=
0) return;
if(filteressidptr != NULL)
{
if(zeiger->essidlen != filteressidlen) return;
if(memcmp(zeiger->essid, filteressidptr, zeiger->essidlen) != 0) return;
}
if(filteressidpartptr != NULL)
{
if(ispartof(filteressidpartlen, (uint8_t*)filteressidpartptr, zeiger-
>essidlen, zeiger->essid) == false) return;
}
if((filtervendorptr != NULL) || (filtervendorapptr != NULL) ||
(filtervendorclientptr != NULL))
{
if(isoui(zeiger->ap, zeiger->client) == false) return;
}
if((flagfilterapless == true) && ((zeiger->mp &0x10) != 0x10)) return;
if((flagfilterrcchecked == true) && ((zeiger->mp &0x80) == 0x80)) return;
if((flagfilterrcnotchecked == true) && ((zeiger->mp &0x80) != 0x80)) return;
if((flagfilterauthorized == true) && ((zeiger->mp &0x07) == 0x00)) return;
if((flagfilterchallenge == true) && ((zeiger->mp &0x07) != 0x01)) return;
if(zeiger->type == HCX_TYPE_PMKID)
{
fprintf(fh_pmkideapol, "WPA*%02d*%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x
%02x%02x%02x%02x%02x*%02x%02x%02x%02x%02x%02x*%02x%02x%02x%02x%02x%02x*",
zeiger->type,
zeiger->hash[0], zeiger->hash[1], zeiger->hash[2], zeiger->hash[3],
zeiger->hash[4], zeiger->hash[5], zeiger->hash[6], zeiger->hash[7],
zeiger->hash[8], zeiger->hash[9], zeiger->hash[10], zeiger->hash[11],
zeiger->hash[12], zeiger->hash[13], zeiger->hash[14], zeiger->hash[15],
zeiger->ap[0], zeiger->ap[1], zeiger->ap[2], zeiger->ap[3], zeiger-
>ap[4], zeiger->ap[5],
zeiger->client[0], zeiger->client[1], zeiger->client[2], zeiger-
>client[3], zeiger->client[4], zeiger->client[5]);
for(p = 0; p < zeiger->essidlen; p++) fprintf(fh_pmkideapol, "%02x", zeiger-
>essid[p]);
fprintf(fh_pmkideapol, "***\n");
pmkidwrittencount++;
return;
}
if(zeiger->type == HCX_TYPE_EAPOL)
{
fprintf(fh_pmkideapol, "WPA*%02d*%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x
%02x%02x%02x%02x%02x*%02x%02x%02x%02x%02x%02x*%02x%02x%02x%02x%02x%02x*",
zeiger->type,
zeiger->hash[0], zeiger->hash[1], zeiger->hash[2], zeiger->hash[3],
zeiger->hash[4], zeiger->hash[5], zeiger->hash[6], zeiger->hash[7],
zeiger->hash[8], zeiger->hash[9], zeiger->hash[10], zeiger->hash[11],
zeiger->hash[12], zeiger->hash[13], zeiger->hash[14], zeiger->hash[15],
zeiger->ap[0], zeiger->ap[1], zeiger->ap[2], zeiger->ap[3], zeiger-
>ap[4], zeiger->ap[5],
zeiger->client[0], zeiger->client[1], zeiger->client[2], zeiger-
>client[3], zeiger->client[4], zeiger->client[5]);
for(p = 0; p < zeiger->essidlen; p++) fprintf(fh_pmkideapol, "%02x", zeiger-
>essid[p]);
fprintf(fh_pmkideapol, "*");
fprintf(fh_pmkideapol, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x
%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x*",
zeiger->nonce[0], zeiger->nonce[1], zeiger->nonce[2], zeiger->nonce[3],
zeiger->nonce[4], zeiger->nonce[5], zeiger->nonce[6], zeiger->nonce[7],
zeiger->nonce[8], zeiger->nonce[9], zeiger->nonce[10], zeiger-
>nonce[11], zeiger->nonce[12], zeiger->nonce[13], zeiger->nonce[14], zeiger-
>nonce[15],
zeiger->nonce[16], zeiger->nonce[17], zeiger->nonce[18], zeiger-
>nonce[19], zeiger->nonce[20], zeiger->nonce[21], zeiger->nonce[22], zeiger-
>nonce[23],
zeiger->nonce[24], zeiger->nonce[25], zeiger->nonce[26], zeiger-
>nonce[27], zeiger->nonce[28], zeiger->nonce[29], zeiger->nonce[30], zeiger-
>nonce[31]);
for(p = 0; p < zeiger->eapauthlen; p++) fprintf(fh_pmkideapol, "%02x",
zeiger->eapol[p]);
fprintf(fh_pmkideapol, "*%02x\n", zeiger->mp);
eapolwrittencount++;
}
return;
}
/*===========================================================================*/
static void writeeapolpmkidessidgroups(void)
{
static int cei;
static int ceo;
static hashlist_t *zeiger;
static FILE *fh_pmkideapol;
static struct stat statinfo;
static const char digit[16] =
{'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};

static char groupoutname[PATH_MAX];

qsort(hashlist, pmkideapolcount, HASHLIST_SIZE, sort_hashlist_by_essid);


for(zeiger = hashlist; zeiger < hashlist +pmkideapolcount; zeiger++)
{
groupoutname[0] = 0;
if((zeiger->essidlen < essidlenmin) || (zeiger->essidlen > essidlenmax))
continue;
if(((zeiger->type &hashtype) != HCX_TYPE_PMKID) && ((zeiger->type
&hashtype) != HCX_TYPE_EAPOL)) continue;
ceo = 0;
for (cei = 0; cei < zeiger->essidlen; cei++)
{
groupoutname[ceo] = digit[(zeiger->essid[cei] & 0xff) >> 4];
ceo++;
groupoutname[ceo] = digit[zeiger->essid[cei] & 0x0f];
ceo++;
}
groupoutname[ceo] = 0;
strcat(&groupoutname[ceo], ".22000");
if((fh_pmkideapol = fopen(groupoutname, "a")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", groupoutname,
strerror(errno));
return;
}
writepmkideapolhashline(fh_pmkideapol, zeiger);
if(fh_pmkideapol != NULL) fclose(fh_pmkideapol);
if(groupoutname[0] != 0)
{
if(stat(groupoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(groupoutname);
}
}
}
return;
}
/*===========================================================================*/
static void writeeapolpmkidouigroups(void)
{
static hashlist_t *zeiger;
static FILE *fh_pmkideapol;
static struct stat statinfo;
static char groupoutname[PATH_MAX];

qsort(hashlist, pmkideapolcount, HASHLIST_SIZE, sort_hashlist_by_essid);


for(zeiger = hashlist; zeiger < hashlist +pmkideapolcount; zeiger++)
{
snprintf(groupoutname, PATH_MAX -1, "%02x%02x%02x.22000", zeiger->ap[0],
zeiger->ap[1], zeiger->ap[2]);
if((fh_pmkideapol = fopen(groupoutname, "a")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", groupoutname,
strerror(errno));
return;
}
writepmkideapolhashline(fh_pmkideapol, zeiger);
if(fh_pmkideapol != NULL) fclose(fh_pmkideapol);
if(groupoutname[0] != 0)
{
if(stat(groupoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(groupoutname);
}
}
}
return;
}
/*===========================================================================*/
static void writeeapolpmkidmacapgroups(void)
{
static hashlist_t *zeiger;
static FILE *fh_pmkideapol;
static struct stat statinfo;
static char groupoutname[PATH_MAX];

qsort(hashlist, pmkideapolcount, HASHLIST_SIZE, sort_hashlist_by_essid);


for(zeiger = hashlist; zeiger < hashlist +pmkideapolcount; zeiger++)
{
snprintf(groupoutname, PATH_MAX -1, "%02x%02x%02x%02x%02x%02x.22000", zeiger-
>ap[0], zeiger->ap[1], zeiger->ap[2], zeiger->ap[3], zeiger->ap[4], zeiger->ap[5]);
if((fh_pmkideapol = fopen(groupoutname, "a")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", groupoutname,
strerror(errno));
return;
}
writepmkideapolhashline(fh_pmkideapol, zeiger);
if(fh_pmkideapol != NULL) fclose(fh_pmkideapol);
if(groupoutname[0] != 0)
{
if(stat(groupoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(groupoutname);
}
}
}
return;
}
/*===========================================================================*/
static void writeeapolpmkidmacclientgroups(void)
{
static hashlist_t *zeiger;
static FILE *fh_pmkideapol;
static struct stat statinfo;
static char groupoutname[PATH_MAX];

qsort(hashlist, pmkideapolcount, HASHLIST_SIZE, sort_hashlist_by_essid);


for(zeiger = hashlist; zeiger < hashlist +pmkideapolcount; zeiger++)
{
snprintf(groupoutname, PATH_MAX -1, "%02x%02x%02x%02x%02x%02x.22000", zeiger-
>client[0], zeiger->client[1], zeiger->client[2], zeiger->client[3], zeiger-
>client[4], zeiger->client[5]);
if((fh_pmkideapol = fopen(groupoutname, "a")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", groupoutname,
strerror(errno));
return;
}
writepmkideapolhashline(fh_pmkideapol, zeiger);
if(fh_pmkideapol != NULL) fclose(fh_pmkideapol);
if(groupoutname[0] != 0)
{
if(stat(groupoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(groupoutname);
}
}
}
return;
}
/*===========================================================================*/
static void writelceapolpmkidfile(char *pmkideapoloutname, long int lcmin, long int
lcmax)
{
static long int lc;
static FILE *fh_pmkideapol;
static hashlist_t *zeiger;
static hashlist_t *zeiger2;
static hashlist_t *zeigerbegin;
static hashlist_t *zeigerend;
static struct stat statinfo;

if(lcmax == 0) lcmax = pmkideapolcount;


if(lcmin > lcmax) return;
if(pmkideapoloutname != NULL)
{
if((fh_pmkideapol = fopen(pmkideapoloutname, "a")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", pmkideapoloutname,
strerror(errno));
return;
}
}
qsort(hashlist, pmkideapolcount, HASHLIST_SIZE, sort_hashlist_by_essid);
zeigerbegin = hashlist;
lc = 0;
for(zeiger = hashlist +1; zeiger < hashlist +pmkideapolcount; zeiger++)
{
if(memcmp(zeigerbegin->essid, zeiger->essid, ESSID_LEN_MAX) == 0)
{
zeigerend = zeiger;
lc++;
}
else
{
if(((zeigerend -zeigerbegin) >= lcmin) && ((zeigerend -zeigerbegin) <=
lcmax))
{
for(zeiger2 = zeigerbegin; zeiger2 <= zeigerend; zeiger2++)
writepmkideapolhashline(fh_pmkideapol, zeiger2);
}
lc = 0;
zeigerbegin = zeiger;
}
}
if(fh_pmkideapol != NULL) fclose(fh_pmkideapol);
if(pmkideapoloutname != NULL)
{
if(stat(pmkideapoloutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(pmkideapoloutname);
}
}
return;
}
/*===========================================================================*/
static void writeeapolpmkidfile(char *pmkideapoloutname)
{
static FILE *fh_pmkideapol;
static hashlist_t *zeiger;
static struct stat statinfo;

if(pmkideapoloutname != NULL)
{
if((fh_pmkideapol = fopen(pmkideapoloutname, "a")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", pmkideapoloutname,
strerror(errno));
return;
}
}
for(zeiger = hashlist; zeiger < hashlist +pmkideapolcount; zeiger++)
writepmkideapolhashline(fh_pmkideapol, zeiger);
if(fh_pmkideapol != NULL) fclose(fh_pmkideapol);
if(pmkideapoloutname != NULL)
{
if(stat(pmkideapoloutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(pmkideapoloutname);
}
}
return;
}
/*===========================================================================*/
static void writepmkideapolhashlineinfo(FILE *fh_pmkideapol, hashlist_t *zeiger)
{
static eapauth_t *eapa;
static wpakey_t *wpak;
static uint8_t keyver;
static uint64_t rc;
static char *vendor;

if((zeiger->essidlen < essidlenmin) || (zeiger->essidlen > essidlenmax)) return;


if(((zeiger->type &hashtype) != HCX_TYPE_PMKID) && ((zeiger->type &hashtype) !=
HCX_TYPE_EAPOL)) return;
if(flagfiltermacap == true) if(memcmp(&filtermacap, zeiger->ap, 6) != 0) return;
if(flagfiltermacclient == true) if(memcmp(&filtermacclient, zeiger->client, 6) !=
0) return;
if(flagfilterouiap == true) if(memcmp(&filterouiap, zeiger->ap, 3) != 0) return;
if(flagfilterouiclient == true) if(memcmp(&filterouiclient, zeiger->client, 3) !=
0) return;
if(filteressidptr != NULL)
{
if(zeiger->essidlen != filteressidlen) return;
if(memcmp(zeiger->essid, filteressidptr, zeiger->essidlen) != 0) return;
}
if(filteressidpartptr != NULL)
{
if(ispartof(filteressidpartlen, (uint8_t*)filteressidpartptr, zeiger-
>essidlen, zeiger->essid) == false) return;
}
if((filtervendorptr != NULL) || (filtervendorapptr != NULL) ||
(filtervendorclientptr != NULL))
{
if(isoui(zeiger->ap, zeiger->client) == false) return;
}
if((flagfilterapless == true) && ((zeiger->mp &0x10) != 0x10)) return;
if((flagfilterrcchecked == true) && ((zeiger->mp &0x80) == 0x80)) return;
if((flagfilterrcnotchecked == true) && ((zeiger->mp &0x80) != 0x80)) return;
if((flagfilterauthorized == true) && ((zeiger->mp &0x07) == 0x00)) return;
if((flagfilterchallenge == true) && ((zeiger->mp &0x07) != 0x01)) return;

fprintf(fh_pmkideapol, "SSID.......: %.*s\n", zeiger->essidlen, zeiger->essid);


vendor = getvendor(zeiger->ap);
fprintf(fh_pmkideapol, "MAC_AP.....: %02x%02x%02x%02x%02x%02x (%s)\n", zeiger-
>ap[0], zeiger->ap[1], zeiger->ap[2], zeiger->ap[3], zeiger->ap[4], zeiger->ap[5],
vendor);
vendor = getvendor(zeiger->client);
fprintf(fh_pmkideapol, "MAC_CLIENT.: %02x%02x%02x%02x%02x%02x (%s)\n", zeiger-
>client[0], zeiger->client[1], zeiger->client[2], zeiger->client[3], zeiger-
>client[4], zeiger->client[5], vendor);
if(zeiger->type == HCX_TYPE_PMKID)
{
fprintf(fh_pmkideapol, "PMKID......: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x
%02x%02x%02x%02x%02x%02x\n",
zeiger->hash[0], zeiger->hash[1], zeiger->hash[2], zeiger->hash[3],
zeiger->hash[4], zeiger->hash[5], zeiger->hash[6], zeiger->hash[7],
zeiger->hash[8], zeiger->hash[9], zeiger->hash[10], zeiger->hash[11],
zeiger->hash[12], zeiger->hash[13], zeiger->hash[14], zeiger->hash[15]);
}
if(zeiger->type == HCX_TYPE_EAPOL)
{
eapa = (eapauth_t*)zeiger->eapol;
wpak = (wpakey_t*)&zeiger->eapol[EAPAUTH_SIZE];
if(eapa->version == 1) fprintf(fh_pmkideapol, "VERSION....: 802.1X-2001 (1)\
n");
if(eapa->version == 2) fprintf(fh_pmkideapol, "VERSION....: 802.1X-2004 (2)\
n");
keyver = ntohs(wpak->keyinfo) & WPA_KEY_INFO_TYPE_MASK;
if(keyver == 1) fprintf(fh_pmkideapol, "KEY VERSION: WPA1\n");
if(keyver == 2) fprintf(fh_pmkideapol, "KEY VERSION: WPA2\n");
if(keyver == 3) fprintf(fh_pmkideapol, "KEY VERSION: WPA2 key version 3\n");
#ifndef BIG_ENDIAN_HOST
rc = byte_swap_64(wpak->replaycount);
#else
rc = wpak->replaycount;
#endif
fprintf(fh_pmkideapol, "REPLAYCOUNT: %" PRIu64 "\n", rc);
if((zeiger->mp & 0x10) == 0x10) fprintf(fh_pmkideapol, "RC INFO....: ROGUE
attack / NC not required\n");
else if((zeiger->mp & 0x80) == 0x00) fprintf(fh_pmkideapol, "RC INFO....: NC
not required\n");
else if((zeiger->mp & 0x80) == 0x80) fprintf(fh_pmkideapol, "RC INFO....: NC
suggested\n");
if((zeiger->mp & 0xe0) == 0x20) fprintf(fh_pmkideapol, "RC INFO....: little
endian router / NC LE suggested\n");
if((zeiger->mp & 0xe0) == 0x40) fprintf(fh_pmkideapol, "RC INFO....: big
endian router / NC BE suggested\n");
if((zeiger->mp & 0x07) == 0x00) fprintf(fh_pmkideapol, "MP M1M2 E2.:
challenge\n");
if((zeiger->mp & 0x07) == 0x01) fprintf(fh_pmkideapol, "MP M1M4 E4.:
authorized\n");
if((zeiger->mp & 0x07) == 0x02) fprintf(fh_pmkideapol, "MP M2M3 E2.:
authorized\n");
if((zeiger->mp & 0x07) == 0x03) fprintf(fh_pmkideapol, "MP M2M3 E3.:
authorized\n");
if((zeiger->mp & 0x07) == 0x04) fprintf(fh_pmkideapol, "MP M3M4 E3.:
authorized\n");
if((zeiger->mp & 0x07) == 0x05) fprintf(fh_pmkideapol, "MP M3M4 E4.:
authorized\n");
fprintf(fh_pmkideapol, "MIC........: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x
%02x%02x%02x%02x%02x%02x\n",
zeiger->hash[0], zeiger->hash[1], zeiger->hash[2], zeiger->hash[3],
zeiger->hash[4], zeiger->hash[5], zeiger->hash[6], zeiger->hash[7],
zeiger->hash[8], zeiger->hash[9], zeiger->hash[10], zeiger->hash[11],
zeiger->hash[12], zeiger->hash[13], zeiger->hash[14], zeiger->hash[15]);
}
fprintf(fh_pmkideapol, "HASHLINE...: ");
writepmkideapolhashline(fh_pmkideapol, zeiger);
fprintf(fh_pmkideapol, "\n");
return;
}
/*===========================================================================*/
static void writevendorapinfofile(char *vendorinfooutname)
{
static char *vendor;
static hashlist_t *zeiger;
static FILE *fh_info;

qsort(hashlist, pmkideapolcount, HASHLIST_SIZE, sort_hashlist_by_macap);


if(strcmp(vendorinfooutname, "stdout") != 0)
{
if((fh_info = fopen(vendorinfooutname, "a")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", vendorinfooutname,
strerror(errno));
return;
}
vendor = getvendor(hashlist->ap);
fprintf(fh_info, "%02x%02x%02x\t%s\t[ACCESS POINT]\n", hashlist->ap[0],
hashlist->ap[1], hashlist->ap[2], vendor);
for(zeiger = hashlist +1; zeiger < hashlist +pmkideapolcount; zeiger++)
{
if(memcmp((zeiger -1)->ap, zeiger->ap, 3) != 0)
{
vendor = getvendor(zeiger->ap);
fprintf(fh_info, "%02x%02x%02x\t%s\t[ACCESS POINT]\n", zeiger-
>ap[0], zeiger->ap[1], zeiger->ap[2], vendor);
}
}
fclose(fh_info);
}
else
{
vendor = getvendor(hashlist->ap);
fprintf(stdout, "%02x%02x%02x\t%s\t[ACCESS POINT]\n", hashlist->ap[0],
hashlist->ap[1], hashlist->ap[2], vendor);
for(zeiger = hashlist +1; zeiger < hashlist +pmkideapolcount; zeiger++)
{
if(memcmp((zeiger -1)->ap, zeiger->ap, 3) != 0)
{
vendor = getvendor(zeiger->ap);
fprintf(stdout, "%02x%02x%02x\t%s\t[ACCESS POINT]\n", zeiger-
>ap[0], zeiger->ap[1], zeiger->ap[2], vendor);
}
}
}
return;
}
/*===========================================================================*/
static void writevendorclientinfofile(char *vendorinfooutname)
{
static char *vendor;
static hashlist_t *zeiger;
static FILE *fh_info;

qsort(hashlist, pmkideapolcount, HASHLIST_SIZE, sort_hashlist_by_macclient);


if(strcmp(vendorinfooutname, "stdout") != 0)
{
if((fh_info = fopen(vendorinfooutname, "a")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", vendorinfooutname,
strerror(errno));
return;
}
vendor = getvendor(hashlist->client);
fprintf(fh_info, "%02x%02x%02x\t%s\t[CLIENT]\n", hashlist->client[0],
hashlist->client[1], hashlist->client[2], vendor);
for(zeiger = hashlist +1; zeiger < hashlist +pmkideapolcount; zeiger++)
{
if(memcmp((zeiger -1)->client, zeiger->client, 3) != 0)
{
vendor = getvendor(zeiger->client);
fprintf(fh_info, "%02x%02x%02x\t%s\t[CLIENT]\n", zeiger-
>client[0], zeiger->client[1], zeiger->client[2], vendor);
}
}
fclose(fh_info);
}
else
{
vendor = getvendor(hashlist->ap);
fprintf(stdout, "%02x%02x%02x\t%s\t[CLIENT]\n", hashlist->ap[0], hashlist-
>ap[1], hashlist->ap[2], vendor);
for(zeiger = hashlist +1; zeiger < hashlist +pmkideapolcount; zeiger++)
{
if(memcmp((zeiger -1)->ap, zeiger->ap, 3) != 0)
{
vendor = getvendor(zeiger->ap);
fprintf(stdout, "%02x%02x%02x\t%s\t[CLIENT]\n", zeiger->ap[0],
zeiger->ap[1], zeiger->ap[2], vendor);
}
}
}
return;
}
/*===========================================================================*/
static void writeinfofile(char *infooutname)
{
static hashlist_t *zeiger;
static FILE *fh_info;

if(strcmp(infooutname, "stdout") != 0)
{
if((fh_info = fopen(infooutname, "a")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", infooutname,
strerror(errno));
return;
}
for(zeiger = hashlist; zeiger < hashlist +pmkideapolcount; zeiger++)
writepmkideapolhashlineinfo(fh_info, zeiger);
fclose(fh_info);
}
else
{
for(zeiger = hashlist; zeiger < hashlist +pmkideapolcount; zeiger++)
writepmkideapolhashlineinfo(stdout, zeiger);
}
return;
}
/*===========================================================================*/
static uint16_t getfield(char *lineptr, size_t bufflen, uint8_t *buff)
{
static size_t p;
static uint8_t idx0;
static uint8_t idx1;
static const uint8_t hashmap[] =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 01234567
0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 89:;<=>?
0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, // @ABCDEFG
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // HIJKLMNO
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // PQRSTUVW
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // XYZ[\]^_
0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, // `abcdefg
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // hijklmno
};

memset(buff, 0, bufflen);
p = 0;
while((lineptr[p] != '*') && (lineptr[p] != 0) && (p /2 <= bufflen))
{
if(!isxdigit((unsigned char)lineptr[p +0])) return 0;
if(!isxdigit((unsigned char)lineptr[p +1])) return 0;
if((lineptr[p +1] == '*') || (lineptr[p +1] == 0)) return 0;
idx0 = ((uint8_t)lineptr[p +0] &0x1F) ^0x10;
idx1 = ((uint8_t)lineptr[p +1] &0x1F) ^0x10;
buff[p /2] = (uint8_t)(hashmap[idx0] <<4) | hashmap[idx1];
p += 2;
}
return p /2;
}
/*===========================================================================*/
static size_t chop(char *buffer, size_t len)
{
static char *ptr;

ptr = buffer +len -1;


while(len)
{
if (*ptr != '\n') break;
*ptr-- = 0;
len--;
}
while(len)
{
if (*ptr != '\r') break;
*ptr-- = 0;
len--;
}
return len;
}
/*---------------------------------------------------------------------------*/
static int fgetline(FILE *inputstream, size_t size, char *buffer)
{
static size_t len;
static char *buffptr;

if(feof(inputstream)) return -1;


buffptr = fgets (buffer, size, inputstream);
if(buffptr == NULL) return -1;
len = strlen(buffptr);
len = chop(buffptr, len);
return len;
}
/*===========================================================================*/
static void removepmkideapol(char *macskipname)
{
static int len;
static int p1, p2;
static FILE *fh_maclistin;
static long int i, f, r;
static int maclistskipcount, maclistskipmax;
static maclist_t *maclistskip, *zeiger, *maclistskipnew;
static hashlist_t *zeigerhash;
static char linein[PMKIDEAPOL_BUFFER_LEN];

maclistskipmax = 1000;
if((maclistskip = (maclist_t*)calloc(maclistskipmax, MACLIST_SIZE)) == NULL)
return;
if((fh_maclistin = fopen(macskipname, "r")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", macskipname, strerror(errno));
return;
}
zeiger = maclistskip;
maclistskipcount = 0;
while(1)
{
if((len = fgetline(fh_maclistin, PMKIDEAPOL_BUFFER_LEN, linein)) == -1)
break;
if(len < 12) continue;
if(len > 17)
{
p2 = 0;
for(p1 = 0; p1 < 17; p1++)
{
if(isxdigit((unsigned char)linein[p1]))
{
linein[p2] = linein[p1];
p2++;
}
}
linein[p2] = 0;
len = p2;
}
linein[12] = 0;
if(getfield(linein, 6, zeiger->mac) != 6) continue;
maclistskipcount++;
if(maclistskipcount >= maclistskipmax)
{
maclistskipmax += 1000;
maclistskipnew = (maclist_t*)realloc(maclistskip, maclistskipmax
*MACLIST_SIZE);
if(maclistskipnew == NULL)
{
fprintf(stderr, "failed to allocate memory for internal list\n");
exit(EXIT_FAILURE);
}
maclistskip = maclistskipnew;
}
zeiger = maclistskip +maclistskipcount;
}
if(fh_maclistin != NULL) fclose(fh_maclistin);
qsort(maclistskip, maclistskipcount, MACLIST_SIZE, sort_maclistin);
qsort(hashlist, pmkideapolcount, HASHLIST_SIZE, sort_hashlist_by_macap);
zeigerhash = hashlist;
zeiger = maclistskip;
f = 0;
r = 0;
for(i = 0; i < pmkideapolcount; i++)
{
if(memcmp((zeigerhash +i)->ap, (zeiger +f)->mac, 6) > 0)
while(f < maclistskipcount)
{
if(memcmp((zeiger +f)->mac, (zeigerhash +i)->ap, 6) >= 0) break;
f++;
}
if(memcmp((zeigerhash +i)->ap, (zeiger +f)->mac, 6) == 0)
{
(zeigerhash +i)->type = HS_REMOVED;
r++;
}
}
qsort(hashlist, pmkideapolcount, HASHLIST_SIZE, sort_hashlist_by_type);
pmkidcount -= r;
qsort(hashlist, pmkideapolcount, HASHLIST_SIZE, sort_hashlist_by_macclient);
zeigerhash = hashlist;
zeiger = maclistskip;
f = 0;
r = 0;
for(i = 0; i < pmkideapolcount; i++)
{
if(memcmp((zeigerhash +i)->client, (zeiger +f)->mac, 6) > 0)
while(f < maclistskipcount)
{
if(memcmp((zeiger +f)->mac, (zeigerhash +i)->client, 6) >= 0) break;
f++;
}
if(memcmp((zeigerhash +i)->client, (zeiger +f)->mac, 6) == 0)
{
(zeigerhash +i)->type = HS_REMOVED;
r++;
}
}
qsort(hashlist, pmkideapolcount, HASHLIST_SIZE, sort_hashlist_by_type);
pmkidcount -= r;
if(maclistskip != NULL) free(maclistskip);
return;
}
/*===========================================================================*/
static void processmacfile(char *maclistinname, char *pmkideapoloutname)
{
static int len;
static int p1, p2;
static FILE *fh_maclistin;
static FILE *fh_pmkideapol;
static struct stat statinfo;
static int maclistincount, maclistinmax;
static maclist_t *maclistin, *zeiger, *maclistinnew;
static hashlist_t *zeigerhash;
static int i, o;

static char linein[PMKIDEAPOL_BUFFER_LEN];

maclistinmax = 1000;
if((maclistin = (maclist_t*)calloc(maclistinmax, MACLIST_SIZE)) == NULL) return;
if((fh_maclistin = fopen(maclistinname, "r")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", maclistinname,
strerror(errno));
return;
}
zeiger = maclistin;
maclistincount = 0;
while(1)
{
if((len = fgetline(fh_maclistin, PMKIDEAPOL_BUFFER_LEN, linein)) == -1)
break;
if(len == 17)
{
p2 = 0;
for(p1 = 0; p1 < 17; p1++)
{
if(isxdigit((unsigned char)linein[p1]))
{
linein[p2] = linein[p1];
p2++;
}
}
linein[p2] = 0;
len = p2;
}
if(len != 12) continue;
if(getfield(linein, 6, zeiger->mac) != 6) continue;
maclistincount++;
if(maclistincount >= maclistinmax)
{
maclistinmax += 1000;
maclistinnew = (maclist_t*)realloc(maclistin, maclistinmax
*MACLIST_SIZE);
if(maclistinnew == NULL)
{
fprintf(stdout, "failed to allocate memory for internal list\n");
exit(EXIT_FAILURE);
}
maclistin = maclistinnew;
}
zeiger = maclistin +maclistincount;
}
if(fh_maclistin != NULL) fclose(fh_maclistin);
qsort(maclistin, maclistincount, MACLIST_SIZE, sort_maclistin);
if(pmkideapoloutname != NULL)
{
if((fh_pmkideapol = fopen(pmkideapoloutname, "a")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", pmkideapoloutname,
strerror(errno));
free(maclistin);
return;
}
}
qsort(hashlist, pmkideapolcount, HASHLIST_SIZE, sort_hashlist_by_macap);
zeiger = maclistin;
zeigerhash = hashlist;
o = 0;
for(i = 0; i < maclistincount; i++)
{
while(o < pmkideapolcount)
{
if(memcmp((zeigerhash +o)->ap, (zeiger +i)->mac, 6) > 0) break;
if(memcmp((zeigerhash +o)->ap, (zeiger +i)->mac, 6) == 0)
writepmkideapolhashline(fh_pmkideapol, zeigerhash +o);
o++;
}
}
qsort(hashlist, pmkideapolcount, HASHLIST_SIZE, sort_hashlist_by_macclient);
zeiger = maclistin;
zeigerhash = hashlist;
o = 0;
for(i = 0; i < maclistincount; i++)
{
while(o < pmkideapolcount)
{
if(memcmp((zeigerhash +o)->client, (zeiger +i)->mac, 6) > 0) break;
if(memcmp((zeigerhash +o)->client, (zeiger +i)->mac, 6) == 0)
writepmkideapolhashline(fh_pmkideapol, zeigerhash +o);
o++;
}
}
if(fh_pmkideapol != NULL) fclose(fh_pmkideapol);
if(pmkideapoloutname != NULL)
{
if(stat(pmkideapoloutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(pmkideapoloutname);
}
}
if(maclistin != NULL) free(maclistin);
return;
}
/*===========================================================================*/
static void processessidfile(char *essidlistinname, char *pmkideapoloutname)
{
static int len;
static int i, o;
static FILE *fh_essidlistin;
static FILE *fh_pmkideapol;
static struct stat statinfo;
static int essidlistincount, essidlistinmax;
static essidlist_t *essidlistin, *zeiger, *essidlistinnew;
static hashlist_t *zeigerhash;
static char hexpfx[] = { "$HEX[" };
static char linein[PMKIDEAPOL_BUFFER_LEN];

essidlistinmax = 1000;
if((essidlistin = (essidlist_t*)calloc(essidlistinmax, ESSIDLIST_SIZE)) == NULL)
return;
if((fh_essidlistin = fopen(essidlistinname, "r")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", essidlistinname,
strerror(errno));
return;
}
zeiger = essidlistin;
essidlistincount = 0;
while(1)
{
if((len = fgetline(fh_essidlistin, PMKIDEAPOL_BUFFER_LEN, linein)) == -1)
break;
if((len < 1) || (len > 70)) continue;
memset(zeiger->essid, 0, 33);
if((len >= 8) && ((len %2) == 0) && (linein[len -1] == ']') &&
(memcmp(linein, hexpfx, 5) == 0))
{
linein[len -1] = 0;
zeiger->essidlen = getfield(&linein[5], 32, zeiger->essid);
}
else if(len <= 32)
{
zeiger->essidlen = len;
memcpy(zeiger->essid, linein, len);
}
else continue;
essidlistincount++;
if(essidlistincount >= essidlistinmax)
{
essidlistinmax += 1000;
essidlistinnew = (essidlist_t*)realloc(essidlistin, essidlistinmax
*ESSIDLIST_SIZE);
if(essidlistinnew == NULL)
{
fprintf(stderr, "failed to allocate memory for internal list\n");
exit(EXIT_FAILURE);
}
essidlistin = essidlistinnew;
}
zeiger = essidlistin +essidlistincount;
}
if(fh_essidlistin != NULL) fclose(fh_essidlistin);
qsort(essidlistin, essidlistincount, ESSIDLIST_SIZE, sort_essidlistin);
qsort(hashlist, pmkideapolcount, HASHLIST_SIZE, sort_hashlist_by_essidlen);
if(pmkideapoloutname == NULL)
{
if(essidlistin != NULL) free(essidlistin);
return;
}
if((fh_pmkideapol = fopen(pmkideapoloutname, "a")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", pmkideapoloutname,
strerror(errno));
free(essidlistin);
return;
}
zeiger = essidlistin;
zeigerhash = hashlist;
o = 0;
for(i = 0; i < essidlistincount; i++)
{
while(o < pmkideapolcount)
{
if((zeigerhash +o)->essidlen < (zeiger +i)->essidlen)
{
o++;
continue;
}
if((zeigerhash +o)->essidlen > (zeiger +i)->essidlen) break;
if((memcmp((zeigerhash +o)->essid, (zeiger +i)->essid, (zeigerhash +o)-
>essidlen)) > 0) break;
if((memcmp((zeigerhash +o)->essid, (zeiger +i)->essid, (zeigerhash +o)-
>essidlen)) == 0) writepmkideapolhashline(fh_pmkideapol, zeigerhash +o);
o++;
}
}
if(fh_pmkideapol != NULL) fclose(fh_pmkideapol);
if(pmkideapoloutname != NULL)
{
if(stat(pmkideapoloutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(pmkideapoloutname);
}
}
if(essidlistin != NULL) free(essidlistin);
return;
}
/*===========================================================================*/
static bool readpmkideapolfile(FILE *fh_pmkideapol)
{
static int len;
static int oflen;
static uint16_t essidlen;
static uint16_t noncelen;
static uint16_t eapauthlen;
static uint16_t mplen;
static hashlist_t *zeiger, *hashlistnew;
static const char wpa01[] = { "WPA*01*" };
static const char wpa02[] = { "WPA*02*" };

static char linein[PMKIDEAPOL_LINE_LEN +1];


static uint8_t buffer[PMKIDEAPOL_LINE_LEN +1];

zeiger = hashlist;
while(1)
{
if((len = fgetline(fh_pmkideapol, PMKIDEAPOL_LINE_LEN, linein)) == -1) break;
readcount++;
if(len < 68)
{
readerrorcount++;
continue;
}
if((memcmp(&linein, &wpa01, 7) != 0) && (memcmp(&linein, &wpa02, 7) != 0))
{
readerrorcount++;
continue;
}
if((linein[39] != '*') && (linein[52] != '*') && (linein[65] != '*'))
{
readerrorcount++;
continue;
}
if(getfield(&linein[7], PMKIDEAPOL_LINE_LEN, buffer) != 16)
{
readerrorcount++;
continue;
}
memcpy(zeiger->hash, &buffer, 16);

if(getfield(&linein[40], PMKIDEAPOL_LINE_LEN, buffer) != 6)


{
readerrorcount++;
continue;
}
memcpy(zeiger->ap, &buffer, 6);

if(getfield(&linein[53], PMKIDEAPOL_LINE_LEN, buffer) != 6)


{
readerrorcount++;
continue;
}
memcpy(zeiger->client, &buffer, 6);
essidlen = getfield(&linein[66], PMKIDEAPOL_LINE_LEN, buffer);
if(essidlen > 32)
{
readerrorcount++;
continue;
}
memcpy(zeiger->essid, &buffer, essidlen);
zeiger->essidlen = essidlen;
if(memcmp(&linein, &wpa01, 7) == 0)
{
zeiger->type = HS_PMKID;
pmkidcount++;
}
else if(memcmp(&linein, &wpa02, 7) == 0)
{
oflen = 66 +essidlen *2 +1;
noncelen = getfield(&linein[oflen], PMKIDEAPOL_LINE_LEN, buffer);
if(noncelen > 32)
{
readerrorcount++;
continue;
}
memcpy(zeiger->nonce, &buffer, 32);
oflen += 65;
eapauthlen = getfield(&linein[oflen], PMKIDEAPOL_LINE_LEN, buffer);
if(eapauthlen > EAPOL_AUTHLEN_MAX)
{
readerrorcount++;
continue;
}
memcpy(zeiger->eapol, &buffer, eapauthlen);
zeiger->eapauthlen = eapauthlen;
oflen += eapauthlen *2 +1;
mplen = getfield(&linein[oflen], PMKIDEAPOL_LINE_LEN, buffer);
if(mplen > 1)
{
readerrorcount++;
continue;
}
zeiger->mp = buffer[0];
zeiger->type = HS_EAPOL;
eapolcount++;
}
else
{
readerrorcount++;
continue;
}
pmkideapolcount = pmkidcount +eapolcount;
if(pmkideapolcount >= hashlistcount)
{
hashlistcount += HASHLIST_MAX;
hashlistnew = (hashlist_t*)realloc(hashlist, hashlistcount
*HASHLIST_SIZE);
if(hashlistnew == NULL)
{
fprintf(stderr, "failed to allocate memory for internal list\n");
exit(EXIT_FAILURE);
}
hashlist = hashlistnew;
}
zeiger = hashlist +pmkideapolcount;
}
return true;
}
/*===========================================================================*/
static bool readbpkdf2file(char *pkdf2inname)
{
static int len;
static char *pskpos;
static FILE *fh_pbkdf2;
static char linein[PBKDF2_LINE_LEN +1];

if((fh_pbkdf2 = fopen(pkdf2inname, "r")) == NULL)


{
fprintf(stdout, "error opening file %s: %s\n", pkdf2inname, strerror(errno));
return false;
}

pbkdf2count = 0;
pbkdf2readerrorcount = 0;
while(1)
{
if((len = fgetline(fh_pbkdf2, PBKDF2_LINE_LEN, linein)) == -1) break;
if(len < 76)
{
pbkdf2readerrorcount++;
continue;
}
if(linein[64] != '*')
{
pbkdf2readerrorcount++;
continue;
}
pskpos = strchr(&linein[65], ':');
if(pskpos == NULL)
{
pbkdf2readerrorcount++;
continue;
}
pskpos[0] = 0;
fprintf(stdout, "%s %s\n", &linein[65], pskpos +1);
pbkdf2count++;
}
fclose(fh_pbkdf2);

return true;
}
/*===========================================================================*/
static void showvendorlist(void)
{
static ouilist_t *zeiger;

fprintf(stdout, "\n");
for(zeiger = ouilist; zeiger < ouilist +ouicount; zeiger++) fprintf(stdout, "%02x
%02x%02x %s\n", zeiger->oui[0], zeiger->oui[1], zeiger->oui[2], zeiger->vendor);
return;
}
/*===========================================================================*/
static int isvendor(int len, char *linein)
{
static int c;
static int ret;
for(c = 7; c < len; c++)
{
if(islower((unsigned char)linein[c])) linein[c] = toupper((unsigned
char)linein[c]);
}
ret = 0;
if(filtervendorptr != NULL)
{
if(strstr(&linein[7], filtervendorptr) != NULL) ret |= TYPE_AP + TYPE_CLIENT;
}
if(filtervendorapptr != NULL)
{
if(strstr(&linein[7], filtervendorapptr) != NULL) ret |= TYPE_AP;
}
if(filtervendorclientptr != NULL)
{
if(strstr(&linein[7], filtervendorclientptr) != NULL) ret |= TYPE_CLIENT;
}
return ret;
}
/*===========================================================================*/
static void readoui(void)
{
static int len;
static uid_t uid;
static struct passwd *pwd;
static struct stat statinfo;
static ouilist_t *zeiger, *ouilistnew;
static FILE *fh_oui;
static char *vendorptr;
static const char *ouinameuser = "/.hcxtools/oui.txt";
static const char *ouinamesystemwide = "/usr/share/ieee-data/oui.txt";
static const char *ouina = "N/A";
static char ouinameuserpath[PATH_MAX +1];
static char linein[OUI_LINE_LEN +1];

usedoui = ouina;
uid = getuid();
pwd = getpwuid(uid);
if(pwd == NULL) return;
strncpy(ouinameuserpath, pwd->pw_dir, PATH_MAX -1);
strncat(ouinameuserpath, ouinameuser, PATH_MAX -1);
if(stat(ouinameuserpath, &statinfo) == 0) usedoui = ouinameuserpath;
else if(stat(ouinameuser, &statinfo) == 0) usedoui = ouinamesystemwide;
else return;
if((fh_oui = fopen(usedoui, "r")) == NULL) return;
zeiger = ouilist;
while(1)
{
if((len = fgetline(fh_oui, OUI_LINE_LEN, linein)) == -1) break;
if(len < 20) continue;
linein[6] = 0;
if(getfield(linein, OUI_LINE_LEN, zeiger->oui) != 3) continue;
if(strstr(&linein[7], "(base 16)") == NULL) continue;
zeiger->type = 0;
if((filtervendorptr != NULL) || (filtervendorapptr != NULL) ||
(filtervendorclientptr != NULL))
{
zeiger->type = isvendor(len, linein);
if(zeiger->type == 0) continue;
}
vendorptr = strrchr(&linein[7], '\t');
if(vendorptr == NULL) continue;
if(vendorptr++ == 0) continue;
strncpy(zeiger->vendor, vendorptr, VENDOR_LEN_MAX -1);
ouicount++;
if(ouicount >= ouilistcount)
{
ouilistcount += OUILIST_MAX;
ouilistnew = (ouilist_t*)realloc(ouilist, ouilistcount *OUILIST_SIZE);
if(ouilistnew == NULL)
{
fprintf(stderr, "failed to allocate memory for internal list\n");
exit(EXIT_FAILURE);
}
ouilist = ouilistnew;
}
zeiger = ouilist +ouicount;
}
fclose(fh_oui);
qsort(ouilist, ouicount, OUILIST_SIZE, sort_ouilist_by_oui);
return;
}
/*===========================================================================*/
static void downloadoui(void)
{
static uid_t uid;
static size_t bread;
static struct passwd *pwd;
static CURLcode ret;
static CURL *hnd;
static FILE *fhoui;
static FILE *fhouitmp;
static struct stat statinfo;
static const char *ouipath = "/.hcxtools";
static const char *ouiname = "/oui.txt";
static char ouinameuserpath[PATH_MAX];
static char ouibuff[OUIBUFFER_MAX];

uid = getuid();
pwd = getpwuid(uid);
if(pwd == NULL) return;
strncpy(ouinameuserpath, pwd->pw_dir, PATH_MAX -1);
strncat(ouinameuserpath, ouipath, PATH_MAX -1);
if(stat(ouinameuserpath, &statinfo) == -1)
{
if(mkdir(ouinameuserpath, 0755) == -1)
{
fprintf(stderr, "failed to create conf dir\n");
return;
}
}
strncat(ouinameuserpath, ouiname, PATH_MAX -1);
fprintf(stdout, "start downloading oui from https://standards-oui.ieee.org to: %s\
n", ouinameuserpath);
if((fhouitmp = tmpfile()) == NULL)
{
fprintf(stderr, "\nfailed to create temporary download file\n");
return;
}
hnd = curl_easy_init ();
curl_easy_setopt(hnd, CURLOPT_URL, "https://standards-oui.ieee.org/oui/oui.txt");
curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 5L);
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, fhouitmp) ;
curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 0L);
ret = curl_easy_perform(hnd);
curl_easy_cleanup(hnd);
if(ret != 0)
{
fprintf(stderr, "\ndownload not successful\n");
return;
}
rewind(fhouitmp);
if((fhoui = fopen(ouinameuserpath, "w")) == NULL)
{
fprintf(stderr, "\nfailed to create %s\n", ouiname);
return;
}
while (!feof(fhouitmp))
{
bread = fread(ouibuff, 1, sizeof(ouibuff), fhouitmp);
if(bread > 0) fwrite(ouibuff, 1, bread, fhoui);
}
fclose(fhoui);
fprintf(stdout, "\ndownload finished\n");
return;
}
/*===========================================================================*/
__attribute__ ((noreturn))
static void version(char *eigenname)
{
fprintf(stdout, "%s %s (C) %s ZeroBeat\n", eigenname, VERSION_TAG, VERSION_YEAR);
exit(EXIT_SUCCESS);
}
/*---------------------------------------------------------------------------*/
__attribute__ ((noreturn))
static void usage(char *eigenname)
{
fprintf(stdout, "%s %s (C) %s ZeroBeat\n"
"usage:\n"
"%s <options>\n"
"\n"
"options:\n"
"-i <file> : input PMKID/EAPOL hash file\n"
"-o <file> : output PMKID/EAPOL hash file\n"
"-E <file> : output ESSID list (autohex enabled)\n"
"-E stdout : output ESSID list to stdout (autohex enabled)\n"
"-L <file> : output ESSID list (unfiltered and unsorted)\n"
" useful in combination with hashcat -a9 option\n"
"-d : download https://standards-oui.ieee.org/oui.txt\n"
" and save to ~/.hcxtools/oui.txt\n"
" internet connection required\n"
// "-p : input PBKDF2 file (hashcat potfile 22000 format)\n"
"-h : show this help\n"
"-v : show version\n"
"\n"
"--essid-group : convert to ESSID groups in working directory\
n"
" full advantage of reuse of PBKDF2\n"
" not on old hash formats\n"
"--oui-group : convert to OUI groups in working directory\n"
" not on old hash formats\n"
"--mac-group-ap : convert APs to MAC groups in working
directory\n"
" not on old hash formats\n"
"--mac-group-client : convert CLIENTs to MAC groups in working
directory\n"
" not on old hash formats\n"
"--type=<digit> : filter by hash type\n"
" bitmask:\n"
" 1 = PMKID\n"
" 2 = EAPOL\n"
" default PMKID and EAPOL (1+2=3)\n"
"--hcx-min=<digit> : disregard hashes with occurrence lower than
hcx-min/ESSID\n"
"--hcx-max=<digit> : disregard hashes with occurrence higher than
hcx-max/ESSID\n"
"--essid-len : filter by ESSID length\n"
" default ESSID length: %d...%d\n"
"--essid-min : filter by ESSID minimum length\n"
" default ESSID minimum length: %d\n"
"--essid-max : filter by ESSID maximum length\n"
" default ESSID maximum length: %d\n"
"--essid=<ESSID> : filter by ESSID\n"
"--essid-part=<part of ESSID> : filter by part of ESSID (case sensitive)\n"
"--essid-partx=<part of ESSID>: filter by part of ESSID (case insensitive)\n"
" locale and wide characters are ignored\n"
"--essid-list=<file> : filter by ESSID file\n"
"--mac-ap=<MAC> : filter AP by MAC\n"
" format: 001122334455, 00:11:22:33:44:55, 00-
11-22-33-44-55 (hex)\n"
"--mac-client=<MAC> : filter CLIENT by MAC\n"
" format: 001122334455, 00:11:22:33:44:55, 00-
11-22-33-44-55 (hex)\n"
"--mac-list=<file> : filter by MAC file\n"
" format: 001122334455, 00:11:22:33:44:55, 00-
11-22-33-44-55 (hex)\n"
"--mac-skiplist=<file> : exclude MAC from file\n"
" format: 001122334455, 00:11:22:33:44:55, 00-
11-22-33-44-55 (hex)\n"
"--oui-ap=<OUI> : filter AP by OUI\n"
" format: 001122, 00:11:22, 00-11-22 (hex)\n"
"--oui-client=<OUI> : filter CLIENT by OUI\n"
" format: 001122, 00:11:22, 00-11-22 (hex)\n"
"--vendor=<VENDOR> : filter AP or CLIENT by (part of) VENDOR name\
n"
"--vendor-ap=<VENDOR> : filter AP by (part of) VENDOR name\n"
"--vendor-client=<VENDOR> : filter CLIENT by (part of) VENDOR name\n",
eigenname, VERSION_TAG, VERSION_YEAR, eigenname, ESSID_LEN_MIN,
ESSID_LEN_MAX, ESSID_LEN_MIN, ESSID_LEN_MAX);

fprintf(stdout, "--authorized : filter EAPOL pairs by status


authorized (M2M3, M3M4, M1M4)\n"
"--challenge : filter EAPOL pairs by status CHALLENGE (M1M2,
M1M2ROGUE)\n"
"--rc : filter EAPOL pairs by replaycount status
checked\n"
"--rc-not : filter EAPOL pairs by replaycount status not
checked\n"
"--apless : filter EAPOL pairs by status M1M2ROGUE (M2
requested from CLIENT)\n"
"--info=<file> : output detailed information about content of
hash file\n"
" no filter options available\n"
"--info=stdout : stdout output detailed information about
content of hash file\n"
" no filter options available\n"
"--info-vendor=<file> : output detailed information about ACCESS
POINT and CLIENT VENDORs\n"
" no filter options available\n"
"--info-vendor-ap=<file> : output detailed information about ACCESS
POINT VENDORs\n"
" no filter options available\n"
"--info-vendor-client=<file> : output detailed information about CLIENT
VENDORs\n"
" no filter options available\n"
"--info-vendor=stdout : stdout output detailed information about
ACCESS POINT and CLIENT VENDORs\n"
" no filter options available\n"
"--info-vendor-ap=stdout : stdout output detailed information about
ACCESS POINT VENDORs\n"
" no filter options available\n"
"--info-vendor-client=stdout : stdout output detailed information about
CLIENT VENDORs\n"
" no filter options available\n"
"--psk=<PSK> : pre-shared key to test\n"
" due to PBKDF2 calculation this is a very slow
process\n"
" no nonce error corrections\n"
"--pmk=<PMK> : plain master key to test\n"
" no nonce error corrections\n"
"--hccapx=<file> : output to deprecated hccapx file\n"
"--hccap=<file> : output to ancient hccap file\n"
"--hccap-single : output to ancient hccap single files (MAC +
count)\n"
"--john=<file> : output to deprecated john file\n"
"--vendorlist : stdout output complete OUI list sorted by
OUI\n"
"--help : show this help\n"
"--version : show version\n"
"\n"
"Important notice:\n"
"%s does not do NONCE ERROR CORRECTIONS\n"
"in case of a packet loss, you get a wrong PTK\n",
eigenname);
exit(EXIT_SUCCESS);
}
/*---------------------------------------------------------------------------*/
__attribute__ ((noreturn))
static void usageerror(char *eigenname)
{
fprintf(stdout, "%s %s (C) %s by ZeroBeat\n"
"usage: %s -h for help\n", eigenname, VERSION_TAG, VERSION_YEAR, eigenname);
exit(EXIT_FAILURE);
}
/*===========================================================================*/
int main(int argc, char *argv[])
{
static int auswahl;
static int index;
static int l;
static int lcmin;
static int lcmax;
static int p1, p2;
static int hashtypein;
static int essidlenin;
static FILE *fh_pmkideapol;
static char *pbkdf2inname;
static char *pmkideapolinname;
static char *pmkideapoloutname;
static char *essidoutname;
static char *essidrawoutname;
static char *essidinname;
static char *macinname;
static char *macskipname;
static char *hccapxoutname;
static char *hccapoutname;
static char *johnoutname;
static char *infooutname;
static char *infovendoroutname;
static char *infovendorapoutname;
static char *infovendorclientoutname;
static char *ouiinstring;
static char *macinstring;
static char *pmkinstring;

static const char *short_options = "i:o:E:L:dp:hv";


static const struct option long_options[] =
{
{"type", required_argument, NULL, HCX_HASH_TYPE},
{"hcx-min", required_argument, NULL, HCX_HASH_MIN},
{"hcx-max", required_argument, NULL, HCX_HASH_MAX},
{"essid-min", required_argument, NULL, HCX_ESSID_MIN},
{"essid-group", no_argument, NULL, HCX_ESSID_GROUP},
{"essid-len", required_argument, NULL, HCX_ESSID_LEN},
{"essid-min", required_argument, NULL, HCX_ESSID_MIN},
{"essid-max", required_argument, NULL, HCX_ESSID_MAX},
{"essid", required_argument, NULL, HCX_FILTER_ESSID},
{"essid-part", required_argument, NULL,
HCX_FILTER_ESSID_PART},
{"essid-partx", required_argument, NULL,
HCX_FILTER_ESSID_PARTX},
{"essid-list", required_argument, NULL,
HCX_FILTER_ESSID_LIST_IN},
{"mac-ap", required_argument, NULL, HCX_FILTER_MAC_AP},
{"mac-client", required_argument, NULL,
HCX_FILTER_MAC_CLIENT},
{"mac-list", required_argument, NULL,
HCX_FILTER_MAC_LIST_IN},
{"mac-skiplist", required_argument, NULL,
HCX_FILTER_MAC_LIST_SKIP},
{"mac-group-ap", no_argument, NULL, HCX_MAC_GROUP_AP},
{"mac-group-client", no_argument, NULL,
HCX_MAC_GROUP_CLIENT},
{"oui-group", no_argument, NULL, HCX_OUI_GROUP},
{"oui-ap", required_argument, NULL, HCX_FILTER_OUI_AP},
{"oui-client", required_argument, NULL,
HCX_FILTER_OUI_CLIENT},
{"vendor", required_argument, NULL, HCX_FILTER_VENDOR},
{"vendor-ap", required_argument, NULL,
HCX_FILTER_VENDOR_AP},
{"vendor-client", required_argument, NULL,
HCX_FILTER_VENDOR_CLIENT},
{"rc", no_argument, NULL, HCX_FILTER_RC},
{"rc-not", no_argument, NULL, HCX_FILTER_RC_NOT},
{"authorized", no_argument, NULL, HCX_FILTER_M12},
{"challenge", no_argument, NULL, HCX_FILTER_M1234},
{"apless", no_argument, NULL, HCX_FILTER_M1M2ROGUE},
{"psk", required_argument, NULL, HCX_PSK},
{"pmk", required_argument, NULL, HCX_PMK},
{"info", required_argument, NULL, HCX_INFO_OUT},
{"info-vendor", required_argument, NULL,
HCX_INFO_VENDOR_OUT},
{"info-vendor-ap", required_argument, NULL,
HCX_INFO_VENDOR_AP_OUT},
{"info-vendor-client", required_argument, NULL,
HCX_INFO_VENDOR_CLIENT_OUT},
{"hccapx", required_argument, NULL, HCX_HCCAPX_OUT},
{"hccap", required_argument, NULL, HCX_HCCAP_OUT},
{"hccap-single", no_argument, NULL, HCX_HCCAP_SINGLE_OUT},
{"john", required_argument, NULL, HCX_JOHN_OUT},
{"vendorlist", no_argument, NULL, HCX_VENDOR_OUT},
{"version", no_argument, NULL, HCX_VERSION},
{"help", no_argument, NULL, HCX_HELP},
{NULL, 0, NULL, 0}
};

auswahl = -1;
index = 0;
optind = 1;
optopt = 0;
pbkdf2inname = NULL;
fh_pmkideapol = NULL;
pmkideapolinname = NULL;
pmkideapoloutname = NULL;
essidoutname = NULL;
essidrawoutname = NULL;
essidinname = NULL;
macinname = NULL;
macskipname = NULL;
infooutname = NULL;
infovendoroutname = NULL;
infovendorapoutname = NULL;
infovendorclientoutname = NULL;
hccapxoutname = NULL;
hccapoutname = NULL;
johnoutname = NULL;
ouiinstring = NULL;
macinstring = NULL;
pmkinstring = NULL;
filteressidptr = NULL;
filteressidpartptr = NULL;
filtervendorptr = NULL;
filtervendorapptr = NULL;
filtervendorclientptr = NULL;
flagfiltermacap = false;
flagfiltermacclient = false;
flagfilterouiap = false;
flagfilterouiclient = false;
flagfilterauthorized = false;
flagfilterchallenge = false;
flagfilterrcchecked = false;
flagfilterrcnotchecked = false;
flagfilterapless = false;
flagpsk = false;
flagpmk = false;
flagessidgroup = false;
flagmacapgroup = false;
flagmacclientgroup = false;
flagouigroup = false;
flagvendorout = false;
flaghccapsingleout = false;
caseflag = false;
hashtypein = 0;
hashtype = HCX_TYPE_PMKID | HCX_TYPE_EAPOL;
essidlenin = ESSID_LEN_MAX;
essidlen = ESSID_LEN_MAX;
essidlenmin = ESSID_LEN_MIN;
essidlenmax = ESSID_LEN_MAX;
lcmin = 0;
lcmax = 0;
statusflag = true;

while((auswahl = getopt_long (argc, argv, short_options, long_options, &index)) !=


-1)
{
switch (auswahl)
{
case HCX_PMKIDEAPOL_IN:
pmkideapolinname = optarg;
break;

case HCX_PMKIDEAPOL_OUT:
pmkideapoloutname = optarg;
break;

case HCX_ESSID_OUT:
essidoutname = optarg;
break;

case HCX_ESSID_RAW_OUT:
essidrawoutname = optarg;
break;

case HCX_VENDOR_OUT:
flagvendorout = true;
break;

case HCX_INFO_OUT:
infooutname = optarg;
break;
case HCX_INFO_VENDOR_OUT:
infovendoroutname = optarg;
break;

case HCX_INFO_VENDOR_AP_OUT:
infovendorapoutname = optarg;
break;

case HCX_INFO_VENDOR_CLIENT_OUT:
infovendorclientoutname = optarg;
break;

case HCX_ESSID_GROUP:
flagessidgroup = true;
break;

case HCX_HASH_TYPE:
hashtypein |= strtol(optarg, NULL, 10);
if((hashtypein < HCX_TYPE_PMKID) || (hashtypein > (HCX_TYPE_PMKID +
HCX_TYPE_EAPOL)))
{
fprintf(stderr, "only hash types 1 and 2 allowed (values 1, 2 or
3)\n");
exit(EXIT_FAILURE);
}
break;

case HCX_ESSID_LEN:
essidlenin = strtol(optarg, NULL, 10);
if((essidlenin < 0) || (essidlenin > ESSID_LEN_MAX))
{
fprintf(stderr, "only values 0...32 allowed\n");
exit(EXIT_FAILURE);
}
essidlenmin = essidlenin;
essidlenmax = essidlenin;
break;

case HCX_ESSID_MIN:
essidlenin = strtol(optarg, NULL, 10);
if((essidlenin < 0) || (essidlenin > ESSID_LEN_MAX))
{
fprintf(stderr, "only values 0...32 allowed\n");
exit(EXIT_FAILURE);
}
essidlenmin = essidlenin;
break;

case HCX_ESSID_MAX:
essidlenin = strtol(optarg, NULL, 10);
if((essidlenin < 0) || (essidlenin > ESSID_LEN_MAX))
{
fprintf(stderr, "only values 0...32 allowed\n");
exit(EXIT_FAILURE);
}
essidlenmax = essidlenin;
break;
case HCX_FILTER_ESSID:
filteressidptr = optarg;
filteressidlen = strlen(filteressidptr);
if((filteressidlen < 1) || (filteressidlen > ESSID_LEN_MAX))
{
fprintf(stderr, "only values 0...32 allowed\n");
exit(EXIT_FAILURE);
}
break;

case HCX_FILTER_ESSID_PART:
filteressidpartptr = optarg;
filteressidpartlen = strlen(filteressidpartptr);
if((filteressidpartlen < 1) || (filteressidpartlen > ESSID_LEN_MAX))
{
fprintf(stderr, "only values 0...32 allowed\n");
exit(EXIT_FAILURE);
}
caseflag = false;
break;

case HCX_FILTER_ESSID_PARTX:
filteressidpartptr = optarg;
filteressidpartlen = strlen(filteressidpartptr);
if((filteressidpartlen < 1) || (filteressidpartlen > ESSID_LEN_MAX))
{
fprintf(stderr, "only values 0...32 allowed\n");
exit(EXIT_FAILURE);
}
caseflag = true;
break;

case HCX_FILTER_ESSID_LIST_IN:
essidinname = optarg;
break;

case HCX_HASH_MIN:
lcmin = strtol(optarg, NULL, 10);
break;

case HCX_HASH_MAX:
lcmax = strtol(optarg, NULL, 10);
break;

case HCX_MAC_GROUP_AP:
flagmacapgroup = true;
break;

case HCX_MAC_GROUP_CLIENT:
flagmacclientgroup = true;
break;

case HCX_OUI_GROUP:
flagouigroup = true;
break;

case HCX_FILTER_OUI_AP:
l= strlen(optarg);
p2 = 0;
for(p1 = 0; p1 < l; p1++)
{
if(isxdigit((unsigned char)optarg[p1]))
{
optarg[p2] = optarg[p1];
p2++;
}
}
optarg[6] = 0;
ouiinstring = optarg;
if(getfield(ouiinstring, 3, filterouiap) != 3)
{
fprintf(stderr, "wrong OUI format\n");
exit(EXIT_FAILURE);
}
flagfilterouiap = true;
break;

case HCX_FILTER_MAC_AP:
l= strlen(optarg);
p2 = 0;
for(p1 = 0; p1 < l; p1++)
{
if(isxdigit((unsigned char)optarg[p1]))
{
optarg[p2] = optarg[p1];
p2++;
}
}
optarg[12] = 0;
macinstring = optarg;
if(getfield(macinstring, 6, filtermacap) != 6)
{
fprintf(stderr, "wrong MAC format $\n");
exit(EXIT_FAILURE);
}
flagfiltermacap = true;
break;

case HCX_FILTER_MAC_CLIENT:
l= strlen(optarg);
p2 = 0;
for(p1 = 0; p1 < l; p1++)
{
if(isxdigit((unsigned char)optarg[p1]))
{
optarg[p2] = optarg[p1];
p2++;
}
}
optarg[12] = 0;
macinstring = optarg;
if(getfield(macinstring, 6, filtermacclient) != 6)
{
fprintf(stderr, "wrong MAC format\n");
exit(EXIT_FAILURE);
}
flagfiltermacclient = true;
break;
case HCX_FILTER_MAC_LIST_IN:
macinname = optarg;
break;

case HCX_FILTER_MAC_LIST_SKIP:
macskipname = optarg;
break;

case HCX_FILTER_OUI_CLIENT:
l= strlen(optarg);
p2 = 0;
for(p1 = 0; p1 < l; p1++)
{
if(isxdigit((unsigned char)optarg[p1]))
{
optarg[p2] = optarg[p1];
p2++;
}
}
optarg[6] = 0;
ouiinstring = optarg;
if(getfield(ouiinstring, 3, filterouiclient) != 3)
{
fprintf(stderr, "wrong OUI format\n");
exit(EXIT_FAILURE);
}
flagfilterouiclient = true;
break;

case HCX_FILTER_VENDOR:
filtervendorptr = optarg;
l = strlen(filtervendorptr);
if(l < 3)
{
fprintf(stderr, "at least three characters of the VENDOR name are
mandatory\n");
exit(EXIT_FAILURE);
}
for(p1 = 0; p1 < l; p1++)
{
if(islower((unsigned char)filtervendorptr[p1]))
filtervendorptr[p1] = toupper((unsigned char)filtervendorptr[p1]);
}
break;

case HCX_FILTER_VENDOR_AP:
filtervendorapptr = optarg;
l = strlen(filtervendorapptr);
if(l < 3)
{
fprintf(stderr, "at least three characters of the VENDOR name are
mandatory\n");
exit(EXIT_FAILURE);
}
for(p1 = 0; p1 < l; p1++)
{
if(islower((unsigned char)filtervendorapptr[p1]))
filtervendorapptr[p1] = toupper((unsigned char)filtervendorapptr[p1]);
}
break;

case HCX_FILTER_VENDOR_CLIENT:
filtervendorclientptr = optarg;
l = strlen(filtervendorclientptr);
if(l < 3)
{
fprintf(stderr, "at least three characters of the VENDOR name are
mandatory\n");
exit(EXIT_FAILURE);
}
for(p1 = 0; p1 < l; p1++)
{
if(islower((unsigned char)filtervendorclientptr[p1]))
filtervendorclientptr[p1] = toupper((unsigned char)filtervendorclientptr[p1]);
}
break;

case HCX_FILTER_RC:
flagfilterrcchecked = true;
break;

case HCX_FILTER_RC_NOT:
flagfilterrcnotchecked = true;
break;

case HCX_FILTER_M12:
flagfilterauthorized = true;
break;

case HCX_FILTER_M1234:
flagfilterchallenge = true;
break;

case HCX_FILTER_M1M2ROGUE:
flagfilterapless = true;
break;

case HCX_PSK:
pskptr = optarg;
pskptrlen = strlen(pskptr);
if((pskptrlen < 0) || (pskptrlen > 63))
{
fprintf(stderr, "only 0...63 characters allowed\n");
exit(EXIT_FAILURE);
}
flagpsk = true;
break;

case HCX_PMK:
pmkinstring = optarg;
if(getfield(pmkinstring, 32, pmk) != 32)
{
fprintf(stderr, "wrong PMK length \n");
exit(EXIT_FAILURE);
}
flagpmk = true;
break;
case HCX_DOWNLOAD_OUI:
downloadoui();
break;

case HCX_PBKDF2_IN:
// pbkdf2inname = optarg;
break;

case HCX_HCCAPX_OUT:
hccapxoutname = optarg;
break;

case HCX_HCCAP_OUT:
hccapoutname = optarg;
break;

case HCX_HCCAP_SINGLE_OUT:
flaghccapsingleout = true;
break;

case HCX_JOHN_OUT:
johnoutname = optarg;
break;

case HCX_HELP:
usage(basename(argv[0]));
break;

case HCX_VERSION:
version(basename(argv[0]));
break;

case '?':
usageerror(basename(argv[0]));
break;
}
}

if(essidlenmin > essidlenmax)


{
fprintf(stderr, "minimum ESSID length is > maximum ESSID length\n");
exit(EXIT_FAILURE);
}

if(argc < 2)
{
fprintf(stderr, "no option selected\n");
return EXIT_SUCCESS;
}

if(initlists() == false) exit(EXIT_FAILURE);


if(pbkdf2inname != NULL) readbpkdf2file(pbkdf2inname);
if((infooutname != NULL) || (infovendoroutname != NULL) || (infovendorapoutname !=
NULL) || (infovendorclientoutname != NULL))
{
filtervendorptr = NULL;
filtervendorapptr = NULL;
filtervendorclientptr = NULL;
}
readoui();
if((ouicount > 0) && (flagvendorout == true))
{
showvendorlist();
printstatus();
closelists();
return EXIT_SUCCESS;
}
if(pmkideapolinname != NULL)
{
if((fh_pmkideapol = fopen(pmkideapolinname, "r")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", pmkideapolinname,
strerror(errno));
closelists();
exit(EXIT_FAILURE);
}
}
if(fh_pmkideapol != NULL) readpmkideapolfile(fh_pmkideapol);

if(pmkideapolcount == 0)
{
fprintf(stdout, "no hashes loaded\n");
if(fh_pmkideapol != NULL) fclose(fh_pmkideapol);
closelists();
return EXIT_SUCCESS;
}

if(essidrawoutname != 0) processessidraw(essidrawoutname);

if(infooutname != NULL)
{
writeinfofile(infooutname);
if(fh_pmkideapol != NULL) fclose(fh_pmkideapol);
closelists();
return EXIT_SUCCESS;
}

if(infovendoroutname != NULL)
{
writevendorapinfofile(infovendoroutname);
writevendorclientinfofile(infovendoroutname);
if(fh_pmkideapol != NULL) fclose(fh_pmkideapol);
closelists();
return EXIT_SUCCESS;
}
else if(infovendorapoutname != NULL)
{
writevendorapinfofile(infovendorapoutname);
if(fh_pmkideapol != NULL) fclose(fh_pmkideapol);
closelists();
return EXIT_SUCCESS;
}
else if(infovendorclientoutname != NULL)
{
writevendorclientinfofile(infovendorclientoutname);
if(fh_pmkideapol != NULL) fclose(fh_pmkideapol);
closelists();
return EXIT_SUCCESS;
}

if(macskipname != NULL) removepmkideapol(macskipname);

if(hashtypein > 0) hashtype = hashtypein;

if(essidoutname != NULL) processessid(essidoutname);


if((pmkideapoloutname != NULL) && (essidinname == NULL))
{
if((lcmin == 0) && (lcmax == 0)) writeeapolpmkidfile(pmkideapoloutname);
else writelceapolpmkidfile(pmkideapoloutname, lcmin, lcmax);
}
if(flagessidgroup == true) writeeapolpmkidessidgroups();
if(flagmacapgroup == true) writeeapolpmkidmacapgroups();
if(flagmacclientgroup == true) writeeapolpmkidmacclientgroups();
if(flagouigroup == true) writeeapolpmkidouigroups();
if(flagpsk == true) testhashfilepsk();
if(flagpmk == true) testhashfilepmk();
if(hccapxoutname != NULL) writehccapxfile(hccapxoutname);
if(hccapoutname != NULL) writehccapfile(hccapoutname);
if(flaghccapsingleout == true) writehccapsinglefile();
if(johnoutname != NULL) writejohnfile(johnoutname);
if((pmkideapoloutname != NULL) && (essidinname != NULL))
processessidfile(essidinname, pmkideapoloutname);
if(macinname != NULL) processmacfile(macinname, pmkideapoloutname);

if(statusflag == true) printstatus();


if(fh_pmkideapol != NULL) fclose(fh_pmkideapol);
closelists();
return EXIT_SUCCESS;
}
/*===========================================================================*/

You might also like