Hcxpcapngtool
Hcxpcapngtool
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <inttypes.h>
#include <libgen.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <time.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 <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/hcxpcapngtool.h"
#include "include/ieee80211.c"
#include "include/strings.c"
#include "include/byteops.c"
#include "include/fileops.c"
#include "include/hashops.c"
#include "include/pcap.c"
#include "include/gzops.c"
/*===========================================================================*/
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))
/*===========================================================================*/
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))
/*===========================================================================*/
/*===========================================================================*/
/* global var */
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];
handshakelistmax = HANDSHAKELIST_MAX;
if((handshakelist = (handshakelist_t*)calloc((handshakelistmax +1),
HANDSHAKELIST_SIZE)) == NULL) return false;
handshakelistptr = handshakelist;
pmkidlistmax = PMKIDLIST_MAX;
if((pmkidlist = (pmkidlist_t*)calloc((pmkidlistmax +1),PMKIDLIST_SIZE)) == NULL)
return false;
pmkidlistptr = pmkidlist;
eapmd5hashlistmax = EAPMD5HASHLIST_MAX;
if((eapmd5hashlist = (eapmd5hashlist_t*)calloc((eapmd5hashlistmax +1),
EAPMD5HASHLIST_SIZE)) == NULL) return false;
eapmd5hashlistptr = eapmd5hashlist;
eapleaphashlistmax = EAPLEAPHASHLIST_MAX;
if((eapleaphashlist = (eapleaphashlist_t*)calloc((eapleaphashlistmax +1),
EAPLEAPHASHLIST_SIZE)) == NULL) return false;
eapleaphashlistptr = eapleaphashlist;
eapmschapv2hashlistmax = EAPMSCHAPV2HASHLIST_MAX;
if((eapmschapv2hashlist = (eapmschapv2hashlist_t*)calloc((eapmschapv2hashlistmax
+1), EAPMSCHAPV2HASHLIST_SIZE)) == NULL) return false;
eapmschapv2hashlistptr = eapmschapv2hashlist;
tacacsplistmax = TACACSPLIST_MAX;
if((tacacsplist = (tacacsplist_t*)calloc((TACACSPLIST_MAX +1), TACACSPLIST_SIZE))
== NULL) return false;
tacacsplistptr = tacacsplist;
memset(&pcapnghwinfo, 0, OPTIONLEN_MAX);
memset(&pcapngosinfo, 0, OPTIONLEN_MAX);
memset(&pcapngapplinfo, 0, OPTIONLEN_MAX);
memset(&pcapngoptioninfo, 0, OPTIONLEN_MAX);
memset(&pcapngweakcandidate, 0 ,OPTIONLEN_MAX);
memset(&pcapngdeviceinfo, 0 ,6);
pcapngtimeresolution = TSRESOL_USEC;
memset(&myaktap, 0 ,6);
memset(&myaktclient, 0 ,6);
memset(&nmeasentence, 0, OPTIONLEN_MAX);
memset(&gpwplold, 0, OPTIONLEN_MAX);
memcpy(&pcapnghwinfo, nastring, 3);
memcpy(&pcapngosinfo, nastring, 3);
memcpy(&pcapngapplinfo, nastring, 3);
memcpy(&pcapngoptioninfo, nastring, 3);
memcpy(&pcapngweakcandidate, nastring, 3);
ieee80211flag = false;
radiotaperrorcount = 0;
nmeacount = 0;
nmeaerrorcount = 0;
endianness = 0;
rawpacketcount = 0;
pcapreaderrors = 0;
skippedpacketcount = 0;
zeroedtimestampcount = 0;
fcsframecount = 0;
band24count = 0;
band5count = 0;
band6count = 0;
wdscount = 0;
actioncount = 0;
actionessidcount = 0;
awdlcount = 0;
beaconcount = 0;
beaconssidunsetcount = 0;
beaconssidzeroedcount = 0;
beaconssidoversizedcount = 0;
beaconhcxcount = 0;
beaconerrorcount = 0;
broadcastmacerrorcount = 0;
pagcount = 0;
proberesponsecount = 0;
proberesponsessidunsetcount = 0;
proberesponsessidzeroedcount = 0;
proberequestundirectedcount = 0;
proberequestdirectedcount = 0;
mgtreservedcount = 0;
deauthenticationcount = 0;
disassociationcount = 0;
authenticationcount = 0;
authopensystemcount = 0;
authseacount = 0;
authsharedkeycount = 0;
authfbtcount = 0;
authfilscount = 0;
authfilspfs = 0;
authfilspkcount = 0;
authnetworkeapcount = 0;
authunknowncount = 0;
associationrequestcount = 0;
associationrequestpskcount = 0;
associationrequestftpskcount = 0;
associationrequestpsk256count = 0;
associationrequestsae256count = 0;
associationrequestsae384bcount = 0;
associationrequestowecount = 0;
reassociationrequestcount = 0;
reassociationrequestpskcount = 0;
reassociationrequestpsk256count = 0;
reassociationrequestsae256count = 0;
reassociationrequestsae384bcount = 0;
reassociationrequestowecount = 0;
ipv4count = 0;
icmp4count = 0;
ipv6count = 0;
icmp6count = 0;
tcpcount = 0;
udpcount = 0;
grecount = 0;
protochapcount = 0;
protochapreqcount = 0;
protochaprespcount = 0;
protochapsuccesscount = 0;
protopapcount = 0;
tacacspcount = 0;
tacacsp2count = 0;
tacacsp3count = 0;
tacacspwrittencount = 0;
wepenccount = 0;
wpaenccount = 0;
eapcount = 0;
eapsimcount = 0;
eapakacount = 0;
eappeapcount = 0;
eapmd5count = 0;
eapmd5hashcount = 0;
eapleapcount = 0;
eapleaphashcount = 0;
eapmschapv2count = 0;
eapmschapv2hashcount = 0;
eaptlscount = 0;
eapexpandedcount = 0;
eapidcount = 0;
eapcodereqcount = 0;
eapcoderespcount = 0;
radiusrequestcount = 0;
radiuschallengecount = 0;
radiusacceptcount = 0;
radiusrejectcount = 0;
zeroedpmkidpskcount = 0;
zeroedpmkidpmkcount = 0;
zeroedeapolpskcount = 0;
zeroedeapolpmkcount = 0;
pmkidcount = 0;
pmkidbestcount = 0;
pmkidroguecount = 0;
pmkiduselesscount = 0;
pmkidakmcount = 0;
pmkidwrittenhcount = 0;
pmkidclientwrittenhcount = 0;
eapolwrittenjcountdeprecated = 0;
pmkidwrittenjcountdeprecated = 0;
pmkidwrittencountdeprecated = 0;
eapolrc4count = 0;
eapolrsncount = 0;
eapolwpacount = 0;
eapolmsgcount = 0;
eapolnccount = 0;
eapolmsgerrorcount = 0;
eapolmsgtimestamperrorcount = 0;
eapolmpbestcount = 0;
eapolmpcount = 0;
eapolm1count = 0;
eapolm1kdv0count = 0;
eapolm1ancount = 0;
eapolm1errorcount = 0;
eapolm2count = 0;
eapolm2kdv0count = 0;
eapolm2ftpskcount = 0;
eapolm2errorcount = 0;
eapolm3count = 0;
eapolm3kdv0count = 0;
eapolm3errorcount = 0;
eapolm4count = 0;
eapolm4zeroedcount = 0;
eapolm4kdv0count = 0;
eapolm4errorcount = 0;
eapolwrittencount = 0;
eapolncwrittencount = 0;
eapolaplesscount = 0;
eapolwrittenjcountdeprecated = 0;
eapolwrittenhcpxcountdeprecated = 0;
eapolwrittenhcpcountdeprecated = 0;
eapolm12e2count = 0;
eapolm14e4count = 0;
eapolm32e2count = 0;
eapolm32e3count = 0;
eapolm34e3count = 0;
eapolm34e4count = 0;
eapmd5writtencount = 0;
eapmd5johnwrittencount = 0;
eapleapwrittencount = 0;
eapmschapv2writtencount = 0;
identitycount = 0;
usernamecount = 0;
taglenerrorcount = 0;
essidcount = 0;
essiderrorcount = 0;
deviceinfocount = 0;
sequenceerrorcount = 0;
essiddupemax = 0;
rcgapmax = 0;
eaptimegapmax = 0;
malformedcount = 0;
timestampmin = 0;
timestampmax = 0;
timestampstart = 0;
captimestampold = 0;
memset(&zeroedpsk, 0, 8);
memset(&zeroedpmk, 0, 32);
memset(&beaconchannel, 0, sizeof(beaconchannel));
memset(&usedfrequency, 0, sizeof(usedfrequency));
return true;
}
/*===========================================================================*/
static void printcontentinfo(void)
{
static int c;
static uint8_t i;
static uint16_t p;
if(donotcleanflag == false)
{
if(eapolmpbestcount > 0) fprintf(stdout, "EAPOL pairs
(best).......................: %ld\n", eapolmpbestcount);
}
else
{
if(eapolmpbestcount > 0) fprintf(stdout, "EAPOL pairs
(useful).....................: %ld\n", eapolmpbestcount);
}
if(eapolaplesscount > 0) fprintf(stdout, "EAPOL ROGUE
pairs........................: %ld\n", eapolaplesscount);
if(eapolwrittencount > 0) fprintf(stdout, "EAPOL pairs written to 22000
hash file...: %ld (RC checked)\n", eapolwrittencount);
if(eapolncwrittencount > 0) fprintf(stdout, "EAPOL pairs written to 22000
hash file...: %ld (RC not checked)\n", eapolncwrittencount);
if(eapolwrittenhcpxcountdeprecated > 0) fprintf(stdout, "EAPOL pairs written to
old format hccapx.: %ld (RC checked)\n", eapolwrittenhcpxcountdeprecated);
if(eapolncwrittenhcpxcountdeprecated > 0) fprintf(stdout, "EAPOL pairs written to
old format hccapx.: %ld (RC not checked)\n", eapolncwrittenhcpxcountdeprecated);
if(eapolwrittenhcpcountdeprecated > 0) fprintf(stdout, "EAPOL pairs written to
old format hccap..: %ld (RC checked)\n", eapolwrittenhcpcountdeprecated);
if(eapolwrittenjcountdeprecated > 0) fprintf(stdout, "EAPOL pairs written to
old format JtR....: %ld (RC checked)\n", eapolwrittenjcountdeprecated);
if(eapolm12e2count > 0) fprintf(stdout, "EAPOL M12E2
(challenge)..................: %ld\n", eapolm12e2count);
if(eapolm14e4count > 0) fprintf(stdout, "EAPOL M14E4
(authorized).................: %ld\n", eapolm14e4count);
if(eapolm32e2count > 0) fprintf(stdout, "EAPOL M32E2
(authorized).................: %ld\n", eapolm32e2count);
if(eapolm32e3count > 0) fprintf(stdout, "EAPOL M32E3
(authorized).................: %ld\n", eapolm32e3count);
if(eapolm34e3count > 0) fprintf(stdout, "EAPOL M34E3
(authorized).................: %ld\n", eapolm34e3count);
if(eapolm34e4count > 0) fprintf(stdout, "EAPOL M34E4
(authorized).................: %ld\n", eapolm34e4count);
if(pmkiduselesscount > 0) fprintf(stdout, "RSN PMKID
(useless)......................: %ld\n", pmkiduselesscount);
if(pmkidcount > 0) fprintf(stdout, "RSN PMKID
(total)........................: %ld\n", pmkidcount);
if(zeroedpmkidpskcount > 0) fprintf(stdout, "RSN PMKID (from zeroed
PSK)..............: %ld (not converted by default options - use --all if needed)\
n", zeroedpmkidpskcount);
if(zeroedpmkidpmkcount > 0) fprintf(stdout, "RSN PMKID (from zeroed
PMK)..............: %ld (not converted by default options - use --all if needed)\
n", zeroedpmkidpmkcount);
if(donotcleanflag == false)
{
if(pmkidbestcount > 0) fprintf(stdout, "RSN PMKID
(best).........................: %ld\n", pmkidbestcount);
}
else
{
if(pmkidbestcount > 0) fprintf(stdout, "RSN PMKID
(useful).......................: %ld\n", pmkidbestcount);
}
if(pmkidroguecount > 0) fprintf(stdout, "RSN PMKID
ROGUE..........................: %ld\n", pmkidroguecount);
if(pmkidakmcount > 0) fprintf(stdout, "RSN PMKID (KDV:0 AKM
defined)............: %ld (PMK not recoverable)\n", pmkidakmcount);
if(pmkidwrittenhcount > 0) fprintf(stdout, "RSN PMKID written to 22000
hash file.....: %ld\n", pmkidwrittenhcount);
if(pmkidclientwrittenhcount > 0) fprintf(stdout, "RSN PMKID written to 22000
hash file.....: %ld (possible MESH/REPEATER PMKIDs)\n", pmkidclientwrittenhcount);
if(pmkidwrittenjcountdeprecated > 0) fprintf(stdout, "RSN PMKID written to old
format JtR......: %ld\n", pmkidwrittenjcountdeprecated);
if(pmkidwrittencountdeprecated > 0) fprintf(stdout, "RSN PMKID written to old
format (1680x)..: %ld\n", pmkidwrittencountdeprecated);
if(pcapreaderrors > 0) fprintf(stdout, "packet read
error........................: %ld\n", pcapreaderrors);
if(radiotaperrorcount > 0) fprintf(stdout, "packet with damaged radiotap
header......: %ld\n", radiotaperrorcount);
if(zeroedtimestampcount > 0) fprintf(stdout, "packets with zeroed
timestamps...........: %ld\n", zeroedtimestampcount);
if(eapolmsgtimestamperrorcount > 0) fprintf(stdout, "EAPOL frames with wrong
timestamp........: %ld\n", eapolmsgtimestamperrorcount);
malformedcount = beaconerrorcount +broadcastmacerrorcount +taglenerrorcount
+essiderrorcount +eapolmsgerrorcount;
if(malformedcount > 0) fprintf(stdout, "malformed packets
(total)................: %ld\n", malformedcount);
beaconerrorcount += broadcastmacerrorcount;
if(beaconerrorcount > 0) fprintf(stdout, "BEACON error (total malformed
packets)...: %ld\n", beaconerrorcount);
if(broadcastmacerrorcount > 0) fprintf(stdout, "BROADCAST MAC error
(malformed packets)..: %ld\n", broadcastmacerrorcount);
if(taglenerrorcount > 0) fprintf(stdout, "IE TAG length error (malformed
packets)..: %ld\n", taglenerrorcount);
if(essiderrorcount > 0) fprintf(stdout, "ESSID error (malformed
packets)..........: %ld\n", essiderrorcount);
eapolmsgerrorcount = eapolmsgerrorcount +eapolm1errorcount +eapolm2errorcount
+eapolm3errorcount +eapolm4errorcount;
if(eapolmsgerrorcount > 0) fprintf(stdout, "EAPOL messages (malformed
packets).......: %ld\n", eapolmsgerrorcount);
if(radiotappresent == true)
{
c = 0;
fprintf(stdout, "\nfrequency statistics from radiotap header (frequency:
received packets)\n"
"----------------------------------------------------------------
-------\n");
for(p = 2412; p <= 7115; p ++)
{
if(usedfrequency[p] != 0)
{
fprintf(stdout, "% 5d: %d\t", p, usedfrequency[p]);
c++;
if((c %4) == 0) fprintf(stdout, "\n");
}
}
fprintf(stdout, "\n");
}
if(zeroedtimestampcount > 0)
{
fprintf(stdout, "\nWarning: missing timestamps!\n"
"This dump file contains frames with zeroed timestamps.\n"
"It prevent calculation of EAPOL TIMEOUT values.\n"
"That is a bug of the capturing/cleaning.\n");
}
if(eapolmsgtimestamperrorcount > 0)
{
fprintf(stdout, "\nWarning: wrong timestamps!\n"
"This dump file contains frames with wrong timestamps.\n"
"It prevent calculation of EAPOL TIMEOUT values.\n"
"That is a bug of the capturing/cleaning tool.\n");
}
if(sequenceerrorcount > 0)
{
fprintf(stdout, "\nWarning: out of sequence timestamps!\n"
"This dump file contains frames with out of sequence timestamps.\n"
"That is a bug of the capturing/cleaning tool.\n");
}
if(ancientdumpfileformat == true)
{
fprintf(stdout, "\nInformation: limited dump file format detected!\n"
"This file format is a very basic format to save captured network
data.\n"
"It is recommended to use PCAP Next Generation dump file format (or
pcapng for short) instead.\n"
"The PCAP Next Generation dump file format is an attempt to overcome
the limitations\n"
"of the currently widely used (but very limited) libpcap (cap, pcap)
format.\n"
"https://www.wireshark.org/docs/wsug_html_chunked/AppFiles.html#ChAppFilesCaptureFi
lesSection\n"
"https://github.com/pcapng/pcapng\n");
}
if(ieee80211flag == false)
{
fprintf(stdout, "\n");
return;
}
if(radiotappresent == false)
{
fprintf(stdout, "\nInformation: radiotap header is missing!\n"
"Radiotap is a de facto standard for 802.11 frame injection and\n"
"reception. The radiotap header format is a mechanism to supply\n"
"additional information about frames, rom the driver to userspace\n"
"applications.\n"
"https://www.radiotap.org/\n");
}
if(magicblockcount > 1)
{
fprintf(stdout, "\nWarning: this dump file contains more than one custom
block!\n"
"This always happens if dump files are merged!\n"
"Do not merge dump files, because this destroys assigned hash values!\
n");
}
if(((deauthenticationcount +disassociationcount) >= 100) && ((deauthenticationcount
+disassociationcount) <= 10000))
{
fprintf(stdout, "\nWarning: too many deauthentication/disassociation frames
detected!\n"
"That can cause that an ACCESS POINT change channel, reset EAPOL
TIMER,\n"
"renew ANONCE and set PMKID to zero.\n"
"This could prevent to calculate a valid EAPOL MESSAGE PAIR\n"
"or to get a valid PMKID.\n");
}
if((deauthenticationcount +disassociationcount) > 10000)
{
fprintf(stdout, "\nWarning: excessive number of
deauthentication/disassociation frames detected!\n"
"That can cause that an ACCESS POINT change channel, reset EAPOL
TIMER,\n"
"renew ANONCE and set PMKID to zero.\n"
"This could prevent to calculate a valid EAPOL MESSAGE PAIR\n"
"or to get a valid PMKID.\n");
}
if(((beaconcount + proberesponsecount) == 0) && ((associationrequestcount +
reassociationrequestcount) == 0))
{
fprintf(stdout, "\nInformation: missing frames!\n"
"This dump file does not contain BEACON or PROBERESPONSE frames.\n"
"This frames contain the ESSID which is mandatory to calculate a PMK.\
n"
"It always happens if the capture file was cleaned or\n"
"it could happen if filter options are used during capturing.\n"
"That makes it impossible to recover the PSK.\n");
}
if(proberequestundirectedcount == 0)
{
fprintf(stdout, "\nInformation: missing frames!\n"
"This dump file does not contain undirected proberequest frames.\n"
"An undirected proberequest may contain information about the PSK.\n"
"It always happens if the capture file was cleaned or\n"
"it could happen if filter options are used during capturing.\n"
"That makes it hard to recover the PSK.\n");
}
if((authenticationcount +associationrequestcount +reassociationrequestcount) == 0)
{
fprintf(stdout, "\nInformation: missing frames!\n"
"This dump file does not contain important frames like\n"
"authentication, association or reassociation.\n"
"It always happens if the capture file was cleaned or\n"
"it could happen if filter options are used during capturing.\n"
"That makes it hard to recover the PSK.\n");
}
if(eapolm1ancount <= 1)
{
fprintf(stdout, "\nInformation: missing frames!\n"
"This dump file does not contain enough EAPOL M1 frames.\n"
"It always happens if the capture file was cleaned or\n"
"it could happen if filter options are used during capturing.\n"
"That makes it impossible to calculate nonce-error-correction values.\
n");
}
if((eapolm1count + eapolm2count + eapolm4count > 0) && (eapolm3count == 0))
{
fprintf(stdout, "\nInformation: missing EAPOL M3 frames!\n"
"This dump file does not contain EAPOL M3 frames (possible packet
loss).\n"
"It strongly recommended to recapture the traffic or\n"
"to use --all option to convert all possible EAPOL MESSAGE PAIRs.\n");
}
if(malformedcount > 5)
{
fprintf(stdout, "\nInformation: malformed packets detected!\n"
"In monitor mode the adapter does not check to see if the cyclic
redundancy check (CRC)\n"
"values are correct for packets captured. The device is able to detect
the Physical Layer\n"
"Convergence Procedure (PLCP) preamble and is able to synchronize to
it, but if there is\n"
"a bit error in the payload it can lead to unexpected results.\n"
"Please analyze the dump file with tshark or Wireshark or make a better
capture!\n");
}
if((eapolwrittencount +eapolncwrittencount +eapolwrittenhcpxcountdeprecated
+eapolncwrittenhcpxcountdeprecated +eapolwrittenhcpcountdeprecated
+eapolwrittenjcountdeprecated +pmkidwrittenhcount
+pmkidwrittenjcountdeprecated +pmkidwrittencountdeprecated
+eapmd5writtencount +eapmd5johnwrittencount +eapleapwrittencount
+eapmschapv2writtencount +tacacspwrittencount) == 0)
{
fprintf(stdout, "\nInformation: no hashes written to hash files\n");
}
fprintf(stdout, "\n");
return;
}
/*===========================================================================*/
static void printlinklayerinfo(void)
{
static uint32_t c;
static time_t tvmin;
static time_t tvmax;
static char timestringmin[32];
static char timestringmax[32];
radiotappresent = false;
tvmin = timestampmin /1000000000;
strftime(timestringmin, 32, "%d.%m.%Y %H:%M:%S", localtime(&tvmin));
tvmax = timestampmax /1000000000;
strftime(timestringmax, 32, "%d.%m.%Y %H:%M:%S", localtime(&tvmax));
fprintf(stdout, "timestamp minimum (GMT)..................: %s\n", timestringmin);
fprintf(stdout, "timestamp maximum (GMT)..................: %s\n", timestringmax);
fprintf(stdout, "used capture interfaces..................: %d\n", iface);
for(c = 0; c < iface; c++)
{
if(c > 0)
{
if(dltlinktype[c] == dltlinktype[c -1]) continue;
}
if(dltlinktype[c] == DLT_IEEE802_11_RADIO)
{
fprintf(stdout, "link layer header type...................:
DLT_IEEE802_11_RADIO (%d)\n", dltlinktype[c]);
radiotappresent = true;
}
else if(dltlinktype[c] == DLT_IEEE802_11) fprintf(stdout, "link layer
header type...................: DLT_IEEE802_11 (%d) very basic format without any
additional information about the quality\n", dltlinktype[c]);
else if(dltlinktype[c] == DLT_PPI) fprintf(stdout, "link layer
header type...................: DLT_PPI (%d)\n", dltlinktype[c]);
else if(dltlinktype[c] == DLT_PRISM_HEADER) fprintf(stdout, "link
layer header type...................: DLT_PRISM_HEADER (%d)\n", dltlinktype[c]);
else if(dltlinktype[c] == DLT_IEEE802_11_RADIO_AVS) fprintf(stdout, "link
layer header type...................: DLT_IEEE802_11_RADIO_AVS (%d)\n",
dltlinktype[c]);
else if(dltlinktype[c] == DLT_EN10MB) fprintf(stdout, "link
layer header type...................: DLT_EN10MB (%d)\n", dltlinktype[c]);
else if(dltlinktype[c] == DLT_NULL) fprintf(stdout, "link layer
header type...................: DLT_NULL (BSD LO) (%d)\n", dltlinktype[c]);
}
return;
}
/*===========================================================================*/
static void outputwordlists(void)
{
static int wecl;
static maclist_t *zeigermac, *zeigermacold;
zeigermacold = NULL;
qsort(aplist, aplistptr -aplist, MACLIST_SIZE, sort_maclist_by_essidlen);
wecl = strlen(pcapngweakcandidate);
if((wecl > 0) && (wecl < 64) && (strcmp(pcapngweakcandidate, "N/A") != 0))
{
if(fh_essid != NULL) fprintf(fh_essid, "%s\n", pcapngweakcandidate);
}
for(zeigermac = aplist; zeigermac < aplistptr; zeigermac++)
{
if((zeigermacold != NULL) && (zeigermac->essidlen == zeigermacold->essidlen))
{
if(memcmp(zeigermac->essid, zeigermacold->essid, zeigermac->essidlen)
== 0) continue;
}
if(fh_essid != NULL) fwriteessidstr(zeigermac->essidlen, zeigermac->essid,
fh_essid);
if((fh_essidproberequest != NULL) && (zeigermac->status == ST_PROBE_REQ))
fwriteessidstr(zeigermac->essidlen, zeigermac->essid, fh_essidproberequest);
if((fh_essidproberequest != NULL) && (zeigermac->status == ST_ACT_MR_REQ))
fwriteessidstr(zeigermac->essidlen, zeigermac->essid, fh_essidproberequest);
essidcount++;
zeigermacold = zeigermac;
}
return;
}
/*===========================================================================*/
static void outputdeviceinfolist(void)
{
static int p;
static maclist_t *zeigermac;
if(tags->essidlen == 0) return;
if(tags->essid[0] == 0) return;
tvo = timestamp /1000000000;
strftime(timestring, 24, "%Y-%m-%d\t%H:%M:%S", gmtime(&tvo));
if((tags->essidlen != 0) && (tags->essid[0] != 0)) fprintf(fh_csv, "%s\t%02x:%02x:
%02x:%02x:%02x:%02x\t%.*s\t", timestring, mac[0], mac[1], mac[2], mac[3], mac[4],
mac[5], tags->essidlen, tags->essid);
else fprintf(fh_csv, "%s\t%02x:%02x:%02x:%02x:%02x:%02x\t<HIDDEN ESSID>\t",
timestring, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
if(tags->kdversion == 0) fprintf(fh_csv, "OPEN");
if((tags->kdversion & KV_WPAIE) == KV_WPAIE) fprintf(fh_csv, "[WPA1]");
if((tags->kdversion & KV_RSNIE) == KV_RSNIE) fprintf(fh_csv, "[WPA2]");
fprintf(fh_csv, "\t");
if((tags->cipher & TCS_TKIP) == TCS_TKIP) fprintf(fh_csv, "[TKIP]");
if((tags->cipher & TCS_CCMP) == TCS_CCMP) fprintf(fh_csv, "[CCMP]");
if((tags->cipher & TCS_WEP40) == TCS_WEP40) fprintf(fh_csv, "[WEP40]");
if((tags->cipher & TCS_WEP104) == TCS_WEP104) fprintf(fh_csv, "[WEP104]");
if((tags->cipher & TCS_WRAP) == TCS_WRAP) fprintf(fh_csv, "[WRAP]");
if((tags->cipher & TCS_BIP) == TCS_BIP) fprintf(fh_csv, "[BIP]");
if((tags->cipher & TCS_NOT_ALLOWED) == TCS_NOT_ALLOWED) fprintf(fh_csv,
"[NOT_ALLOWED]");
fprintf(fh_csv, "\t");
if((tags->akm & TAK_PSK) == TAK_PSK) fprintf(fh_csv, "[PSK]");
if((tags->akm & TAK_PSKSHA256) == TAK_PSKSHA256) fprintf(fh_csv, "[PSK_SHA256]");
if((tags->akm & TAK_PMKSA) == TAK_PMKSA) fprintf(fh_csv, "[PMKSA]");
if((tags->akm & TAK_PMKSA256) == TAK_PMKSA256) fprintf(fh_csv, "[PMKSA_SHA256]");
if((tags->akm & TAK_FT) == TAK_FT) fprintf(fh_csv, "[FT]");
if((tags->akm & TAK_FT_PSK) == TAK_FT_PSK) fprintf(fh_csv, "[FT_PSK]");
if((tags->akm & TAK_FT_SAE) == TAK_FT_SAE) fprintf(fh_csv, "[FT_SAE]");
if((tags->akm & TAK_TDLS) == TAK_TDLS) fprintf(fh_csv, "[TDLS]");
if((tags->akm & TAK_SAE_SHA256) == TAK_SAE_SHA256) fprintf(fh_csv, "[SAE_SHA256]");
if((tags->akm & TAK_SAE_SHA256B) == TAK_SAE_SHA256B) fprintf(fh_csv,
"[SAE_SHA256B]");
if((tags->akm & TAK_SAE_SHA384B) == TAK_SAE_SHA384B) fprintf(fh_csv,
"[SAE_SHA384B]");
if((tags->akm & TAK_AP_PKA) == TAK_AP_PKA) fprintf(fh_csv, "[AP_PKA]");
if((tags->akm & TAK_OWE) == TAK_OWE) fprintf(fh_csv, "[OWE]");
fprintf(fh_csv, "\t");
if((tags->country[0] >= 'A') && (tags->country[0] <= 'Z') && (tags->country[1] >=
'A') && (tags->country[1] <= 'Z')) fprintf(fh_csv,"%c%c\t", tags->country[0], tags-
>country[1]);
else fprintf(fh_csv,"00\t");
if(tags->channel != 0) fprintf(fh_csv,"%d\t", tags->channel);
else fprintf(fh_csv,"%d\t", interfacechannel);
fprintf(fh_csv, "%d\t", rssi);
p = 7;
c = 0;
latitude = 0;
longitude = 0;
ew = 'E';
ns = 'S';
latm = 0;
lonm = 0;
fix = 0;
satcount = 0;
hdop = 0;
altitude = 0;
altunit = 'M';
if(nmealen < 48)
{
fprintf(fh_csv, "%f\t%c\t%f\t%c\t%f\t%f\t%d\t%d\t%f\t%f\t%c\n", latitude, ew,
longitude, ns, latm, lonm, fix, satcount, hdop, altitude, altunit);
return;
}
if(memcmp(&gpgga, nmeasentence, 6) == 0)
{
while((nmeasentence[p] != 0) && (c < 1))
{
if(nmeasentence[p] == ',') c++;
p++;
}
sscanf(&nmeasentence[p],"%f,%c,%f,%c,%d,%d,%f,%f,%c", &latitude, &ew,
&longitude, &ns, &fix, &satcount, &hdop, &altitude, &altunit);
if(latitude != 0) latm = ((int)latitude) /100 + (((int)latitude) %100
+latitude -(int)latitude)/60;
if(longitude != 0) lonm = ((int)longitude) /100 + (((int)longitude) %100
+longitude -(int)longitude)/60;
if(ew == 'W') latm =-latm;
if(ns == 'S') lonm =-lonm;
fprintf(fh_csv, "%f\t%c\t%f\t%c\t%f\t%f\t%d\t%d\t%f\t%f\t%c\n", latitude, ew,
longitude, ns, latm, lonm, fix, satcount, hdop, altitude, altunit);
return;
}
if(memcmp(&gprmc, nmeasentence, 6) == 0)
{
while((nmeasentence[p] != 0) && (c < 2))
{
if(nmeasentence[p] == ',') c++;
p++;
}
sscanf(&nmeasentence[p],"%f,%c,%f,%c", &latitude, &ew, &longitude, &ns);
if(latitude != 0) latm = ((int)latitude) /100 + (((int)latitude) %100
+latitude -(int)latitude)/60;
if(longitude != 0) lonm = ((int)longitude) /100 + (((int)longitude) %100
+longitude -(int)longitude)/60;
if(ew == 'W') latm =-latm;
if(ns == 'S') lonm =-lonm;
fprintf(fh_csv, "%f\t%c\t%f\t%c\t%f\t%f\t%d\t%d\t%f\t%f\t%c\n", latitude, ew,
longitude, ns, latm, lonm, fix, satcount, hdop, altitude, altunit);
return;
}
return;
}
/*===========================================================================*/
static void writegpwpl(uint8_t *mac)
{
static int c;
static int cs;
static int cc, ca, ce;
static int gpwpllen;
static char *gpwplptr;
static const char gpgga[] = "$GPGGA";
static const char gprmc[] = "$GPRMC";
static char gpwpl[NMEA_MAX];
protopapcount++;
return;
}
/*===========================================================================*/
static void processptppacket(uint32_t restlen, uint8_t *ptpptr)
{
static ptp_t *ptp;
shalen = 40;
mdctx = EVP_MD_CTX_create();
if(mdctx == NULL) return false;
if(EVP_DigestInit_ex(mdctx, EVP_sha1(), NULL) == 0)
{
EVP_MD_CTX_free(mdctx);
return false;
}
shalen = MSCHAPV2_CHALLENGE_LEN_MAX;
if(EVP_DigestUpdate(mdctx, peer_challenge, MSCHAPV2_CHALLENGE_PEER_LEN_MAX) == 0)
{
EVP_MD_CTX_free(mdctx);
return false;
}
if(EVP_DigestUpdate(mdctx, auth_challenge, MSCHAPV2_CHALLENGE_PEER_LEN_MAX) == 0)
{
EVP_MD_CTX_free(mdctx);
return false;
}
if(EVP_DigestUpdate(mdctx, username, usernamelen) == 0)
{
EVP_MD_CTX_free(mdctx);
return false;
}
if(EVP_DigestFinal_ex(mdctx, shahash, &shalen) == 0)
{
EVP_MD_CTX_free(mdctx);
return false;
}
EVP_MD_CTX_free(mdctx);
memcpy(challenge, shahash, MSCHAPV2_CHALLENGE_LEN_MAX);
return true;
}
/*===========================================================================*/
static inline size_t mschapv2_username_clean(uint8_t *username, size_t usernamelen,
uint8_t *usernameclean)
{
static char *ptr;
zeiger = eapmschapv2hashlist;
zeigerold = NULL;
qsort(eapmschapv2hashlist, eapmschapv2hashlistptr -eapmschapv2hashlist,
EAPMSCHAPV2HASHLIST_SIZE, sort_eapmschapv2hashlist_by_id);
for(zeiger = eapmschapv2hashlist; zeiger < eapmschapv2hashlistptr; zeiger++)
{
if((zeigerold != NULL) && (zeigerold->id == zeiger->id) && (zeigerold-
>mschapv2usernamelen == zeiger->mschapv2usernamelen) && (memcmp(zeigerold-
>mschapv2username, zeiger->mschapv2username, zeiger->mschapv2usernamelen) == 0) &&
(memcmp(zeigerold->mschapv2request, zeiger->mschapv2request, MSCHAPV2REQ_LEN_MAX)
== 0) && (memcmp(zeigerold->mschapv2response, zeiger->mschapv2response,
MSCHAPV2RESP_LEN_MAX) == 0)) continue;
if(fh_eapleap != NULL)
{
usernamecleanlen = mschapv2_username_clean(zeiger->mschapv2username,
zeiger->mschapv2usernamelen, usernameclean);
if(mschapv2_challenge_hash(zeiger->mschapv2response, zeiger-
>mschapv2request, usernameclean, usernamecleanlen, challenge) == false) continue;
fprintf(fh_eapleap, "%.*s::::%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\n",
(int)zeiger->mschapv2usernamelen, zeiger->mschapv2username,
zeiger->mschapv2response[24], zeiger->mschapv2response[25],
zeiger->mschapv2response[26], zeiger->mschapv2response[27], zeiger-
>mschapv2response[28], zeiger->mschapv2response[29], zeiger->mschapv2response[30],
zeiger->mschapv2response[31],
zeiger->mschapv2response[32], zeiger->mschapv2response[33],
zeiger->mschapv2response[34], zeiger->mschapv2response[35], zeiger-
>mschapv2response[36], zeiger->mschapv2response[37], zeiger->mschapv2response[38],
zeiger->mschapv2response[39],
zeiger->mschapv2response[40], zeiger->mschapv2response[41],
zeiger->mschapv2response[42], zeiger->mschapv2response[43], zeiger-
>mschapv2response[44], zeiger->mschapv2response[45], zeiger->mschapv2response[46],
zeiger->mschapv2response[47],
challenge[0], challenge[1], challenge[2], challenge[3],
challenge[4], challenge[5], challenge[6], challenge[7]);
eapmschapv2writtencount++;
}
zeigerold = zeiger;
}
return;
}
/*===========================================================================*/
static void addeapmschapv2hash(uint8_t id, uint8_t mschapv2usernamelen, uint8_t
*mschapv2username, uint8_t *mschapv2request, uint8_t *mschapv2response)
{
static eapmschapv2hashlist_t *eapmschapv2hashlistnew;
eapmschapv2hashcount++;
if(eapmschapv2hashlistptr >= eapmschapv2hashlist +eapmschapv2hashlistmax)
{
eapmschapv2hashlistnew = (eapmschapv2hashlist_t*)realloc(eapmschapv2hashlist,
(eapmschapv2hashlistmax +EAPMSCHAPV2HASHLIST_MAX) *EAPMSCHAPV2HASHLIST_SIZE);
if(eapmschapv2hashlistnew == NULL)
{
printf("failed to allocate memory for internal list\n");
exit(EXIT_FAILURE);
}
eapmschapv2hashlist = eapmschapv2hashlistnew;
eapmschapv2hashlistptr = eapmschapv2hashlistnew +eapmschapv2hashlistmax;
eapmschapv2hashlistmax += EAPMSCHAPV2HASHLIST_MAX;
}
memset(eapmschapv2hashlistptr, 0, EAPMSCHAPV2HASHLIST_SIZE);
eapmschapv2hashlistptr->id = id;
memcpy(eapmschapv2hashlistptr->mschapv2request, mschapv2request,
MSCHAPV2REQ_LEN_MAX);
memcpy(eapmschapv2hashlistptr->mschapv2response, mschapv2response,
MSCHAPV2RESP_LEN_MAX);
eapmschapv2hashlistptr->mschapv2usernamelen = mschapv2usernamelen;
memcpy(eapmschapv2hashlistptr->mschapv2username, mschapv2username,
mschapv2usernamelen);
eapmschapv2hashlistptr++;
return;
}
/*===========================================================================*/
static void processexteapmschapv2(uint64_t eaptimestamp, uint8_t *macto, uint8_t
*macfm, uint8_t eapcode, uint32_t restlen, uint8_t *eapmschapv2ptr)
{
static eapmschapv2_t *eapmschapv2;
static uint16_t eaplen;
static uint16_t mschapv2len;
static eapmschapv2msglist_t *zeiger;
static uint32_t mschapv2usernamelen;
static uint8_t *mschapv2usernameptr;
eapmschapv2count++;
eapmschapv2 = (eapmschapv2_t*)eapmschapv2ptr;
eaplen = ntohs(eapmschapv2->eaplen);
mschapv2len = ntohs(eapmschapv2->mschapv2len);
if(eaplen > restlen) return;
if((eapcode == EAP_CODE_REQ) && (eapmschapv2->opcode == EAP_MSCHAPV2_OPCODE_REQ))
{
zeiger = eapmschapv2msglist +EAPMSCHAPV2MSGLIST_MAX;
if(eapmschapv2->mschapv2valuesize != MSCHAPV2REQ_LEN_MAX) return;
memset(zeiger, 0, EAPMSCHAPV2MSGLIST_SIZE);
zeiger->timestamp = eaptimestamp;
memcpy(zeiger->ap, macfm, 6);
memcpy(zeiger->client, macto, 6);
zeiger->type = EAP_CODE_REQ;
zeiger->id = eapmschapv2->id;
memcpy(zeiger->mschapv2request, eapmschapv2->mschapv2data, eapmschapv2-
>mschapv2valuesize);
mschapv2usernamelen = eaplen -EAPMSCHAPV2_SIZE -eapmschapv2-
>mschapv2valuesize;
if(mschapv2usernamelen > MSCHAPV2USERNAME_LEN_MAX) return;
if(EAPMSCHAPV2_SIZE +MSCHAPV2REQ_LEN_MAX +mschapv2usernamelen > restlen)
return;
mschapv2usernameptr = eapmschapv2ptr +EAPMSCHAPV2_SIZE +eapmschapv2-
>mschapv2valuesize;
if((fh_identity != 0) && (mschapv2usernamelen > 0))
{
fwritestring(mschapv2usernamelen, mschapv2usernameptr, fh_identity);
identitycount++;
}
qsort(eapmschapv2msglist, EAPMSCHAPV2MSGLIST_MAX +1, EAPMSCHAPV2MSGLIST_SIZE,
sort_eapmschapv2msglist_by_timestamp);
}
else if((eapcode == EAP_CODE_RESP) && (eapmschapv2->opcode ==
EAP_MSCHAPV2_OPCODE_RESP))
{
zeiger = eapmschapv2msglist +EAPMSCHAPV2MSGLIST_MAX;
if(mschapv2len != eaplen -EXTEAP_SIZE) return;
if(memcmp(&zeroed32, eapmschapv2->mschapv2data
+MSCHAPV2_CHALLENGE_PEER_LEN_MAX +MSCHAPV2_RESERVED_LEN_MAX,
MSCHAPV2_NTRESPONSE_LEN_MAX) == 0) return;
if(eapmschapv2->mschapv2valuesize != MSCHAPV2RESP_LEN_MAX) return;
memset(zeiger, 0, EAPMSCHAPV2MSGLIST_SIZE);
zeiger->timestamp = eaptimestamp;
memcpy(zeiger->ap, macto, 6);
memcpy(zeiger->client, macfm, 6);
zeiger->type = EAP_CODE_RESP;
zeiger->id = eapmschapv2->id;
memcpy(zeiger->mschapv2response, eapmschapv2->mschapv2data, eapmschapv2-
>mschapv2valuesize);
mschapv2usernamelen = restlen -EAPMSCHAPV2_SIZE -eapmschapv2-
>mschapv2valuesize;
if(mschapv2usernamelen == 0) return;
if(mschapv2usernamelen > MSCHAPV2USERNAME_LEN_MAX) return;
if(EAPMSCHAPV2_SIZE +MSCHAPV2REQ_LEN_MAX +mschapv2usernamelen > restlen)
return;
mschapv2usernameptr = eapmschapv2ptr +EAPMSCHAPV2_SIZE +eapmschapv2-
>mschapv2valuesize;
zeiger->mschapv2usernamelen = mschapv2usernamelen;
memcpy(zeiger->mschapv2username, mschapv2usernameptr, mschapv2usernamelen);
if(fh_username != 0)
{
fwritestring(mschapv2usernamelen, mschapv2usernameptr, fh_username);
usernamecount++;
}
for(zeiger = eapmschapv2msglist; zeiger < eapmschapv2msglist
+EAPMSCHAPV2MSGLIST_MAX; zeiger++)
{
if((zeiger->type) != EAP_CODE_REQ) continue;
if((zeiger->id) != eapmschapv2->id) continue;
if(memcmp(zeiger->ap, macto, 6) != 0) continue;
if(memcmp(zeiger->client, macfm, 6) != 0) continue;
zeiger->mschapv2usernamelen = mschapv2usernamelen;
memcpy(zeiger->mschapv2username, mschapv2usernameptr,
mschapv2usernamelen);
addeapmschapv2hash(eapmschapv2->id, zeiger->mschapv2usernamelen,
zeiger->mschapv2username, zeiger->mschapv2request, eapmschapv2->mschapv2data);
}
qsort(eapmschapv2msglist, EAPMSCHAPV2MSGLIST_MAX +1, EAPMSCHAPV2MSGLIST_SIZE,
sort_eapmschapv2msglist_by_timestamp);
}
return;
}
/*===========================================================================*/
static void outputeapleaphashlist(void)
{
static eapleaphashlist_t *zeiger, *zeigerold;
zeiger = eapleaphashlist;
zeigerold = eapleaphashlist;
if(memcmp(&zeroed32, zeiger->leaprequest, LEAPREQ_LEN_MAX) == 0) return;
qsort(eapleaphashlist, eapleaphashlistptr -eapleaphashlist, EAPLEAPHASHLIST_SIZE,
sort_eapleaphashlist_by_id);
if(fh_eapleap != NULL)
{
fprintf(fh_eapleap, "%.*s::::%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\
n",
zeiger->leapusernamelen, zeiger->leapusername,
zeiger->leapresponse[0], zeiger->leapresponse[1], zeiger-
>leapresponse[2], zeiger->leapresponse[3], zeiger->leapresponse[4], zeiger-
>leapresponse[5], zeiger->leapresponse[6], zeiger->leapresponse[7],
zeiger->leapresponse[8], zeiger->leapresponse[9], zeiger-
>leapresponse[10], zeiger->leapresponse[11], zeiger->leapresponse[12], zeiger-
>leapresponse[13], zeiger->leapresponse[14], zeiger->leapresponse[15],
zeiger->leapresponse[16], zeiger->leapresponse[17], zeiger-
>leapresponse[18], zeiger->leapresponse[19], zeiger->leapresponse[20], zeiger-
>leapresponse[21], zeiger->leapresponse[22], zeiger->leapresponse[23],
zeiger->leaprequest[0], zeiger->leaprequest[1], zeiger->leaprequest[2],
zeiger->leaprequest[3], zeiger->leaprequest[4], zeiger->leaprequest[5], zeiger-
>leaprequest[6], zeiger->leaprequest[7]);
eapleapwrittencount++;
}
for(zeiger = eapleaphashlist +1; zeiger < eapleaphashlistptr; zeiger++)
{
if((zeigerold->id == zeiger->id) && (zeigerold->leapusernamelen == zeiger-
>leapusernamelen) && (memcmp(zeigerold->leapusername, zeiger->leapusername, zeiger-
>leapusernamelen) == 0) && (memcmp(zeigerold->leaprequest, zeiger->leaprequest,
LEAPREQ_LEN_MAX) == 0) && (memcmp(zeigerold->leapresponse, zeiger->leapresponse,
LEAPRESP_LEN_MAX) == 0)) continue;
if(fh_eapleap != NULL)
{
fprintf(fh_eapleap, "%.*s::::%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\n",
zeiger->leapusernamelen, zeiger->leapusername,
zeiger->leapresponse[0], zeiger->leapresponse[1], zeiger-
>leapresponse[2], zeiger->leapresponse[3], zeiger->leapresponse[4], zeiger-
>leapresponse[5], zeiger->leapresponse[6], zeiger->leapresponse[7],
zeiger->leapresponse[8], zeiger->leapresponse[9], zeiger-
>leapresponse[10], zeiger->leapresponse[11], zeiger->leapresponse[12], zeiger-
>leapresponse[13], zeiger->leapresponse[14], zeiger->leapresponse[15],
zeiger->leapresponse[16], zeiger->leapresponse[17], zeiger-
>leapresponse[18], zeiger->leapresponse[19], zeiger->leapresponse[20], zeiger-
>leapresponse[21], zeiger->leapresponse[22], zeiger->leapresponse[23],
zeiger->leaprequest[0], zeiger->leaprequest[1], zeiger-
>leaprequest[2], zeiger->leaprequest[3], zeiger->leaprequest[4], zeiger-
>leaprequest[5], zeiger->leaprequest[6], zeiger->leaprequest[7]);
eapleapwrittencount++;
}
zeigerold = zeiger;
}
return;
}
/*===========================================================================*/
static void addeapleaphash(uint8_t id, uint8_t leapusernamelen, uint8_t
*leapusername, uint8_t *leaprequest, uint8_t *leapresponse)
{
static eapleaphashlist_t *eapleaphashlistnew;
eapleaphashcount++;
if(eapleaphashlistptr >= eapleaphashlist +eapleaphashlistmax)
{
eapleaphashlistnew = (eapleaphashlist_t*)realloc(eapleaphashlist,
(eapleaphashlistmax +EAPLEAPHASHLIST_MAX) *EAPLEAPHASHLIST_SIZE);
if(eapleaphashlistnew == NULL)
{
fprintf(stderr, "failed to allocate memory for internal list\n");
exit(EXIT_FAILURE);
}
eapleaphashlist = eapleaphashlistnew;
eapleaphashlistptr = eapleaphashlistnew +eapleaphashlistmax;
eapleaphashlistmax += EAPLEAPHASHLIST_MAX;
}
memset(eapleaphashlistptr, 0, EAPLEAPHASHLIST_SIZE);
eapleaphashlistptr->id = id;
memcpy(eapleaphashlistptr->leaprequest, leaprequest, LEAPREQ_LEN_MAX);
memcpy(eapleaphashlistptr->leapresponse, leapresponse, LEAPRESP_LEN_MAX);
eapleaphashlistptr->leapusernamelen = leapusernamelen;
memcpy(eapleaphashlistptr->leapusername, leapusername, leapusernamelen);
eapleaphashlistptr++;
return;
}
/*===========================================================================*/
static void processexteapleap(uint64_t eaptimestamp, uint8_t *macto, uint8_t
*macfm, uint8_t eapcode, uint32_t restlen, uint8_t *eapleapptr)
{
static eapleap_t *eapleap;
static uint32_t eapleaplen;
static eapleapmsglist_t *zeiger;
static uint32_t leapusernamelen;
static uint8_t *leapusernameptr;
eapleapcount++;
eapleap = (eapleap_t*)eapleapptr;
eapleaplen = ntohs(eapleap->eapleaplen);
if(eapleaplen > restlen) return;
if(eapleap->version != 1) return;
if(eapleap->reserved != 0) return;
if(eapcode == EAP_CODE_REQ)
{
zeiger = eapleapmsglist +EAPLEAPMSGLIST_MAX;
if(eapleap->leaplen != LEAPREQ_LEN_MAX) return;
if(eapleap->leaplen > eapleaplen -EAPLEAP_SIZE) return;
if(eapleap->leaplen == eapleaplen -EAPLEAP_SIZE) return;
if(memcmp(&zeroed32, eapleap->leapdata, LEAPREQ_LEN_MAX) == 0) return;
memset(zeiger, 0, EAPLEAPMSGLIST_SIZE);
zeiger->timestamp = eaptimestamp;
memcpy(zeiger->ap, macfm, 6);
memcpy(zeiger->client, macto, 6);
zeiger->type = EAP_CODE_REQ;
zeiger->id = eapleap->id;
memcpy(zeiger->leaprequest, eapleap->leapdata, LEAPREQ_LEN_MAX);
leapusernamelen = eapleaplen -EAPLEAP_SIZE -LEAPREQ_LEN_MAX;
if(leapusernamelen == 0) return;
if(leapusernamelen > LEAPUSERNAME_LEN_MAX) return;
if(EAPLEAP_SIZE +LEAPREQ_LEN_MAX +leapusernamelen > restlen) return;
leapusernameptr = eapleapptr +EAPLEAP_SIZE +LEAPREQ_LEN_MAX;
zeiger->leapusernamelen = leapusernamelen;
memcpy(zeiger->leapusername, leapusernameptr, leapusernamelen);
if(fh_username != 0)
{
fwritestring(leapusernamelen, leapusernameptr, fh_username);
usernamecount++;
}
qsort(eapleapmsglist, EAPLEAPMSGLIST_MAX +1, EAPLEAPMSGLIST_SIZE,
sort_eapleapmsglist_by_timestamp);
}
else if(eapcode == EAP_CODE_RESP)
{
zeiger = eapleapmsglist +EAPLEAPMSGLIST_MAX;
if(eapleap->leaplen != LEAPRESP_LEN_MAX) return;
if(eapleap->leaplen > eapleaplen -EAPLEAP_SIZE) return;
if(memcmp(&zeroed32, eapleap->leapdata, LEAPRESP_LEN_MAX) == 0) return;
memset(zeiger, 0, EAPLEAPMSGLIST_SIZE);
zeiger->timestamp = eaptimestamp;
memcpy(zeiger->ap, macto, 6);
memcpy(zeiger->client, macfm, 6);
zeiger->type = EAP_CODE_RESP;
zeiger->id = eapleap->id;
memcpy(zeiger->leapresponse, eapleap->leapdata, LEAPRESP_LEN_MAX);
for(zeiger = eapleapmsglist; zeiger < eapleapmsglist +EAPLEAPMSGLIST_MAX;
zeiger++)
{
if((zeiger->type) != EAP_CODE_REQ) continue;
if((zeiger->id) != eapleap->id) continue;
if(memcmp(zeiger->ap, macto, 6) != 0) continue;
if(memcmp(zeiger->client, macfm, 6) != 0) continue;
addeapleaphash(eapleap->id, zeiger->leapusernamelen, zeiger-
>leapusername, zeiger->leaprequest, eapleap->leapdata);
}
qsort(eapleapmsglist, EAPLEAPMSGLIST_MAX +1, EAPLEAPMSGLIST_SIZE,
sort_eapleapmsglist_by_timestamp);
}
return;
}
/*===========================================================================*/
static void outputeapmd5hashlist(void)
{
static eapmd5hashlist_t *zeiger, *zeigerold;
zeiger = eapmd5hashlist;
zeigerold = eapmd5hashlist;
if(memcmp(&zeroed32, zeiger->md5request, EAPMD5_LEN_MAX) == 0) return;
qsort(eapmd5hashlist, eapmd5hashlistptr -eapmd5hashlist, EAPMD5HASHLIST_SIZE,
sort_eapmd5hashlist_by_id);
if(fh_eapmd5 != 0)
{
fprintf(fh_eapmd5, "%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:%02x\n",
zeiger->md5response[0], zeiger->md5response[1], zeiger-
>md5response[2], zeiger->md5response[3], zeiger->md5response[4], zeiger-
>md5response[5], zeiger->md5response[6], zeiger->md5response[7],
zeiger->md5response[8], zeiger->md5response[9], zeiger-
>md5response[10], zeiger->md5response[11], zeiger->md5response[12], zeiger-
>md5response[13], zeiger->md5response[14], zeiger->md5response[15],
zeiger->md5request[0], zeiger->md5request[1], zeiger-
>md5request[2], zeiger->md5request[3], zeiger->md5request[4], zeiger-
>md5request[5], zeiger->md5request[6], zeiger->md5request[7],
zeiger->md5request[8], zeiger->md5request[9], zeiger-
>md5request[10], zeiger->md5request[11], zeiger->md5request[12], zeiger-
>md5request[13], zeiger->md5request[14], zeiger->md5request[15],
zeiger->id);
eapmd5writtencount++;
}
if(fh_eapmd5john != 0)
{
fprintf(fh_eapmd5john, "$chap$%x*%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\n",
zeiger->id,
zeiger->md5request[0], zeiger->md5request[1], zeiger-
>md5request[2], zeiger->md5request[3], zeiger->md5request[4], zeiger-
>md5request[5], zeiger->md5request[6], zeiger->md5request[7],
zeiger->md5request[8], zeiger->md5request[9], zeiger-
>md5request[10], zeiger->md5request[11], zeiger->md5request[12], zeiger-
>md5request[13], zeiger->md5request[14], zeiger->md5request[15],
zeiger->md5response[0], zeiger->md5response[1], zeiger-
>md5response[2], zeiger->md5response[3], zeiger->md5response[4], zeiger-
>md5response[5], zeiger->md5response[6], zeiger->md5response[7],
zeiger->md5response[8], zeiger->md5response[9], zeiger-
>md5response[10], zeiger->md5response[11], zeiger->md5response[12], zeiger-
>md5response[13], zeiger->md5response[14], zeiger->md5response[15]);
eapmd5johnwrittencount++;
}
for(zeiger = eapmd5hashlist +1; zeiger < eapmd5hashlistptr; zeiger++)
{
if((zeigerold->id == zeiger->id) && (memcmp(zeigerold->md5request, zeiger-
>md5request, EAPMD5_LEN_MAX) == 0) && (memcmp(zeigerold->md5response, zeiger-
>md5response, EAPMD5_LEN_MAX) == 0)) continue;
if(fh_eapmd5 != 0)
{
fprintf(fh_eapmd5, "%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:
%02x\n",
zeiger->md5response[0], zeiger->md5response[1], zeiger-
>md5response[2], zeiger->md5response[3], zeiger->md5response[4], zeiger-
>md5response[5], zeiger->md5response[6], zeiger->md5response[7],
zeiger->md5response[8], zeiger->md5response[9], zeiger-
>md5response[10], zeiger->md5response[11], zeiger->md5response[12], zeiger-
>md5response[13], zeiger->md5response[14], zeiger->md5response[15],
zeiger->md5request[0], zeiger->md5request[1], zeiger-
>md5request[2], zeiger->md5request[3], zeiger->md5request[4], zeiger-
>md5request[5], zeiger->md5request[6], zeiger->md5request[7],
zeiger->md5request[8], zeiger->md5request[9], zeiger-
>md5request[10], zeiger->md5request[11], zeiger->md5request[12], zeiger-
>md5request[13], zeiger->md5request[14], zeiger->md5request[15],
zeiger->id);
eapmd5writtencount++;
}
if(fh_eapmd5john != 0)
{
fprintf(fh_eapmd5john, "$chap$%x*%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\n",
zeiger->id,
zeiger->md5request[0], zeiger->md5request[1], zeiger-
>md5request[2], zeiger->md5request[3], zeiger->md5request[4], zeiger-
>md5request[5], zeiger->md5request[6], zeiger->md5request[7],
zeiger->md5request[8], zeiger->md5request[9], zeiger-
>md5request[10], zeiger->md5request[11], zeiger->md5request[12], zeiger-
>md5request[13], zeiger->md5request[14], zeiger->md5request[15],
zeiger->md5response[0], zeiger->md5response[1], zeiger-
>md5response[2], zeiger->md5response[3], zeiger->md5response[4], zeiger-
>md5response[5], zeiger->md5response[6], zeiger->md5response[7],
zeiger->md5response[8], zeiger->md5response[9], zeiger-
>md5response[10], zeiger->md5response[11], zeiger->md5response[12], zeiger-
>md5response[13], zeiger->md5response[14], zeiger->md5response[15]);
eapmd5johnwrittencount++;
}
zeigerold = zeiger;
}
return;
}
/*===========================================================================*/
static void addeapmd5hash(uint8_t id, uint8_t *challenge, uint8_t *response)
{
static eapmd5hashlist_t *eapmd5hashlistnew;
eapmd5hashcount++;
if(eapmd5hashlistptr >= eapmd5hashlist +eapmd5hashlistmax)
{
eapmd5hashlistnew = (eapmd5hashlist_t*)realloc(eapmd5hashlist,
(eapmd5hashlistmax +EAPMD5HASHLIST_MAX) *EAPMD5HASHLIST_SIZE);
if(eapmd5hashlistnew == NULL)
{
fprintf(stderr, "failed to allocate memory for internal list\n");
exit(EXIT_FAILURE);
}
eapmd5hashlist = eapmd5hashlistnew;
eapmd5hashlistptr = eapmd5hashlistnew +eapmd5hashlistmax;
eapmd5hashlistmax += EAPMD5HASHLIST_MAX;
}
memset(eapmd5hashlistptr, 0, EAPMD5HASHLIST_SIZE);
eapmd5hashlistptr->id = id;
memcpy(eapmd5hashlistptr->md5request, challenge, EAPMD5_LEN_MAX);
memcpy(eapmd5hashlistptr->md5response, response, EAPMD5_LEN_MAX);
eapmd5hashlistptr++;
return;
}
/*===========================================================================*/
static void processexteapmd5(uint64_t eaptimestamp, uint8_t *macto, uint8_t *macfm,
uint8_t eapcode, uint32_t restlen, uint8_t *eapmd5ptr)
{
static eapmd5_t *eapmd5;
static uint32_t eapmd5len;
static eapmd5msglist_t *zeiger;
eapmd5count++;
eapmd5 = (eapmd5_t*)eapmd5ptr;
eapmd5len = ntohs(eapmd5->eapmd5len);
if(eapmd5len != restlen) return;
if(eapmd5->md5len != EAPMD5_LEN_MAX) return;
if(memcmp(&zeroed32, eapmd5->md5data, EAPMD5_LEN_MAX) == 0) return;
if(eapcode == EAP_CODE_REQ)
{
zeiger = eapmd5msglist +EAPMD5MSGLIST_MAX;
memset(zeiger, 0, EAPMD5MSGLIST_SIZE );
zeiger->timestamp = eaptimestamp;
memcpy(zeiger->ap, macfm, 6);
memcpy(zeiger->client, macto, 6);
zeiger->type = EAP_CODE_REQ;
zeiger->id = eapmd5->id;
memcpy(zeiger->md5, eapmd5->md5data, EAPMD5_LEN_MAX);
qsort(eapmd5msglist, EAPMD5MSGLIST_MAX +1, EAPMD5MSGLIST_SIZE,
sort_eapmd5msglist_by_timestamp);
}
else if(eapcode == EAP_CODE_RESP)
{
zeiger = eapmd5msglist +EAPMD5MSGLIST_MAX;
memset(zeiger, 0, EAPMD5MSGLIST_SIZE );
zeiger->timestamp = eaptimestamp;
memcpy(zeiger->ap, macto, 6);
memcpy(zeiger->client, macfm, 6);
zeiger->type = EAP_CODE_RESP;
zeiger->id = eapmd5->id;
memcpy(zeiger->md5, eapmd5->md5data, EAPMD5_LEN_MAX);
for(zeiger = eapmd5msglist; zeiger < eapmd5msglist +EAPMD5MSGLIST_MAX;
zeiger++)
{
if((zeiger->type) != EAP_CODE_REQ) continue;
if((zeiger->id) != eapmd5->id) continue;
if(memcmp(zeiger->ap, macto, 6) != 0) continue;
if(memcmp(zeiger->client, macfm, 6) != 0) continue;
addeapmd5hash(eapmd5->id, zeiger->md5, eapmd5->md5data);
}
qsort(eapmd5msglist, EAPMD5MSGLIST_MAX +1, EAPMD5MSGLIST_SIZE,
sort_eapmd5msglist_by_timestamp);
}
return;
}
/*===========================================================================*/
static void hccap2base(unsigned char *in, unsigned char b)
{
static const char itoa64[65] =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
memset(eapoltmp, 0, sizeof(eapoltmp));
memcpy(eapoltmp, eapolmessage, eapollen);
wpakzero = (wpakey_t*)(eapoltmp +EAPAUTH_SIZE);
wpak = (wpakey_t*)(eapolmessage +EAPAUTH_SIZE);
memset(wpakzero->keymic, 0, 16);
if((keyver == 1) || (keyver == 2))
{
memset(&pkedata, 0, sizeof(pkedata));
pkeptr = pkedata;
memcpy(pkeptr, "Pairwise key expansion", 23);
if(memcmp(macap, macsta, 6) < 0)
{
memcpy(pkeptr +23, macap, 6);
memcpy(pkeptr +29, macsta, 6);
}
else
{
memcpy(pkeptr +23, macsta, 6);
memcpy(pkeptr +29, macap, 6);
}
if(memcmp(nonceap, wpak->nonce, 32) < 0)
{
memcpy (pkeptr +35, nonceap, 32);
memcpy (pkeptr +67, wpak->nonce, 32);
}
else
{
memcpy (pkeptr +35, wpak->nonce, 32);
memcpy (pkeptr +67, nonceap, 32);
}
if(!EVP_MAC_init(ctxhmac, testpmk, 32, paramssha1)) return false;
if(!EVP_MAC_update(ctxhmac, pkedata, 100)) return false;
if(!EVP_MAC_final(ctxhmac, pkedata, NULL, 100)) return false;
if(keyver == 2)
{
if(!EVP_MAC_init(ctxhmac, pkedata, 16, paramssha1)) return false;
if(!EVP_MAC_update(ctxhmac, eapoltmp, eapollen)) return false;
if(!EVP_MAC_final(ctxhmac, eapoltmp, NULL, eapollen)) return false;
}
if(keyver == 1)
{
if(!EVP_MAC_init(ctxhmac, pkedata, 16, paramsmd5)) return false;
if(!EVP_MAC_update(ctxhmac, eapoltmp, eapollen)) return false;
if(!EVP_MAC_final(ctxhmac, eapoltmp, NULL, eapollen)) return false;
}
}
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(macap, macsta, 6) < 0)
{
memcpy(pkeptr +22, macap, 6);
memcpy(pkeptr +28, macsta, 6);
}
else
{
memcpy(pkeptr +22, macsta, 6);
memcpy(pkeptr +28, macap, 6);
}
if(memcmp(nonceap, wpak->nonce, 32) < 0)
{
memcpy (pkeptr +34, nonceap, 32);
memcpy (pkeptr +66, wpak->nonce, 32);
}
else
{
memcpy (pkeptr +34, wpak->nonce, 32);
memcpy (pkeptr +66, nonceap, 32);
}
pkedata[100] = 0x80;
pkedata[101] = 1;
if(!EVP_MAC_init(ctxhmac, testpmk, 32, paramssha256)) return false;
if(!EVP_MAC_update(ctxhmac, pkedata, 102)) return false;
if(!EVP_MAC_final(ctxhmac, pkedata, NULL, 102)) return false;
if(!EVP_MAC_init(ctxcmac, pkedata, 16, paramsaes128)) return false;
if(!EVP_MAC_update(ctxcmac, eapoltmp, eapollen)) return false;
if(!EVP_MAC_final(ctxcmac, eapoltmp, NULL, eapollen)) return false;
}
if(memcmp(wpak->keymic, eapoltmp, 16) == 0) return true;
return false;
}
/*===========================================================================*/
static bool testzeroedpsk(uint8_t essidlen, uint8_t *essid)
{
if(PKCS5_PBKDF2_HMAC_SHA1(zeroedpsk, 8, essid, essidlen, 4096, 32, calculatedpmk)
== 0) return false;
return true;
}
/*===========================================================================*/
static void getnc(handshakelist_t *zeigerhsakt)
{
static handshakelist_t *zeigerhs, *zeigerhsold;
zeigerhsold = zeigerhsakt;
for(zeigerhs = zeigerhsakt; zeigerhs < handshakelistptr; zeigerhs++)
{
if(memcmp(zeigerhs->ap, zeigerhsold->ap, 6) != 0) return;
{
zeigerhsakt->status |= zeigerhs->status &0xe0;
zeigerhsold->status |= zeigerhs->status &0xe0;
}
zeigerhsold = zeigerhs;
}
return;
}
/*===========================================================================*/
static handshakelist_t *gethandshake(maclist_t *zeigermac, handshakelist_t
*zeigerhsakt)
{
static int p;
static handshakelist_t *zeigerhs, *zeigerhsold;
static wpakey_t *wpak, *wpaktemp;
static int i;
static unsigned char *hcpos;
static uint8_t keyvertemp;
static uint8_t eapoltemp[EAPOL_AUTHLEN_MAX];
static hccapx_t hccapx;
static hccap_t hccap;
static time_t tvhs;
static char timestringhs[32];
zeigerhsold = NULL;
for(zeigerhs = zeigerhsakt; zeigerhs < handshakelistptr; zeigerhs++)
{
tvhs = zeigerhs->timestamp /1000000000;
strftime(timestringhs, 32, "%d.%m.%Y %H:%M:%S", localtime(&tvhs));
if(donotcleanflag == false)
{
if(memcmp(&mac_broadcast, zeigerhs->client, 6) == 0) continue;
if(memcmp(&mac_broadcast, zeigerhs->ap, 6) == 0) continue;
if(zeigerhsold != NULL)
{
if((memcmp(zeigerhs->ap, zeigerhsold->ap, 6) == 0) &&
(memcmp(zeigerhs->client, zeigerhsold->client, 6) == 0))
{
if((zeigerhs->status &ST_APLESS) != ST_APLESS)
getnc(zeigerhs);
continue;
}
}
}
if(memcmp(zeigermac->addr, zeigerhs->ap, 6) == 0)
{
eapolmpbestcount++;
if((zeigerhs->status &ST_APLESS) != ST_APLESS) getnc(zeigerhs);
if((zeigerhs->status &ST_APLESS) == ST_APLESS) eapolaplesscount++;
if((zeigerhs->status &7) == ST_M12E2) eapolm12e2count++;
if((zeigerhs->status &7) == ST_M14E4) eapolm14e4count++;
if((zeigerhs->status &7) == ST_M32E2) eapolm32e2count++;
if((zeigerhs->status &7) == ST_M32E3) eapolm32e3count++;
if((zeigerhs->status &7) == ST_M34E3) eapolm34e3count++;
if((zeigerhs->status &7) == ST_M34E4) eapolm34e4count++;
wpak = (wpakey_t*)(zeigerhs->eapol +EAPAUTH_SIZE);
keyvertemp = ntohs(wpak->keyinfo) & WPA_KEY_INFO_TYPE_MASK;
memcpy(&eapoltemp, zeigerhs->eapol, zeigerhs->eapauthlen);
wpaktemp = (wpakey_t*)(eapoltemp +EAPAUTH_SIZE);
memset(wpaktemp->keymic, 0, 16);
if(donotcleanflag == false)
{
if(testzeroedpsk(zeigermac->essidlen, zeigermac->essid) == true)
{
if(testeapolpmk(calculatedpmk, keyvertemp, zeigerhs-
>client, zeigerhs->ap, zeigerhs->anonce, zeigerhs->eapauthlen, zeigerhs->eapol) ==
true)
{
zeroedeapolpskcount++;
eapolmpbestcount--;
continue;
}
}
}
if(fh_pmkideapol != 0)
{
//WPA*TYPE*PMKID-ODER-MIC*MACAP*MACSTA*ESSID_HEX*ANONCE*EAPOL*MP
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*",
HCX_TYPE_EAPOL,
wpak->keymic[0], wpak->keymic[1], wpak->keymic[2], wpak-
>keymic[3], wpak->keymic[4], wpak->keymic[5], wpak->keymic[6], wpak->keymic[7],
wpak->keymic[8], wpak->keymic[9], wpak->keymic[10], wpak-
>keymic[11], wpak->keymic[12], wpak->keymic[13], wpak->keymic[14], wpak-
>keymic[15],
zeigerhs->ap[0], zeigerhs->ap[1], zeigerhs->ap[2],
zeigerhs->ap[3], zeigerhs->ap[4], zeigerhs->ap[5],
zeigerhs->client[0], zeigerhs->client[1], zeigerhs-
>client[2], zeigerhs->client[3], zeigerhs->client[4], zeigerhs->client[5]);
for(p = 0; p < zeigermac->essidlen; p++) fprintf(fh_pmkideapol,
"%02x", zeigermac->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*",
zeigerhs->anonce[0], zeigerhs->anonce[1], zeigerhs-
>anonce[2], zeigerhs->anonce[3], zeigerhs->anonce[4], zeigerhs->anonce[5],
zeigerhs->anonce[6], zeigerhs->anonce[7],
zeigerhs->anonce[8], zeigerhs->anonce[9], zeigerhs-
>anonce[10], zeigerhs->anonce[11], zeigerhs->anonce[12], zeigerhs->anonce[13],
zeigerhs->anonce[14], zeigerhs->anonce[15],
zeigerhs->anonce[16], zeigerhs->anonce[17], zeigerhs-
>anonce[18], zeigerhs->anonce[19], zeigerhs->anonce[20], zeigerhs->anonce[21],
zeigerhs->anonce[22], zeigerhs->anonce[23],
zeigerhs->anonce[24], zeigerhs->anonce[25], zeigerhs-
>anonce[26], zeigerhs->anonce[27], zeigerhs->anonce[28], zeigerhs->anonce[29],
zeigerhs->anonce[30], zeigerhs->anonce[31]);
for(p = 0; p < zeigerhs->eapauthlen; p++) fprintf(fh_pmkideapol,
"%02x", eapoltemp[p]);
if(addtimestampflag == false) fprintf(fh_pmkideapol, "*%02x\n",
zeigerhs->status);
else fprintf(fh_pmkideapol, "*%02x\t%s %" PRIu64 "\n", zeigerhs-
>status, timestringhs, zeigerhs->timestampgap);
if(zeigerhs->rcgap == 0) eapolwrittencount++;
else eapolncwrittencount++;
}
if((fh_pmkideapoljtrdeprecated != 0) && (zeigerhs->rcgap == 0))
{
memset (&hccap, 0, sizeof(hccap_t));
memcpy(&hccap.ap, zeigerhs->ap, 6);
memcpy(&hccap.client, zeigerhs->client, 6);
memcpy(&hccap.anonce, zeigerhs->anonce, 32);
memcpy(&hccap.snonce, wpak->nonce, 32);
memcpy(&hccap.keymic, &wpak->keymic, 16);
hccap.keyver = keyvertemp;
hccap.eapol_size = zeigerhs->eapauthlen;
memcpy(&hccap.eapol, &eapoltemp, zeigerhs->eapauthlen);
#ifdef BIG_ENDIAN_HOST
hccap.eapol_size = byte_swap_16(hccap.eapol_size);
#endif
fprintf(fh_pmkideapoljtrdeprecated, "%.*s:$WPAPSK$%.*s#",
zeigermac->essidlen, zeigermac->essid, zeigermac->essidlen, zeigermac->essid);
hcpos = (unsigned char*)&hccap;
for (i = 36; i + 3 < (int)HCCAP_SIZE; i += 3)
hccap2base(&hcpos[i], 1);
hccap2base(&hcpos[i], 0);
fprintf(fh_pmkideapoljtrdeprecated, ":%02x-%02x-%02x-%02x-%02x-
%02x:%02x-%02x-%02x-%02x-%02x-%02x:%02x%02x%02x%02x%02x%02x",
zeigerhs->client[0], zeigerhs->client[1], zeigerhs-
>client[2], zeigerhs->client[3], zeigerhs->client[4], zeigerhs->client[5],
zeigerhs->ap[0], zeigerhs->ap[1], zeigerhs->ap[2],
zeigerhs->ap[3], zeigerhs->ap[4], zeigerhs->ap[5],
zeigerhs->ap[0], zeigerhs->ap[1], zeigerhs->ap[2],
zeigerhs->ap[3], zeigerhs->ap[4], zeigerhs->ap[5]);
if(keyvertemp == 1) fprintf(fh_pmkideapoljtrdeprecated, "::WPA");
else fprintf(fh_pmkideapoljtrdeprecated, "::WPA2");
if((zeigerhs->status &0x7) == 0)
fprintf(fh_pmkideapoljtrdeprecated, ":not verified");
else fprintf(fh_pmkideapoljtrdeprecated, ":verified");
fprintf(fh_pmkideapoljtrdeprecated, ":%s\n",
basename(jtrbasenamedeprecated));
eapolwrittenjcountdeprecated++;
}
if(fh_hccapxdeprecated != 0)
{
memset (&hccapx, 0, sizeof(hccapx_t));
hccapx.signature = HCCAPX_SIGNATURE;
hccapx.version = HCCAPX_VERSION;
hccapx.message_pair = zeigerhs->status;
hccapx.essid_len = zeigermac->essidlen;
memcpy(&hccapx.essid, zeigermac->essid, zeigermac->essidlen);
memcpy(&hccapx.ap, zeigerhs->ap, 6);
memcpy(&hccapx.client, zeigerhs->client, 6);
memcpy(&hccapx.anonce, zeigerhs->anonce, 32);
memcpy(&hccapx.snonce, wpak->nonce, 32);
hccapx.eapol_len = zeigerhs->eapauthlen;
memcpy(&hccapx.eapol, &eapoltemp, zeigerhs->eapauthlen);
hccapx.keyver = keyvertemp;
memcpy(&hccapx.keymic, wpak->keymic, 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_hccapxdeprecated);
if(zeigerhs->rcgap == 0) eapolwrittenhcpxcountdeprecated++;
else eapolncwrittenhcpxcountdeprecated++;
}
if((fh_hccapdeprecated != 0) && (zeigerhs->rcgap == 0))
{
memset(&hccap, 0, sizeof(hccap_t));
memcpy(&hccap.essid, zeigermac->essid, zeigermac->essidlen);
memcpy(&hccap.ap, zeigerhs->ap, 6);
memcpy(&hccap.client, zeigerhs->client, 6);
memcpy(&hccap.anonce, zeigerhs->anonce, 32);
memcpy(&hccap.snonce, wpak->nonce, 32);
memcpy(&hccap.keymic, wpak->keymic, 16);
hccap.keyver = keyvertemp;
hccap.eapol_size = zeigerhs->eapauthlen;
memcpy(&hccap.eapol, &eapoltemp, zeigerhs->eapauthlen);
#ifdef BIG_ENDIAN_HOST
hccap.eapol_size = byte_swap_16(hccap.eapol_size);
#endif
fwrite(&hccap, HCCAP_SIZE, 1, fh_hccapdeprecated);
eapolwrittenhcpcountdeprecated++;
}
}
if(memcmp(zeigerhs->ap, zeigermac->addr, 6) > 0)
{
zeigerhsakt = zeigerhs;
return zeigerhsakt;
}
zeigerhsold = zeigerhs;
}
return zeigerhsakt;
}
/*===========================================================================*/
static pmkidlist_t *getpmkid(maclist_t *zeigermac, pmkidlist_t *zeigerpmkidakt)
{
static int p;
static pmkidlist_t *zeigerpmkid, *zeigerpmkidold;
static time_t tvhs;
static char timestringhs[32];
zeigerpmkidold = NULL;
for(zeigerpmkid = zeigerpmkidakt; zeigerpmkid < pmkidlistptr; zeigerpmkid++)
{
tvhs = zeigerpmkid->timestamp /1000000000;
strftime(timestringhs, 32, "%d.%m.%Y %H:%M:%S", localtime(&tvhs));
if(donotcleanflag == false)
{
if(memcmp(&mac_broadcast, zeigerpmkid->client, 6) == 0) continue;
if(memcmp(&mac_broadcast, zeigerpmkid->ap, 6) == 0) continue;
if(zeigerpmkidold != NULL)
{
if((memcmp(zeigerpmkid->ap, zeigerpmkidold->ap, 6) == 0) &&
(memcmp(zeigerpmkid->client, zeigerpmkidold->client, 6) == 0)) continue;
}
}
if(memcmp(zeigermac->addr, zeigerpmkid->ap, 6) == 0)
{
if(donotcleanflag == false)
{
if(testzeroedpsk(zeigermac->essidlen, zeigermac->essid) == true)
{
if(testpmkid(calculatedpmk, zeigerpmkid->client,
zeigerpmkid->ap, zeigerpmkid->pmkid) == true)
{
zeroedpmkidpskcount++;
continue;
}
}
}
if(memcmp(&myaktclient, zeigerpmkid->client, 6) == 0) pmkidroguecount+
+;
pmkidbestcount++;
if(fh_pmkideapol != 0)
{
//WPA*TYPE*PMKID-ODER-MIC*MACAP*MACSTA*ESSID_HEX*ANONCE*EAPOL*MP
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*",
HCX_TYPE_PMKID,
zeigerpmkid->pmkid[0], zeigerpmkid->pmkid[1], zeigerpmkid-
>pmkid[2], zeigerpmkid->pmkid[3], zeigerpmkid->pmkid[4], zeigerpmkid->pmkid[5],
zeigerpmkid->pmkid[6], zeigerpmkid->pmkid[7],
zeigerpmkid->pmkid[8], zeigerpmkid->pmkid[9], zeigerpmkid-
>pmkid[10], zeigerpmkid->pmkid[11], zeigerpmkid->pmkid[12], zeigerpmkid->pmkid[13],
zeigerpmkid->pmkid[14], zeigerpmkid->pmkid[15],
zeigerpmkid->ap[0], zeigerpmkid->ap[1], zeigerpmkid->ap[2],
zeigerpmkid->ap[3], zeigerpmkid->ap[4], zeigerpmkid->ap[5],
zeigerpmkid->client[0], zeigerpmkid->client[1],
zeigerpmkid->client[2], zeigerpmkid->client[3], zeigerpmkid->client[4],
zeigerpmkid->client[5]);
for(p = 0; p < zeigermac->essidlen; p++) fprintf(fh_pmkideapol,
"%02x", zeigermac->essid[p]);
if(addtimestampflag == false) fprintf(fh_pmkideapol, "***%02x\n",
zeigerpmkid->status);
else fprintf(fh_pmkideapol, "***%02x\t%s\n", zeigerpmkid-
>status, timestringhs);
pmkidwrittenhcount++;
}
if((fh_pmkideapolclient != 0) && ((zeigerpmkid->status & PMKID_CLIENT)
== PMKID_CLIENT))
{
//WPA*TYPE*PMKID-ODER-MIC*MACAP*MACSTA*ESSID_HEX*ANONCE*EAPOL*MP
fprintf(fh_pmkideapolclient, "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*",
HCX_TYPE_PMKID,
zeigerpmkid->pmkid[0], zeigerpmkid->pmkid[1], zeigerpmkid-
>pmkid[2], zeigerpmkid->pmkid[3], zeigerpmkid->pmkid[4], zeigerpmkid->pmkid[5],
zeigerpmkid->pmkid[6], zeigerpmkid->pmkid[7],
zeigerpmkid->pmkid[8], zeigerpmkid->pmkid[9], zeigerpmkid-
>pmkid[10], zeigerpmkid->pmkid[11], zeigerpmkid->pmkid[12], zeigerpmkid->pmkid[13],
zeigerpmkid->pmkid[14], zeigerpmkid->pmkid[15],
zeigerpmkid->ap[0], zeigerpmkid->ap[1], zeigerpmkid->ap[2],
zeigerpmkid->ap[3], zeigerpmkid->ap[4], zeigerpmkid->ap[5],
zeigerpmkid->client[0], zeigerpmkid->client[1],
zeigerpmkid->client[2], zeigerpmkid->client[3], zeigerpmkid->client[4],
zeigerpmkid->client[5]);
for(p = 0; p < zeigermac->essidlen; p++)
fprintf(fh_pmkideapolclient, "%02x", zeigermac->essid[p]);
if(addtimestampflag == false) fprintf(fh_pmkideapolclient, "***
%02x\n", zeigerpmkid->status);
else fprintf(fh_pmkideapolclient, "***%02x\t%s\n", zeigerpmkid-
>status, timestringhs);
pmkidclientwrittenhcount++;
}
if(fh_pmkideapoljtrdeprecated != 0)
{
fprintf(fh_pmkideapoljtrdeprecated, "%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*",
zeigerpmkid->pmkid[0], zeigerpmkid->pmkid[1], zeigerpmkid-
>pmkid[2], zeigerpmkid->pmkid[3], zeigerpmkid->pmkid[4], zeigerpmkid->pmkid[5],
zeigerpmkid->pmkid[6], zeigerpmkid->pmkid[7],
zeigerpmkid->pmkid[8], zeigerpmkid->pmkid[9], zeigerpmkid-
>pmkid[10], zeigerpmkid->pmkid[11], zeigerpmkid->pmkid[12], zeigerpmkid->pmkid[13],
zeigerpmkid->pmkid[14], zeigerpmkid->pmkid[15],
zeigerpmkid->ap[0], zeigerpmkid->ap[1], zeigerpmkid->ap[2],
zeigerpmkid->ap[3], zeigerpmkid->ap[4], zeigerpmkid->ap[5],
zeigerpmkid->client[0], zeigerpmkid->client[1],
zeigerpmkid->client[2], zeigerpmkid->client[3], zeigerpmkid->client[4],
zeigerpmkid->client[5]);
for(p = 0; p < zeigermac->essidlen; p++)
fprintf(fh_pmkideapoljtrdeprecated, "%02x", zeigermac->essid[p]);
fprintf(fh_pmkideapoljtrdeprecated, "\n");
pmkidwrittenjcountdeprecated++;
}
if(fh_pmkiddeprecated != 0)
{
fprintf(fh_pmkiddeprecated, "%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*",
zeigerpmkid->pmkid[0], zeigerpmkid->pmkid[1], zeigerpmkid-
>pmkid[2], zeigerpmkid->pmkid[3], zeigerpmkid->pmkid[4], zeigerpmkid->pmkid[5],
zeigerpmkid->pmkid[6], zeigerpmkid->pmkid[7],
zeigerpmkid->pmkid[8], zeigerpmkid->pmkid[9], zeigerpmkid-
>pmkid[10], zeigerpmkid->pmkid[11], zeigerpmkid->pmkid[12], zeigerpmkid->pmkid[13],
zeigerpmkid->pmkid[14], zeigerpmkid->pmkid[15],
zeigerpmkid->ap[0], zeigerpmkid->ap[1], zeigerpmkid->ap[2],
zeigerpmkid->ap[3], zeigerpmkid->ap[4], zeigerpmkid->ap[5],
zeigerpmkid->client[0], zeigerpmkid->client[1],
zeigerpmkid->client[2], zeigerpmkid->client[3], zeigerpmkid->client[4],
zeigerpmkid->client[5]);
for(p = 0; p < zeigermac->essidlen; p++)
fprintf(fh_pmkiddeprecated, "%02x", zeigermac->essid[p]);
fprintf(fh_pmkiddeprecated, "\n");
pmkidwrittencountdeprecated++;
}
}
if(memcmp(zeigerpmkid->ap, zeigermac->addr, 6) > 0)
{
zeigerpmkidakt = zeigerpmkid;
return zeigerpmkidakt;
}
zeigerpmkidold = zeigerpmkid;
}
return zeigerpmkidakt;
}
/*===========================================================================*/
static void outputwpalists(void)
{
static maclist_t *zeigermac, *zeigermacold;
static handshakelist_t *zeigerhsakt;
static pmkidlist_t *zeigerpmkidakt;
static int essiddupecount;
eapolmpcount++;
if((mpfield &ST_APLESS) != ST_APLESS)
{
for(zeiger = messagelist; zeiger < messagelist +MESSAGELIST_MAX; zeiger++)
{
if((zeiger->status &ST_APLESS) != ST_APLESS)
{
if(memcmp(msgap->ap, zeiger->ap, 6) == 0) mpfield |= zeiger-
>status & 0xe0;
}
}
}
if(msgap->timestamp == msgclient->timestamp) eapolmsgtimestamperrorcount++;
if(testeapolpmk(zeroedpmk, keyver, msgclient->client, msgap->ap, msgap->nonce,
msgclient->eapauthlen, msgclient->eapol) == false)
{
if(handshakelistptr >= handshakelist +handshakelistmax)
{
handshakelistnew = (handshakelist_t*)realloc(handshakelist,
(handshakelistmax +HANDSHAKELIST_MAX) *HANDSHAKELIST_SIZE);
if(handshakelistnew == NULL)
{
fprintf(stderr, "failed to allocate memory for internal list\n");
exit(EXIT_FAILURE);
}
handshakelist = handshakelistnew;
handshakelistptr = handshakelistnew +handshakelistmax;
handshakelistmax += HANDSHAKELIST_MAX;
}
memset(handshakelistptr, 0, HANDSHAKELIST_SIZE);
handshakelistptr->timestampgap = eaptimegap;
handshakelistptr->status = mpfield;
handshakelistptr->rcgap = rcgap;
if(handshakelistptr->rcgap > 0) handshakelistptr->status |= ST_NC;
handshakelistptr->messageap = msgap->message;
handshakelistptr->messageclient = msgclient->message;
memcpy(handshakelistptr->ap, msgap->ap, 6);
memcpy(handshakelistptr->client, msgclient->client, 6);
memcpy(handshakelistptr->anonce, msgap->nonce, 32);
memcpy(handshakelistptr->pmkid, msgap->pmkid, 32);
handshakelistptr->eapauthlen = msgclient->eapauthlen;
memcpy(handshakelistptr->eapol, msgclient->eapol, msgclient->eapauthlen);
handshakelistptr->timestamp = msgclient->timestamp;
if(cleanbackhandshake() == false) handshakelistptr++;
}
else
{
zeroedeapolpmkcount++;
if(donotcleanflag == true)
{
if(handshakelistptr >= handshakelist +handshakelistmax)
{
handshakelistnew = (handshakelist_t*)realloc(handshakelist,
(handshakelistmax +HANDSHAKELIST_MAX) *HANDSHAKELIST_SIZE);
if(handshakelistnew == NULL)
{
fprintf(stderr, "failed to allocate memory for internal
list\n");
exit(EXIT_FAILURE);
}
handshakelist = handshakelistnew;
handshakelistptr = handshakelistnew +handshakelistmax;
handshakelistmax += HANDSHAKELIST_MAX;
}
memset(handshakelistptr, 0, HANDSHAKELIST_SIZE);
handshakelistptr->timestampgap = eaptimegap;
handshakelistptr->status = mpfield;
handshakelistptr->rcgap = rcgap;
if(handshakelistptr->rcgap > 0) handshakelistptr->status |= ST_NC;
handshakelistptr->messageap = msgap->message;
handshakelistptr->messageclient = msgclient->message;
memcpy(handshakelistptr->ap, msgap->ap, 6);
memcpy(handshakelistptr->client, msgclient->client, 6);
memcpy(handshakelistptr->anonce, msgap->nonce, 32);
memcpy(handshakelistptr->pmkid, msgap->pmkid, 32);
handshakelistptr->eapauthlen = msgclient->eapauthlen;
memcpy(handshakelistptr->eapol, msgclient->eapol, msgclient-
>eapauthlen);
handshakelistptr->timestamp = msgclient->timestamp;
if(cleanbackhandshake() == false) handshakelistptr++;
}
}
return;
}
/*===========================================================================*/
static bool cleanbackpmkid(void)
{
static int c;
static pmkidlist_t *zeiger;
pmkidcount++;
if(testpmkid(zeroedpmk, macclient, macap, pmkid) == false)
{
if(pmkidlistptr >= pmkidlist +pmkidlistmax)
{
pmkidlistnew = (pmkidlist_t*)realloc(pmkidlist, (pmkidlistmax
+PMKIDLIST_MAX) *PMKIDLIST_SIZE);
if(pmkidlistnew == NULL)
{
fprintf(stderr, "failed to allocate memory for internal list\n");
exit(EXIT_FAILURE);
}
pmkidlist = pmkidlistnew;
pmkidlistptr = pmkidlistnew +pmkidlistmax;
pmkidlistmax += PMKIDLIST_MAX;
}
memset(pmkidlistptr, 0, PMKIDLIST_SIZE);
memcpy(pmkidlistptr->ap, macap, 6);
memcpy(pmkidlistptr->client, macclient, 6);
memcpy(pmkidlistptr->pmkid, pmkid, 16);
pmkidlistptr->timestamp = timestamp;
pmkidlistptr->status |= pmkidstatus;
if(cleanbackpmkid() == false) pmkidlistptr++;
}
else
{
zeroedpmkidpmkcount++;
if(donotcleanflag == true)
{
if(pmkidlistptr >= pmkidlist +pmkidlistmax)
{
pmkidlistnew = (pmkidlist_t*)realloc(pmkidlist, (pmkidlistmax
+PMKIDLIST_MAX) *PMKIDLIST_SIZE);
if(pmkidlistnew == NULL)
{
fprintf(stderr, "failed to allocate memory for internal
list\n");
exit(EXIT_FAILURE);
}
pmkidlist = pmkidlistnew;
pmkidlistptr = pmkidlistnew +maclistmax;
pmkidlistmax += PMKIDLIST_MAX;
}
memset(pmkidlistptr, 0, PMKIDLIST_SIZE);
memcpy(pmkidlistptr->ap, macap, 6);
memcpy(pmkidlistptr->client, macclient, 6);
memcpy(pmkidlistptr->pmkid, pmkid, 16);
pmkidlistptr->status |= pmkidstatus;
if(cleanbackpmkid() == false) pmkidlistptr++;
}
}
return;
}
/*===========================================================================*/
static void process80211exteap(uint64_t eaptimestamp, uint8_t *macto, uint8_t
*macfm, uint32_t restlen, uint8_t *eapptr)
{
static eapauth_t *eapauth;
static uint32_t authlen;
static exteap_t *exteap;
static uint32_t exteaplen;
static uint32_t idstrlen;
eapcount++;
if(restlen < (int)EAPAUTH_SIZE) return;
eapauth = (eapauth_t*)eapptr;
authlen = ntohs(eapauth->len);
if(authlen > restlen) return;
exteap = (exteap_t*)(eapptr +EAPAUTH_SIZE);
exteaplen = ntohs(exteap->len);
if(exteaplen > authlen) return;
idstrlen = exteaplen -EXTEAP_SIZE;
if(exteap->type == EAP_TYPE_SIM) eapsimcount++;
else if(exteap->type == EAP_TYPE_AKA) eapakacount++;
else if(exteap->type == EAP_TYPE_PEAP) eappeapcount++;
else if(exteap->type == EAP_TYPE_TLS) eaptlscount++;
else if(exteap->type == EAP_TYPE_EXPAND) eapexpandedcount++;
else if(exteap->type == EAP_TYPE_MD5) processexteapmd5(eaptimestamp, macto, macfm,
exteap->code, exteaplen, eapptr +EAPAUTH_SIZE);
else if(exteap->type == EAP_TYPE_LEAP) processexteapleap(eaptimestamp, macto,
macfm, exteap->code, exteaplen, eapptr +EAPAUTH_SIZE);
else if(exteap->type == EAP_TYPE_MSEAP) processexteapmschapv2(eaptimestamp, macto,
macfm, exteap->code, exteaplen, eapptr +EAPAUTH_SIZE);
if(exteap->code == EAP_CODE_REQ)
{
eapcodereqcount++;
if(exteap->type == EAP_TYPE_ID)
{
if(idstrlen > 1)
{
if(eapptr[EAPAUTH_SIZE +EXTEAP_SIZE] != 0)
{
identitycount++;
if(fh_identity != NULL) fwritestring(idstrlen,
&eapptr[EAPAUTH_SIZE +EXTEAP_SIZE], fh_identity);
}
else if(eapptr[EAPAUTH_SIZE +EXTEAP_SIZE +1] != 0)
{
identitycount++;
if(fh_identity != NULL) fwritestring(idstrlen -1,
&eapptr[EAPAUTH_SIZE +EXTEAP_SIZE +1], fh_identity);
}
}
eapidcount++;
}
}
else if(exteap->code == EAP_CODE_RESP)
{
eapcoderespcount++;
if(exteap->type == EAP_TYPE_ID)
{
if(idstrlen > 1)
{
if(eapptr[EAPAUTH_SIZE +EXTEAP_SIZE] != 0)
{
identitycount++;
if(fh_identity != NULL) fwritestring(idstrlen,
&eapptr[EAPAUTH_SIZE +EXTEAP_SIZE], fh_identity);
}
else if(eapptr[EAPAUTH_SIZE +EXTEAP_SIZE +1] != 0)
{
identitycount++;
if(fh_identity != NULL) fwritestring(idstrlen -1,
&eapptr[EAPAUTH_SIZE +EXTEAP_SIZE +1], fh_identity);
}
}
eapidcount++;
}
}
return;
}
/*===========================================================================*/
static bool gettagwps(int wpslen, uint8_t *tagptr, tags_t *zeiger)
{
static wpsie_t *wpsptr;
wpslen -= WPSVENDOR_SIZE;
tagptr += WPSVENDOR_SIZE;
if(wpslen < (int)WPSIE_SIZE) return true;
zeiger->wpsinfo = 1;
wpsptr = (wpsie_t*)tagptr;
if(ntohs(wpsptr->type) != WPS_VERSION) return true;
if(ntohs(wpsptr->len) != 1) return true;
if(wpsptr->data[0] != 0x10) return true;
tagptr += ntohs(wpsptr->len) +WPSIE_SIZE;
wpslen -= ntohs(wpsptr->len) +WPSIE_SIZE;
while(0 < wpslen)
{
wpsptr = (wpsie_t*)tagptr;
if((ntohs(wpsptr->type) == WPS_MANUFACTURER) && (ntohs(wpsptr->len) > 0) &&
(ntohs(wpsptr->len) < DEVICE_INFO_MAX))
{
zeiger->manufacturerlen = ntohs(wpsptr->len);
memcpy(zeiger->manufacturer, wpsptr->data, zeiger->manufacturerlen);
}
else if((ntohs(wpsptr->type) == WPS_MODELNAME) && (ntohs(wpsptr->len) > 0) &&
(ntohs(wpsptr->len) < DEVICE_INFO_MAX))
{
zeiger->modellen = ntohs(wpsptr->len);
memcpy(zeiger->model, wpsptr->data, zeiger->modellen);
}
else if((ntohs(wpsptr->type) == WPS_SERIALNUMBER) && (ntohs(wpsptr->len) > 0)
&& (ntohs(wpsptr->len) < DEVICE_INFO_MAX))
{
zeiger->serialnumberlen = ntohs(wpsptr->len);
memcpy(zeiger->serialnumber, wpsptr->data, zeiger->serialnumberlen);
}
else if((ntohs(wpsptr->type) == WPS_DEVICENAME) && (ntohs(wpsptr->len) > 0)
&& (ntohs(wpsptr->len) < DEVICE_INFO_MAX))
{
zeiger->devicenamelen = ntohs(wpsptr->len);
memcpy(zeiger->devicename, wpsptr->data, zeiger->devicenamelen);
}
else if((ntohs(wpsptr->type) == WPS_UUIDE) && (ntohs(wpsptr->len) ==
WPS_ENROLLEE_LEN))
{
zeiger->enrolleelen = ntohs(wpsptr->len);
memcpy(zeiger->enrollee, wpsptr->data, zeiger->enrolleelen);
}
tagptr += ntohs(wpsptr->len) +WPSIE_SIZE;
wpslen -= ntohs(wpsptr->len) +WPSIE_SIZE;
}
if(wpslen != 0) return false;
return true;
}
/*===========================================================================*/
static bool gettagwpa(int wpalen, uint8_t *ieptr, tags_t *zeiger)
{
static int c;
static wpaie_t *wpaptr;
static int wpatype;
static suite_t *gsuiteptr;
static suitecount_t *csuitecountptr;
static suite_t *csuiteptr;
static int csuitecount;
static suitecount_t *asuitecountptr;
static suite_t *asuiteptr;
static int asuitecount;
wpaptr = (wpaie_t*)ieptr;
wpalen -= WPAIE_SIZE;
ieptr += WPAIE_SIZE;
#ifndef BIG_ENDIAN_HOST
wpatype = wpaptr->type;
#else
wpatype = byte_swap_16(wpaptr->type);
#endif
if(wpatype != VT_WPA_IE) return false;
zeiger->kdversion |= KV_WPAIE;
gsuiteptr = (suite_t*)ieptr;
if(memcmp(gsuiteptr->oui, &ouimscorp, 3) == 0)
{
if(gsuiteptr->type == CS_WEP40) zeiger->groupcipher |= TCS_WEP40;
if(gsuiteptr->type == CS_TKIP) zeiger->groupcipher |= TCS_TKIP;
if(gsuiteptr->type == CS_WRAP) zeiger->groupcipher |= TCS_WRAP;
if(gsuiteptr->type == CS_CCMP) zeiger->groupcipher |= TCS_CCMP;
if(gsuiteptr->type == CS_WEP104) zeiger->groupcipher |= TCS_WEP104;
if(gsuiteptr->type == CS_BIP) zeiger->groupcipher |= TCS_BIP;
if(gsuiteptr->type == CS_NOT_ALLOWED) zeiger->groupcipher = TCS_NOT_ALLOWED;
}
wpalen -= SUITE_SIZE;
ieptr += SUITE_SIZE;
csuitecountptr = (suitecount_t*)ieptr;
wpalen -= SUITECOUNT_SIZE;
ieptr += SUITECOUNT_SIZE;
#ifndef BIG_ENDIAN_HOST
csuitecount = csuitecountptr->count;
#else
csuitecount = byte_swap_16(csuitecountptr->count);
#endif
if(csuitecount *4 > wpalen)
{
taglenerrorcount++;
return false;
}
for(c = 0; c < csuitecount; c++)
{
csuiteptr = (suite_t*)ieptr;
if(memcmp(csuiteptr->oui, &ouimscorp, 3) == 0)
{
if(csuiteptr->type == CS_WEP40) zeiger->cipher |= TCS_WEP40;
if(csuiteptr->type == CS_TKIP) zeiger->cipher |= TCS_TKIP;
if(csuiteptr->type == CS_WRAP) zeiger->cipher |= TCS_WRAP;
if(csuiteptr->type == CS_CCMP) zeiger->cipher |= TCS_CCMP;
if(csuiteptr->type == CS_WEP104) zeiger->cipher |= TCS_WEP104;
if(csuiteptr->type == CS_BIP) zeiger->cipher |= TCS_BIP;
if(csuiteptr->type == CS_NOT_ALLOWED) zeiger->cipher |=
TCS_NOT_ALLOWED;
}
wpalen -= SUITE_SIZE;
ieptr += SUITE_SIZE;
if(wpalen == 0) return true;
if(wpalen < 0) return false;
}
asuitecountptr = (suitecount_t*)ieptr;
wpalen -= SUITECOUNT_SIZE;
ieptr += SUITECOUNT_SIZE;
#ifndef BIG_ENDIAN_HOST
asuitecount = asuitecountptr->count;
#else
asuitecount = byte_swap_16(asuitecountptr->count);
#endif
if(asuitecount *4 > wpalen)
{
taglenerrorcount++;
return false;
}
for(c = 0; c < asuitecount; c++)
{
asuiteptr = (suite_t*)ieptr;
if(memcmp(asuiteptr->oui, &ouimscorp, 3) == 0)
{
if(asuiteptr->type == AK_PMKSA) zeiger->akm |= TAK_PMKSA;
if(asuiteptr->type == AK_PSK) zeiger->akm |= TAK_PSK;
if(asuiteptr->type == AK_FT) zeiger->akm |= TAK_FT;
if(asuiteptr->type == AK_FT_PSK) zeiger->akm |= TAK_FT_PSK;
if(asuiteptr->type == AK_PMKSA256) zeiger->akm |= TAK_PMKSA256;
if(asuiteptr->type == AK_PSKSHA256) zeiger->akm |= TAK_PSKSHA256;
if(asuiteptr->type == AK_TDLS) zeiger->akm |= TAK_TDLS;
if(asuiteptr->type == AK_SAE_SHA256) zeiger->akm |= TAK_SAE_SHA256;
if(asuiteptr->type == AK_FT_SAE) zeiger->akm |= TAK_FT_SAE;
if(asuiteptr->type == AK_SAE_SHA384B) zeiger->akm |= TAK_SAE_SHA384B;
if(asuiteptr->type == AK_OWE) zeiger->akm |= TAK_OWE;
}
wpalen -= SUITE_SIZE;
ieptr += SUITE_SIZE;
if(wpalen == 0) return true;
if(wpalen < 0) return false;
}
return true;
}
/*===========================================================================*/
static bool gettagvendor(int vendorlen, uint8_t *ieptr, tags_t *zeiger)
{
static wpaie_t *wpaptr;
wpaptr = (wpaie_t*)ieptr;
if(memcmp(wpaptr->oui, &ouimscorp, 3) == 0)
{
if((wpaptr->ouitype == VT_WPA_IE) && (vendorlen >= WPAIE_LEN_MIN))
{
if(gettagwpa(vendorlen, ieptr, zeiger) == false) return false;
return true;
}
if((wpaptr->ouitype == VT_WPS_IE) && (vendorlen >= (int)WPSIE_SIZE))
{
if(gettagwps(vendorlen, ieptr, zeiger) == false) return false;
return true;
}
return true;
}
if(vendorlen == 0x17)
{
if(memcmp(&hcxoui, ieptr, 0x17) == 0) beaconhcxcount++;
}
return true;
}
/*===========================================================================*/
static bool gettagrsn(int rsnlen, uint8_t *ieptr, tags_t *zeiger)
{
static int c;
static rsnie_t *rsnptr;
static int rsnver;
static suite_t *gsuiteptr;
static suitecount_t *csuitecountptr;
static suite_t *csuiteptr;
static int csuitecount;
static suitecount_t *asuitecountptr;
static suite_t *asuiteptr;
static int asuitecount;
static rsnpmkidlist_t *rsnpmkidlistptr;
static int rsnpmkidcount;
rsnptr = (rsnie_t*)ieptr;
#ifndef BIG_ENDIAN_HOST
rsnver = rsnptr->version;
#else
rsnver = byte_swap_16(rsnptr->version);
#endif
if(rsnver != 1) return true;
zeiger->kdversion |= KV_RSNIE;
rsnlen -= RSNIE_SIZE;
ieptr += RSNIE_SIZE;
gsuiteptr = (suite_t*)ieptr;
if(memcmp(gsuiteptr->oui, &suiteoui, 3) == 0)
{
if(gsuiteptr->type == CS_WEP40) zeiger->groupcipher |= TCS_WEP40;
if(gsuiteptr->type == CS_TKIP) zeiger->groupcipher |= TCS_TKIP;
if(gsuiteptr->type == CS_WRAP) zeiger->groupcipher |= TCS_WRAP;
if(gsuiteptr->type == CS_CCMP) zeiger->groupcipher |= TCS_CCMP;
if(gsuiteptr->type == CS_GCMP) zeiger->groupcipher |= TCS_GCMP;
if(gsuiteptr->type == CS_WEP104) zeiger->groupcipher |= TCS_WEP104;
if(gsuiteptr->type == CS_BIP) zeiger->groupcipher |= TCS_BIP;
if(gsuiteptr->type == CS_NOT_ALLOWED) zeiger->groupcipher |= TCS_NOT_ALLOWED;
}
rsnlen -= SUITE_SIZE;
ieptr += SUITE_SIZE;
csuitecountptr = (suitecount_t*)ieptr;
rsnlen -= SUITECOUNT_SIZE;
ieptr += SUITECOUNT_SIZE;
#ifndef BIG_ENDIAN_HOST
csuitecount = csuitecountptr->count;
#else
csuitecount = byte_swap_16(csuitecountptr->count);
#endif
if(csuitecount *4 > rsnlen)
{
taglenerrorcount++;
return false;
}
for(c = 0; c < csuitecount; c++)
{
csuiteptr = (suite_t*)ieptr;
if(memcmp(csuiteptr->oui, &suiteoui, 3) == 0)
{
if(csuiteptr->type == CS_WEP40) zeiger->cipher |= TCS_WEP40;
if(csuiteptr->type == CS_TKIP) zeiger->cipher |= TCS_TKIP;
if(csuiteptr->type == CS_WRAP) zeiger->cipher |= TCS_WRAP;
if(csuiteptr->type == CS_CCMP) zeiger->cipher |= TCS_CCMP;
if(csuiteptr->type == CS_GCMP) zeiger->cipher |= TCS_GCMP;
if(csuiteptr->type == CS_WEP104) zeiger->cipher |= TCS_WEP104;
if(csuiteptr->type == CS_BIP) zeiger->cipher |= TCS_BIP;
if(csuiteptr->type == CS_NOT_ALLOWED) zeiger->cipher |=
TCS_NOT_ALLOWED;
}
rsnlen -= SUITE_SIZE;
ieptr += SUITE_SIZE;
if(rsnlen < 0) return false;
if(rsnlen == 0) return true;
}
asuitecountptr = (suitecount_t*)ieptr;
rsnlen -= SUITECOUNT_SIZE;
ieptr += SUITECOUNT_SIZE;
#ifndef BIG_ENDIAN_HOST
asuitecount = asuitecountptr->count;
#else
asuitecount = byte_swap_16(asuitecountptr->count);
#endif
if(asuitecount *4 > rsnlen)
{
taglenerrorcount++;
return false;
}
for(c = 0; c < asuitecount; c++)
{
asuiteptr = (suite_t*)ieptr;
if(memcmp(asuiteptr->oui, &suiteoui, 3) == 0)
{
if(asuiteptr->type == AK_PMKSA) zeiger->akm |= TAK_PMKSA;
if(asuiteptr->type == AK_PSK) zeiger->akm |= TAK_PSK;
if(asuiteptr->type == AK_FT) zeiger->akm |= TAK_FT;
if(asuiteptr->type == AK_FT_PSK) zeiger->akm |= TAK_FT_PSK;
if(asuiteptr->type == AK_PMKSA256) zeiger->akm |= TAK_PMKSA256;
if(asuiteptr->type == AK_PSKSHA256) zeiger->akm |= TAK_PSKSHA256;
if(asuiteptr->type == AK_TDLS) zeiger->akm |= TAK_TDLS;
if(asuiteptr->type == AK_SAE_SHA256) zeiger->akm |= TAK_SAE_SHA256;
if(asuiteptr->type == AK_FT_SAE) zeiger->akm |= TAK_FT_SAE;
if(asuiteptr->type == AK_SAE_SHA384B) zeiger->akm |= TAK_SAE_SHA384B;
if(asuiteptr->type == AK_OWE) zeiger->akm |= TAK_OWE;
}
rsnlen -= SUITE_SIZE;
ieptr += SUITE_SIZE;
if(rsnlen < 0) return false;
if(rsnlen == 0) return true;
}
rsnlen -= RSNCAPABILITIES_SIZE;
ieptr += RSNCAPABILITIES_SIZE;
if(rsnlen <= 0) return true;
rsnpmkidlistptr = (rsnpmkidlist_t*)ieptr;
#ifndef BIG_ENDIAN_HOST
rsnpmkidcount = rsnpmkidlistptr->count;
#else
rsnpmkidcount = byte_swap_16(rsnpmkidlistptr->count);
#endif
if(rsnpmkidcount == 0) return true;
rsnlen -= RSNPMKIDLIST_SIZE;
ieptr += RSNPMKIDLIST_SIZE;
if(rsnlen < 16) return true;
if(((zeiger->akm &TAK_PSK) == TAK_PSK) || ((zeiger->akm &TAK_PSKSHA256) ==
TAK_PSKSHA256))
{
if(memcmp(&zeroed32, ieptr, 16) == 0) return true;
for(c = 0; c < 12; c++)
{
if(memcmp(&zeroed32, &ieptr[c], 4) == 0) return false;
if(memcmp(&foxtrott, &ieptr[c], 4) == 0) return false;
}
memcpy(zeiger->pmkid, ieptr, 16);
}
return true;
}
/*===========================================================================*/
static bool isessidvalid(int essidlen, uint8_t *essid)
{
static int c;
static const uint8_t foxtrott[4] = { 0xff, 0xff, 0xff, 0xff };
memset(zeiger, 0, TAGS_SIZE);
ef = false;
while(0 < infolen)
{
if(infolen == 4) return true;
tagptr = (ietag_t*)infoptr;
if(tagptr->len == 0)
{
infoptr += tagptr->len +IETAG_SIZE;
infolen -= tagptr->len +IETAG_SIZE;
continue;
}
if(tagptr->len > infolen) return false;
if(tagptr->id == TAG_SSID)
{
if(tagptr->len > ESSID_LEN_MAX)
{
taglenerrorcount++;
return false;
}
if(isessidvalid(tagptr->len, &tagptr->data[0]) == false) return false;
{
ef = true;
memcpy(zeiger->essid, &tagptr->data[0], tagptr->len);
zeiger->essidlen = tagptr->len;
}
}
else if(tagptr->id == TAG_CHAN)
{
if(tagptr->len == 1) zeiger->channel = tagptr->data[0];
}
else if(tagptr->id == TAG_COUNTRY)
{
if(tagptr->len > 2)
{
zeiger->country[0] = tagptr->data[0];
zeiger->country[1] = tagptr->data[1];
}
}
else if(tagptr->id == TAG_RSN)
{
if(tagptr->len >= RSNIE_LEN_MIN)
{
if(gettagrsn(tagptr->len, tagptr->data, zeiger) == false) return
false;
}
}
else if(tagptr->id == TAG_VENDOR)
{
if(tagptr->len >= VENDORIE_SIZE)
{
if(gettagvendor(tagptr->len, tagptr->data, zeiger) == false)
return false;
}
}
infoptr += tagptr->len +IETAG_SIZE;
infolen -= tagptr->len +IETAG_SIZE;
}
if((infolen != 0) && (infolen != 4) && (ef == false)) return false;
return true;
}
/*===========================================================================*/
static void process80211eapol_m4(uint64_t eaptimestamp, uint8_t *macap, uint8_t
*macclient, uint32_t restlen, uint8_t *eapauthptr)
{
static int c;
static messagelist_t *zeiger;
static uint8_t *wpakptr;
static wpakey_t *wpak;
static eapauth_t *eapauth;
static uint32_t authlen;
static uint64_t eaptimegap;
static uint8_t keyver;
static uint64_t rc;
static uint64_t rcgap;
static uint8_t mpfield;
eapolm3count++;
eapolmsgcount++;
zeigerakt = messagelist +MESSAGELIST_MAX;
eapauth = (eapauth_t*)eapauthptr;
authlen = ntohs(eapauth->len);
if(authlen > restlen) return;
wpakptr = eapauthptr +EAPAUTH_SIZE;
wpak = (wpakey_t*)wpakptr;
keyver = ntohs(wpak->keyinfo) & WPA_KEY_INFO_TYPE_MASK;
if((keyver == 0) || (keyver > 3))
{
eapolm3kdv0count++;
return;
}
if(ntohs(wpak->wpadatalen) > (restlen -EAPAUTH_SIZE -WPAKEY_SIZE))
{
if(fh_log != NULL) fprintf(fh_log, "EAPOL M3 wpa data len > eap
authentication len: %ld\n", rawpacketcount);
eapolm3errorcount++;
return;
}
#ifndef BIG_ENDIAN_HOST
rc = byte_swap_64(wpak->replaycount);
#else
rc = wpak->replaycount;
#endif
if(memcmp(&zeroed32, wpak->keymic, 16) == 0)
{
if(fh_log != NULL) fprintf(fh_log, "EAPOL M3 key mic zeroed: %ld\n",
rawpacketcount);
eapolm3errorcount++;
return;
}
for(c = 0; c < 12; c++)
{
if(memcmp(&zeroed32, &wpak->keymic[c], 4) == 0)
{
if(fh_log != NULL) fprintf(fh_log, "EAPOL M3 key mic possible plcp bit
error: %ld\n", rawpacketcount);
eapolm3errorcount++;
return;
}
if(memcmp(&foxtrott, &wpak->keymic[c], 4) == 0)
{
if(fh_log != NULL) fprintf(fh_log, "EAPOL M3 key mic possible plcp bit
error: %ld\n", rawpacketcount);
eapolm3errorcount++;
return;
}
}
if(memcmp(&zeroed32, wpak->keyid, 8) != 0)
{
if(fh_log != NULL) fprintf(fh_log, "EAPOL M3 key id != 0: %ld\n",
rawpacketcount);
eapolm3errorcount++;
return;
}
memset(zeigerakt, 0, MESSAGELIST_SIZE);
zeigerakt->timestamp = eaptimestamp;
zeigerakt->eapolmsgcount = eapolmsgcount;
memcpy(zeigerakt->client, macclient, 6);
memcpy(zeigerakt->ap, macap, 6);
zeigerakt->message = HS_M3;
zeigerakt->rc = rc;
memcpy(zeigerakt->nonce, wpak->nonce, 32);
for(zeiger = messagelist; zeiger < messagelist +MESSAGELIST_MAX; zeiger++)
{
if(((zeiger->message &HS_M1) == HS_M1) || ((zeiger->message &HS_M3) ==
HS_M3))
{
if((memcmp(zeiger->nonce, wpak->nonce, 28) == 0) && (memcmp(&zeiger-
>nonce[29], &wpak->nonce[29], 4) != 0))
{
zeiger->status |= ST_NC;
zeigerakt->status |= ST_NC;
if(zeiger->nonce[31] != wpak->nonce[31]) zeiger->status |= ST_LE;
else if(zeiger->nonce[28] != wpak->nonce[28]) zeiger->status |=
ST_BE;
eapolnccount++;
}
}
if((zeiger->message &HS_M2) == HS_M2)
{
if(memcmp(zeiger->ap, macap, 6) != 0) continue;
if(memcmp(zeiger->client, macclient, 6) != 0) continue;
if(zeiger->rc >= rc -1) rcgap = zeiger->rc -rc +1;
else rcgap = rc +1 -zeiger->rc;
if(zeiger->rc != myaktreplaycount)
{
if(rcgap > rcgapmax) rcgapmax = rcgap;
}
if(rcgap > ncvalue) continue;
if(eaptimestamp > zeiger->timestamp) eaptimegap = eaptimestamp -zeiger-
>timestamp;
else eaptimegap = zeiger->timestamp -eaptimestamp;
mpfield = ST_M32E2;
if(myaktreplaycount > 0)
{
if(zeiger->rc == myaktreplaycount) continue;
}
if(eaptimegap > eaptimegapmax) eaptimegapmax = eaptimegap;
if(eaptimegap <= eapoltimeoutvalue) addhandshake(eaptimegap, rcgap,
zeiger, messagelist +MESSAGELIST_MAX, keyver, mpfield);
}
if((zeiger->message &HS_M4) != HS_M4) continue;
if(memcmp(zeiger->ap, macap, 6) != 0) continue;
if(memcmp(zeiger->client, macclient, 6) != 0) continue;
if(zeiger->rc >= rc) rcgap = zeiger->rc -rc;
else rcgap = rc -zeiger->rc;
if(rcgap > rcgapmax) rcgapmax = rcgap;
if(rcgap > ncvalue) continue;
if(eaptimestamp > zeiger->timestamp) eaptimegap = eaptimestamp -zeiger-
>timestamp;
else eaptimegap = zeiger->timestamp -eaptimestamp;
mpfield = ST_M34E4;
if(myaktreplaycount > 0)
{
if(zeiger->rc == myaktreplaycount) continue;
}
if(eaptimegap > eaptimegapmax) eaptimegapmax = eaptimegap;
if(eaptimegap <= eapoltimeoutvalue) addhandshake(eaptimegap, rcgap, zeiger,
messagelist +MESSAGELIST_MAX, keyver, mpfield);
}
qsort(messagelist, MESSAGELIST_MAX +1, MESSAGELIST_SIZE,
sort_messagelist_by_epcount);
return;
}
/*===========================================================================*/
static void process80211eapol_m2(uint64_t eaptimestamp, uint8_t *macap, uint8_t
*macclient, uint32_t restlen, uint8_t *eapauthptr)
{
static int c;
static messagelist_t *zeiger;
static uint8_t *wpakptr;
static wpakey_t *wpak;
static eapauth_t *eapauth;
static uint32_t authlen;
static uint64_t eaptimegap;
static uint8_t keyver;
static uint64_t rc;
static uint64_t rcgap;
static uint8_t mpfield;
static uint16_t wpainfolen;
static tags_t tags;
eapolm1count++;
eapolmsgcount++;
eapauth = (eapauth_t*)eapauthptr;
authlen = ntohs(eapauth->len);
if(authlen > restlen) return;
wpakptr = eapauthptr +EAPAUTH_SIZE;
wpak = (wpakey_t*)wpakptr;
keyver = ntohs(wpak->keyinfo) & WPA_KEY_INFO_TYPE_MASK;
if((keyver == 0) || (keyver > 3))
{
eapolm1kdv0count++;
if(authlen >= (int)(WPAKEY_SIZE +PMKID_SIZE))
{
pmkid = (pmkid_t*)(wpakptr +WPAKEY_SIZE);
if(pmkid->id != TAG_VENDOR) return;
if((pmkid->len == 0x14) && (pmkid->type == 0x04))
{
if(memcmp(&zeroed32, pmkid->pmkid, 16) == 0)
{
pmkiduselesscount++;
}
else
{
pmkidakmcount++;
pmkidcount++;
}
}
}
return;
}
if(ntohs(wpak->wpadatalen) > (restlen -EAPAUTH_SIZE -WPAKEY_SIZE))
{
if(fh_log != NULL) fprintf(fh_log, "EAPOL M1 wpa data len > eap
authentication len: %ld\n", rawpacketcount);
eapolm1errorcount++;
return;
}
#ifndef BIG_ENDIAN_HOST
rc = byte_swap_64(wpak->replaycount);
#else
rc = wpak->replaycount;
#endif
if(wpak->keyrsc != 0)
{
if(fh_log != NULL) fprintf(fh_log, "EAPOL M1 key rc != 0: %ld\n",
rawpacketcount);
eapolm1errorcount++;
return;
}
if(memcmp(&zeroed32, wpak->keyid, 8) != 0)
{
if(fh_log != NULL) fprintf(fh_log, "EAPOL M1 key id != 0: %ld\n",
rawpacketcount);
eapolm1errorcount++;
return;
}
if((memcmp(&fakenonce1, wpak->nonce, 32) == 0) && (rc == 17)) return;
if((memcmp(&fakenonce2, wpak->nonce, 32) == 0) && (rc == 17)) return;
zeiger = messagelist +MESSAGELIST_MAX;
memset(zeiger, 0, MESSAGELIST_SIZE);
zeiger->timestamp = eaptimestamp;
zeiger->eapolmsgcount = eapolmsgcount;
memcpy(zeiger->client, macclient, 6);
memcpy(zeiger->ap, macap, 6);
zeiger->message = HS_M1;
zeiger->rc = rc;
memcpy(zeiger->nonce, wpak->nonce, 32);
eapauth = (eapauth_t*)eapauthptr;
authlen = ntohs(eapauth->len);
if(authlen > eapauthlen)
{
eapolmsgerrorcount++;
return;
}
wpakptr = eapauthptr +EAPAUTH_SIZE;
wpak = (wpakey_t*)wpakptr;
keyinfo = (getkeyinfo(ntohs(wpak->keyinfo)));
if(wpak->keydescriptor == EAP_KDT_RC4)
{
process80211rc4key();
return;
}
else if(wpak->keydescriptor == EAP_KDT_WPA) eapolwpacount++;
else if(wpak->keydescriptor == EAP_KDT_RSN) eapolrsncount++;
else return;
if(authlen < WPAKEY_SIZE)
{
eapolmsgerrorcount++;
return;
}
keylen = ntohs(wpak->keylen);
if((keylen != 0) && (keylen != 16) && (keylen != 32))
{
eapolmsgerrorcount++;
return;
}
if(keyinfo == 1) process80211eapol_m1(eaptimestamp, macto, macfm, macsrc,
eapauthlen, eapauthptr);
else if(keyinfo == 2)
{
if(authlen != 0x5f) process80211eapol_m2(eaptimestamp, macto, macfm,
eapauthlen, eapauthptr);
else process80211eapol_m4(eaptimestamp, macto, macfm, eapauthlen,
eapauthptr);
}
else if(keyinfo == 3) process80211eapol_m3(eaptimestamp, macto, macfm, eapauthlen,
eapauthptr);
else if(keyinfo == 4) process80211eapol_m4(eaptimestamp, macto, macfm, eapauthlen,
eapauthptr);
return;
}
/*===========================================================================*/
static void process80211eap(uint64_t eaptimestamp, uint8_t *macto, uint8_t *macfm,
uint8_t *macsrc, uint32_t restlen, uint8_t *eapptr)
{
static eapauth_t *eapauth;
eapauth = (eapauth_t*)eapptr;
if(restlen < (int)EAPAUTH_SIZE) return;
if(eapauth->type == EAPOL_KEY)
{
process80211eapol(eaptimestamp, macto, macfm, macsrc, restlen, eapptr);
}
else if(eapauth->type == EAP_PACKET) process80211exteap(eaptimestamp, macto, macfm,
restlen, eapptr);
//else if(eapauth->type == EAPOL_ASF) process80211exteap_asf();
//else if(eapauth->type == EAPOL_MKA) process80211exteap_mka();
else if(eapauth->type == EAPOL_START)
{
}
else if(eapauth->type == EAPOL_START)
{
}
else if(eapauth->type == EAPOL_LOGOFF)
{
}
if(fh_nmea != NULL) writegpwpl(macfm);
return;
}
/*===========================================================================*/
static bool cleanbackmac(void)
{
static int c;
static maclist_t *zeiger;
zeiger = aplistptr;
for(c = 0; c < 20; c ++)
{
zeiger--;
if(zeiger < aplist) return false;
if(zeiger->type != aplistptr->type) continue;
if(zeiger->essidlen != aplistptr->essidlen) continue;
if(memcmp(zeiger->addr, aplistptr->addr, 6) != 0) continue;
if(memcmp(zeiger->essid, aplistptr->essid, aplistptr->essidlen) != 0)
continue;
zeiger->timestamp = aplistptr->timestamp;
zeiger->count += 1;
zeiger->status |= aplistptr->status;
zeiger->type |= aplistptr->type;
zeiger->groupcipher |= aplistptr->groupcipher;
zeiger->cipher |= aplistptr->cipher;
zeiger->akm |= aplistptr->akm;
if(zeiger->manufacturerlen == 0)
{
memcpy(zeiger->manufacturer, aplistptr->manufacturer, aplistptr-
>manufacturerlen);
zeiger->manufacturerlen = aplistptr->manufacturerlen;
}
if(zeiger->modellen == 0)
{
memcpy(zeiger->model, aplistptr->model, aplistptr->modellen);
zeiger->modellen = aplistptr->modellen;
}
if(zeiger->serialnumberlen == 0)
{
memcpy(zeiger->serialnumber, aplistptr->serialnumber, aplistptr-
>serialnumberlen);
zeiger->serialnumberlen = aplistptr->serialnumberlen;
}
if(zeiger->devicenamelen == 0)
{
memcpy(zeiger->devicename, aplistptr->devicename, aplistptr-
>devicenamelen);
zeiger->devicenamelen = aplistptr->devicenamelen;
}
if(zeiger->enrolleelen == 0)
{
memcpy(zeiger->enrollee, aplistptr->enrollee, aplistptr->enrolleelen);
zeiger->enrolleelen = aplistptr->enrolleelen;
}
return true;
}
return false;
}
/*===========================================================================*/
static void process80211reassociation_req(uint64_t reassociationrequesttimestamp,
uint8_t *macclient, uint8_t *macap, uint32_t reassociationrequestlen, uint8_t
*reassociationrequestptr)
{
static int clientinfolen;
static uint8_t *clientinfoptr;
static maclist_t *aplistnew;
static tags_t tags;
reassociationrequestcount++;
clientinfoptr = reassociationrequestptr +CAPABILITIESREQSTA_SIZE;
clientinfolen = reassociationrequestlen -CAPABILITIESREQSTA_SIZE;
if(clientinfolen < (int)IETAG_SIZE) return;
if(gettags(clientinfolen, clientinfoptr, &tags) == false) return;
if(tags.essidlen == 0) return;
if(tags.essid[0] == 0) return;
if(aplistptr >= aplist +maclistmax)
{
aplistnew = (maclist_t*)realloc(aplist, (maclistmax +MACLIST_MAX)
*MACLIST_SIZE);
if(aplistnew == NULL)
{
fprintf(stderr, "failed to allocate memory for internal list\n");
exit(EXIT_FAILURE);
}
aplist = aplistnew;
aplistptr = aplistnew +maclistmax;
maclistmax += MACLIST_MAX;
}
if(fh_nmea != NULL) writegpwpl(macclient);
memset(aplistptr, 0, MACLIST_SIZE);
aplistptr->timestamp = reassociationrequesttimestamp;
aplistptr->count = 1;
aplistptr->type = AP;
memcpy(aplistptr->addr, macap, 6);
aplistptr->essidlen = tags.essidlen;
memcpy(aplistptr->essid, tags.essid, tags.essidlen);
aplistptr->groupcipher = tags.groupcipher;
aplistptr->cipher = tags.cipher;
aplistptr->akm = tags.akm;
if(ignoreieflag == true)
{
if(memcmp(&zeroed32, tags.pmkid, 16) != 0)
addpmkid(reassociationrequesttimestamp, macclient, macap, tags.pmkid,
PMKID_CLIENT);
}
else if(((tags.akm &TAK_PSK) == TAK_PSK) || ((tags.akm &TAK_PSKSHA256) ==
TAK_PSKSHA256))
{
if(memcmp(&zeroed32, tags.pmkid, 16) != 0)
addpmkid(reassociationrequesttimestamp, macclient, macap, tags.pmkid,
PMKID_CLIENT);
}
else if((tags.akm &TAK_FT_PSK) == TAK_FT_PSK) reassociationrequestftpskcount++;
associationrequestcount++;
clientinfoptr = associationrequestptr +CAPABILITIESSTA_SIZE;
clientinfolen = associationrequestlen -CAPABILITIESSTA_SIZE;
if(clientinfolen < (int)IETAG_SIZE) return;
if(gettags(clientinfolen, clientinfoptr, &tags) == false) return;
if(tags.essidlen == 0) return;
if(tags.essid[0] == 0) return;
if(aplistptr >= aplist +maclistmax)
{
aplistnew = (maclist_t*)realloc(aplist, (maclistmax +MACLIST_MAX)
*MACLIST_SIZE);
if(aplistnew == NULL)
{
fprintf(stderr, "failed to allocate memory for internal list\n");
exit(EXIT_FAILURE);
}
aplist = aplistnew;
aplistptr = aplistnew +maclistmax;
maclistmax += MACLIST_MAX;
}
memset(aplistptr, 0, MACLIST_SIZE);
aplistptr->timestamp = associationrequesttimestamp;
aplistptr->count = 1;
aplistptr->status = ST_ASSOC_REQ;
aplistptr->type = AP;
memcpy(aplistptr->addr, macap, 6);
aplistptr->essidlen = tags.essidlen;
memcpy(aplistptr->essid, tags.essid, tags.essidlen);
aplistptr->groupcipher = tags.groupcipher;
aplistptr->cipher = tags.cipher;
aplistptr->akm = tags.akm;
if(ignoreieflag == true)
{
if(memcmp(&zeroed32, tags.pmkid, 16) != 0)
addpmkid(associationrequesttimestamp, macclient, macap, tags.pmkid, PMKID_CLIENT);
}
else if(((tags.akm &TAK_PSK) == TAK_PSK) || ((tags.akm &TAK_PSKSHA256) ==
TAK_PSKSHA256))
{
if(memcmp(&zeroed32, tags.pmkid, 16) != 0)
addpmkid(associationrequesttimestamp, macclient, macap, tags.pmkid, PMKID_CLIENT);
}
if((tags.akm &TAK_PSK) == TAK_PSK) associationrequestpskcount++;
else if((tags.akm &TAK_FT_PSK) == TAK_FT_PSK) associationrequestftpskcount++;
else if((tags.akm &TAK_PSKSHA256) == TAK_PSKSHA256) associationrequestpsk256count+
+;
else if((tags.akm &TAK_SAE_SHA256) == TAK_SAE_SHA256)
associationrequestsae256count++;
else if((tags.akm &TAK_SAE_SHA384B) == TAK_SAE_SHA384B)
associationrequestsae384bcount++;
else if((tags.akm &TAK_OWE) == TAK_OWE) associationrequestowecount++;
if(cleanbackmac() == false) aplistptr++;
if(aplistptr >= aplist +maclistmax)
{
aplistnew = (maclist_t*)realloc(aplist, (maclistmax +MACLIST_MAX)
*MACLIST_SIZE);
if(aplistnew == NULL)
{
fprintf(stderr, "failed to allocate memory for internal list\n");
exit(EXIT_FAILURE);
}
aplist = aplistnew;
aplistptr = aplistnew +maclistmax;
maclistmax += MACLIST_MAX;
}
memset(aplistptr, 0, MACLIST_SIZE);
aplistptr->timestamp = associationrequesttimestamp;
aplistptr->count = 1;
aplistptr->status = ST_ASSOC_REQ;
aplistptr->type = CLIENT;
memcpy(aplistptr->addr, macclient, 6);
aplistptr->essidlen = tags.essidlen;
memcpy(aplistptr->essid, tags.essid, tags.essidlen);
aplistptr->groupcipher = tags.groupcipher;
aplistptr->cipher = tags.cipher;
aplistptr->akm = tags.akm;
if(cleanbackmac() == false) aplistptr++;
if(fh_nmea != NULL) writegpwpl(macclient);
return;
}
/*===========================================================================*/
static inline void process80211authentication(uint8_t *macfm, uint32_t
authenticationlen, uint8_t *authenticationptr)
{
static authf_t *auth;
authenticationcount++;
auth = (authf_t*)authenticationptr;
if(authenticationlen < (int)AUTHENTICATIONFRAME_SIZE) return;
if(auth->algorithm == OPEN_SYSTEM) authopensystemcount++;
else if(auth->algorithm == SAE) authseacount++;
else if(auth->algorithm == SHARED_KEY) authsharedkeycount++;
else if(auth->algorithm == FBT) authfbtcount++;
else if(auth->algorithm == FILS) authfilscount++;
else if(auth->algorithm == FILSPFS) authfilspfs++;
else if(auth->algorithm == FILSPK) authfilspkcount++;
else if(auth->algorithm == NETWORKEAP) authnetworkeapcount++;
else authunknowncount++;
if(fh_nmea != NULL) writegpwpl(macfm);
return;
}
/*===========================================================================*/
static void process80211probe_req_direct(uint64_t proberequesttimestamp, uint8_t
*macclient, uint8_t *macap, uint32_t proberequestlen, uint8_t *proberequestptr)
{
static maclist_t *aplistnew;
static tags_t tags;
proberequestdirectedcount++;
if(proberequestlen < (int)IETAG_SIZE) return;
if(gettags(proberequestlen, proberequestptr, &tags) == false) return;
if(tags.essidlen == 0) return;
if(tags.essid[0] == 0) return;
if(aplistptr >= aplist +maclistmax)
{
aplistnew = (maclist_t*)realloc(aplist, (maclistmax +MACLIST_MAX)
*MACLIST_SIZE);
if(aplistnew == NULL)
{
fprintf(stderr, "failed to allocate memory for internal list\n");
exit(EXIT_FAILURE);
}
aplist = aplistnew;
aplistptr = aplistnew +maclistmax;
maclistmax += MACLIST_MAX;
}
memset(aplistptr, 0, MACLIST_SIZE);
aplistptr->timestamp = proberequesttimestamp;
aplistptr->count = 1;
aplistptr->status = ST_PROBE_REQ;
aplistptr->type = AP;
memcpy(aplistptr->addr, macap, 6);
aplistptr->essidlen = tags.essidlen;
memcpy(aplistptr->essid, tags.essid, tags.essidlen);
if(cleanbackmac() == false) aplistptr++;
if(aplistptr >= aplist +maclistmax)
{
aplistnew = (maclist_t*)realloc(aplist, (maclistmax +MACLIST_MAX)
*MACLIST_SIZE);
if(aplistnew == NULL)
{
fprintf(stderr, "failed to allocate memory for internal list\n");
exit(EXIT_FAILURE);
}
aplist = aplistnew;
aplistptr = aplistnew +maclistmax;
maclistmax += MACLIST_MAX;
}
memset(aplistptr, 0, MACLIST_SIZE);
aplistptr->timestamp = proberequesttimestamp;
aplistptr->count = 1;
aplistptr->status = ST_PROBE_REQ;
aplistptr->type = CLIENT;
memcpy(aplistptr->addr, macclient, 6);
aplistptr->essidlen = tags.essidlen;
memcpy(aplistptr->essid, tags.essid, tags.essidlen);
if(cleanbackmac() == false) aplistptr++;
return;
}
/*===========================================================================*/
static void process80211probe_req(uint64_t proberequesttimestamp, uint8_t
*macclient, uint32_t proberequestlen, uint8_t *proberequestptr)
{
static maclist_t *aplistnew;
static tags_t tags;
proberequestundirectedcount++;
if(proberequestlen < (int)IETAG_SIZE) return;
if(gettags(proberequestlen, proberequestptr, &tags) == false) return;
if(tags.essidlen == 0) return;
if(tags.essid[0] == 0) return;
if(aplistptr >= aplist +maclistmax)
{
aplistnew = (maclist_t*)realloc(aplist, (maclistmax +MACLIST_MAX)
*MACLIST_SIZE);
if(aplistnew == NULL)
{
fprintf(stderr, "failed to allocate memory for internal list\n");
exit(EXIT_FAILURE);
}
aplist = aplistnew;
aplistptr = aplistnew +maclistmax;
maclistmax += MACLIST_MAX;
}
memset(aplistptr, 0, MACLIST_SIZE);
aplistptr->timestamp = proberequesttimestamp;
aplistptr->count = 1;
aplistptr->status = ST_PROBE_REQ;
aplistptr->type = CLIENT;
memcpy(aplistptr->addr, macclient, 6);
aplistptr->essidlen = tags.essidlen;
memcpy(aplistptr->essid, tags.essid, tags.essidlen);
if(cleanbackmac() == false) aplistptr++;
return;
}
/*===========================================================================*/
static void process80211probe_resp(uint64_t proberesponsetimestamp, uint8_t *macap,
uint32_t proberesponselen, uint8_t *proberesponseptr)
{
static int apinfolen;
static maclist_t *aplistnew;
static uint8_t *apinfoptr;
static tags_t tags;
proberesponsecount++;
apinfoptr = proberesponseptr +CAPABILITIESAP_SIZE;
apinfolen = proberesponselen -CAPABILITIESAP_SIZE;
if(proberesponselen < (int)IETAG_SIZE) return;
if(gettags(apinfolen, apinfoptr, &tags) == false) return;
if(tags.essidlen == 0)
{
proberesponsessidunsetcount++;
return;
}
if(memcmp(&tags.essid, &zeroed32, tags.essidlen) == 0)
{
proberesponsessidzeroedcount++;
return;
}
if(tags.essid[0] == 0) return;
if(aplistptr >= aplist +maclistmax)
{
aplistnew = (maclist_t*)realloc(aplist, (maclistmax +MACLIST_MAX)
*MACLIST_SIZE);
if(aplistnew == NULL)
{
fprintf(stderr, "failed to allocate memory for internal list\n");
exit(EXIT_FAILURE);
}
aplist = aplistnew;
aplistptr = aplistnew +maclistmax;
maclistmax += MACLIST_MAX;
}
memset(aplistptr, 0, MACLIST_SIZE);
aplistptr->timestamp = proberesponsetimestamp;
aplistptr->count = 1;
aplistptr->status = ST_PROBE_RESP;
aplistptr->type = AP;
memcpy(aplistptr->addr, macap, 6);
aplistptr->essidlen = tags.essidlen;
memcpy(aplistptr->essid, tags.essid, tags.essidlen);
aplistptr->groupcipher = tags.groupcipher;
aplistptr->cipher = tags.cipher;
aplistptr->akm = tags.akm;
aplistptr->manufacturerlen = tags.manufacturerlen;
memcpy(aplistptr->manufacturer, tags.manufacturer, tags.manufacturerlen);
aplistptr->modellen = tags.modellen;
memcpy(aplistptr->model, tags.model, tags.modellen);
aplistptr->serialnumberlen = tags.serialnumberlen;
memcpy(aplistptr->serialnumber, tags.serialnumber, tags.serialnumberlen);
aplistptr->devicenamelen = tags.devicenamelen;
memcpy(aplistptr->devicename, tags.devicename, tags.devicenamelen);
aplistptr->enrolleelen = tags.enrolleelen;
memcpy(aplistptr->enrollee, tags.enrollee, tags.enrolleelen);
if(fh_csv != NULL) writecsv(proberesponsetimestamp, macap, &tags);
if(cleanbackmac() == false) aplistptr++;
if(fh_nmea != NULL) writegpwpl(macap);
return;
}
/*===========================================================================*/
static inline bool processpag(uint8_t *macap, int vendorlen, uint8_t *ieptr)
{
static int c, p;
static const uint8_t mac_pwag[6] =
{
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad
};
beaconcount++;
if(memcmp(&mac_broadcast, macbc, 6) != 0)
{
broadcastmacerrorcount++;
return;
}
apinfoptr = beaconptr +CAPABILITIESAP_SIZE;
apinfolen = beaconlen -CAPABILITIESAP_SIZE;
if(apinfoptr[0] == TAG_PAG)
{
if(processpag(macap, apinfolen, apinfoptr) == true) return;
}
if(beaconlen < (int)IETAG_SIZE)
{
beaconerrorcount++;
return;
}
if(gettags(apinfolen, apinfoptr, &tags) == false)
{
beaconerrorcount++;
if(tags.essidlen > 32) beaconssidoversizedcount++;
return;
}
if(tags.essidlen == 0)
{
beaconssidunsetcount++;
return;
}
if(memcmp(&tags.essid, &zeroed32, tags.essidlen) == 0)
{
beaconssidzeroedcount++;
return;
}
if((tags.channel > 0) && (tags.channel <= 14))
{
beaconchannel[0] |= GHZ24;
beaconchannel[tags.channel]++;
}
if((tags.channel > 14) && (tags.channel < CHANNEL_MAX))
{
beaconchannel[0] |= GHZ5;
beaconchannel[tags.channel]++;
}
if(tags.essid[0] == 0) return;
if(aplistptr >= aplist +maclistmax)
{
aplistnew = (maclist_t*)realloc(aplist, (maclistmax +MACLIST_MAX)
*MACLIST_SIZE);
if(aplistnew == NULL)
{
fprintf(stderr, "failed to allocate memory for internal list\n");
exit(EXIT_FAILURE);
}
aplist = aplistnew;
aplistptr = aplistnew +maclistmax;
maclistmax += MACLIST_MAX;
}
memset(aplistptr, 0, MACLIST_SIZE);
aplistptr->timestamp = beacontimestamp;
aplistptr->count = 1;
aplistptr->status = ST_BEACON;
aplistptr->type = AP;
memcpy(aplistptr->addr, macap, 6);
aplistptr->essidlen = tags.essidlen;
memcpy(aplistptr->essid, tags.essid, tags.essidlen);
aplistptr->groupcipher = tags.groupcipher;
aplistptr->cipher = tags.cipher;
aplistptr->akm = tags.akm;
aplistptr->manufacturerlen = tags.manufacturerlen;
memcpy(aplistptr->manufacturer, tags.manufacturer, tags.manufacturerlen);
aplistptr->modellen = tags.modellen;
memcpy(aplistptr->model, tags.model, tags.modellen);
aplistptr->serialnumberlen = tags.serialnumberlen;
memcpy(aplistptr->serialnumber, tags.serialnumber, tags.serialnumberlen);
aplistptr->devicenamelen = tags.devicenamelen;
memcpy(aplistptr->devicename, tags.devicename, tags.devicenamelen);
aplistptr->enrolleelen = tags.enrolleelen;
memcpy(aplistptr->enrollee, tags.enrollee, tags.enrolleelen);
if(fh_csv != NULL) writecsv(beacontimestamp, macap, &tags);
if(cleanbackmac() == false) aplistptr++;
if(fh_nmea != NULL) writegpwpl(macap);
return;
}
/*===========================================================================*/
static void process80211actionmeasurement(uint64_t actiontimestamp, uint8_t
*macclient, uint32_t packetlen, uint8_t *packetptr)
{
static maclist_t *aplistnew;
static tags_t tags;
static actmm_t *actmm;
ieee80211flag = true;
frequency = 0;
rth = (rth_t*)capptr;
pf = RTH_SIZE;
if((rth->it_present & IEEE80211_RADIOTAP_CHANNEL) != IEEE80211_RADIOTAP_CHANNEL)
return;
if((rth->it_present & IEEE80211_RADIOTAP_EXT) == IEEE80211_RADIOTAP_EXT)
{
pp = (uint32_t*)capptr;
for(i = 2; i < rthlen /4; i++)
{
#ifdef BIG_ENDIAN_HOST
pp[i] = byte_swap_32(pp[i]);
#endif
pf += 4;
if((pp[i] & IEEE80211_RADIOTAP_EXT) != IEEE80211_RADIOTAP_EXT) break;
}
}
if((rth->it_present & IEEE80211_RADIOTAP_TSFT) == IEEE80211_RADIOTAP_TSFT)
{
if((pf %8) != 0) pf += 4;
pf += 8;
}
if((rth->it_present & IEEE80211_RADIOTAP_FLAGS) == IEEE80211_RADIOTAP_FLAGS) pf +=
1;
if((rth->it_present & IEEE80211_RADIOTAP_RATE) == IEEE80211_RADIOTAP_RATE) pf += 1;
if((rth->it_present & IEEE80211_RADIOTAP_CHANNEL) == IEEE80211_RADIOTAP_CHANNEL)
{
if(pf > caplen) return;
if((pf %2) != 0) pf += 1;
frequency = (capptr[pf +1] << 8) + capptr[pf];
usedfrequency[frequency] += 1;
if(frequency == 2484)
{
interfacechannel = 14;
band24count++;
}
else if(frequency < 2484)
{
interfacechannel = (frequency -2407)/5;
band24count++;
}
rssi = 0;
interfacechannel = 0;
if(fh_raw_out != NULL)
{
cs = captimestamp &0xff;
cs ^= (captimestamp >> 8) &0xff;
cs ^= (captimestamp >> 16) &0xff;
cs ^= (captimestamp >> 24) &0xff;
cs ^= (captimestamp >> 32) &0xff;
cs ^= (captimestamp >> 40) &0xff;
cs ^= (captimestamp >> 48) &0xff;
cs ^= (captimestamp >> 56) &0xff;
cs ^= linktype &0xff;
cs ^= (linktype >> 8) &0xff;
cs ^= (linktype >> 16) &0xff;
cs ^= (linktype >> 24) &0xff;
#ifndef BIG_ENDIAN_HOST
fprintf(fh_raw_out, "%016" PRIx64 "*%08x*", captimestamp, linktype);
#else
fprintf(fh_raw_out, "%016" PRIx64 "*%08x*", byte_swap_64(captimestamp),
byte_swap_32(linktype));
#endif
for(p = 0; p < caplen; p++)
{
fprintf(fh_raw_out, "%02x", capptr[p]);
cs ^= capptr[p];
}
fprintf(fh_raw_out, "*%02x\n", cs);
}
if(packetlen < 4)
{
pcapreaderrors++;
fprintf(stdout, "failed to read packet\n");
if(fh_log != NULL) fprintf(fh_log, "failed to read packet (len < 4): %ld\n",
rawpacketcount);
return;
}
fcs = (fcs_t*)(packetptr +packetlen -4);
crc = fcscrc32check(packetptr, packetlen -4);
#ifdef BIG_ENDIAN_HOST
crc = byte_swap_32(crc);
#endif
if(crc == fcs->fcs)
{
fcsframecount++;
packetlen -= 4;
}
process80211packet(captimestamp, packetlen, packetptr);
return;
}
/*===========================================================================*/
void processcap(int fd, char *eigenname, char *pcaporgname, char *pcapinname)
{
static unsigned int res;
static off_t resseek;
static pcap_hdr_t pcapfhdr;
static pcaprec_hdr_t pcaprhdr;
static uint64_t timestampcap;
static uint8_t packet[MAXPACPSNAPLEN];
ancientdumpfileformat = true;
fprintf(stdout, "%s %s reading from %s...\n", basename(eigenname), VERSION_TAG,
basename(pcapinname));
iface = 1;
res = read(fd, &pcapfhdr, PCAPHDR_SIZE);
if(res != PCAPHDR_SIZE)
{
pcapreaderrors++;
fprintf(stdout, "failed to read pcap header\n");
if(fh_log != NULL) fprintf(fh_log, "failed to read pcap header: %s\n",
basename(pcapinname));
return;
}
#ifdef BIG_ENDIAN_HOST
pcapfhdr.magic_number = byte_swap_32(pcapfhdr.magic_number);
pcapfhdr.version_major = byte_swap_16(pcapfhdr.version_major);
pcapfhdr.version_minor = byte_swap_16(pcapfhdr.version_minor);
pcapfhdr.thiszone = byte_swap_32(pcapfhdr.thiszone);
pcapfhdr.sigfigs = byte_swap_32(pcapfhdr.sigfigs);
pcapfhdr.snaplen = byte_swap_32(pcapfhdr.snaplen);
pcapfhdr.network = byte_swap_32(pcapfhdr.network);
#endif
if(pcapfhdr.magic_number == PCAPMAGICNUMBERBE)
{
pcapfhdr.magic_number = byte_swap_32(pcapfhdr.magic_number);
pcapfhdr.version_major = byte_swap_16(pcapfhdr.version_major);
pcapfhdr.version_minor = byte_swap_16(pcapfhdr.version_minor);
pcapfhdr.thiszone = byte_swap_32(pcapfhdr.thiszone);
pcapfhdr.sigfigs = byte_swap_32(pcapfhdr.sigfigs);
pcapfhdr.snaplen = byte_swap_32(pcapfhdr.snaplen);
pcapfhdr.network = byte_swap_32(pcapfhdr.network);
endianness = 1;
}
versionmajor = pcapfhdr.version_major;
versionminor = pcapfhdr.version_minor;
dltlinktype[0] = pcapfhdr.network;
if(pcapfhdr.version_major != PCAP_MAJOR_VER)
{
pcapreaderrors++;
fprintf(stdout, "unsupported major pcap version\n");
if(fh_log != NULL) fprintf(fh_log, "unsupported major pcap version: %d\n",
pcapfhdr.version_major);
return;
}
if(pcapfhdr.version_minor != PCAP_MINOR_VER)
{
pcapreaderrors++;
fprintf(stdout, "unsupported minor pcap version\n");
if(fh_log != NULL) fprintf(fh_log, "unsupported minor pcap version: %d\n",
pcapfhdr.version_minor);
return;
}
if(pcapfhdr.snaplen > MAXPACPSNAPLEN)
{
pcapreaderrors++;
fprintf(stdout, "detected oversized snaplen (%d)\n", pcapfhdr.snaplen);
if(fh_log != NULL) fprintf(fh_log, "detected oversized snaplen (%d): %d\n",
pcapfhdr.snaplen, pcapfhdr.version_minor);
}
while(1)
{
res = read(fd, &pcaprhdr, PCAPREC_SIZE);
if(res == 0) break;
if(res != PCAPREC_SIZE)
{
pcapreaderrors++;
fprintf(stdout, "failed to read pcap packet header for packet %ld\n",
rawpacketcount);
if(fh_log != NULL) fprintf(fh_log, "failed to read pcap packet header:
%ld\n", rawpacketcount);
break;
}
#ifdef BIG_ENDIAN_HOST
pcaprhdr.ts_sec = byte_swap_32(pcaprhdr.ts_sec);
pcaprhdr.ts_usec = byte_swap_32(pcaprhdr.ts_usec);
pcaprhdr.incl_len = byte_swap_32(pcaprhdr.incl_len);
pcaprhdr.orig_len = byte_swap_32(pcaprhdr.orig_len);
#endif
if(endianness == 1)
{
pcaprhdr.ts_sec = byte_swap_32(pcaprhdr.ts_sec);
pcaprhdr.ts_usec = byte_swap_32(pcaprhdr.ts_usec);
pcaprhdr.incl_len = byte_swap_32(pcaprhdr.incl_len);
pcaprhdr.orig_len = byte_swap_32(pcaprhdr.orig_len);
}
if(pcaprhdr.incl_len > pcapfhdr.snaplen)
{
pcapreaderrors++;
if(fh_log != NULL) fprintf(fh_log, "inclusive length > snaplen: %ld\n",
rawpacketcount);
}
if(pcaprhdr.incl_len < MAXPACPSNAPLEN)
{
rawpacketcount++;
res = read(fd, &packet, pcaprhdr.incl_len);
if(res != pcaprhdr.incl_len)
{
pcapreaderrors++;
fprintf(stdout, "failed to read packet %ld\n", rawpacketcount);
if(fh_log != NULL) fprintf(fh_log, "packet error: %ld\n",
rawpacketcount);
break;
}
}
else
{
skippedpacketcount++;
resseek = lseek(fd, pcaprhdr.incl_len, SEEK_CUR);
if(resseek < 0)
{
pcapreaderrors++;
fprintf(stdout, "failed to set file pointer\n");
if(fh_log != NULL) fprintf(fh_log, "failed to set file pointer:
%s\n", basename(pcapinname));
break;
}
continue;
}
if(pcaprhdr.incl_len > 0)
{
timestampcap = ((uint64_t)pcaprhdr.ts_sec *1000000) + pcaprhdr.ts_usec;
timestampcap *= 1000;
processlinktype(timestampcap, pcapfhdr.network, pcaprhdr.incl_len,
packet);
}
}
magicblockcount = 0;
ancientdumpfileformat = false;
fprintf(stdout, "%s %s reading from %s...\n", basename(eigenname), VERSION_TAG,
basename(pcapinname));
iface = 0;
nmealen = 0;
memset(&interfaceid, 0, sizeof(int) *MAX_INTERFACE_ID);
fdsize = lseek(fd, 0, SEEK_END);
if(fdsize < 0)
{
pcapreaderrors++;
fprintf(stdout, "failed to get file size\n");
if(fh_log != NULL) fprintf(fh_log, "failed to get file size: %s\n",
basename(pcapinname));
return;
}
snaplen = 0;
memset(&packet, 0, MAXPACPSNAPLEN);
while(1)
{
aktseek = lseek(fd, 0, SEEK_CUR);
if(aktseek < 0)
{
pcapreaderrors++;
fprintf(stdout, "failed to set file pointer\n");
if(fh_log != NULL) fprintf(fh_log, "failed to set file pointer: %s\n",
basename(pcapinname));
break;
}
res = read(fd, &pcpngblock, BH_SIZE);
if(res == 0)
{
break;
}
if(res != BH_SIZE)
{
pcapreaderrors++;
fprintf(stdout, "failed to read block header\n");
if(fh_log != NULL) fprintf(fh_log, "failed to read block header: %s\n",
basename(pcapinname));
break;
}
pcapngbh = (block_header_t*)pcpngblock;
blocktype = pcapngbh->block_type;
blocklen = pcapngbh->total_length;
blockmagic = pcapngbh->byte_order_magic;
#ifdef BIG_ENDIAN_HOST
blocktype = byte_swap_32(blocktype);
blocklen = byte_swap_32(blocklen);
blockmagic = byte_swap_32(blockmagic);
#endif
if(blocktype == PCAPNGBLOCKTYPE)
{
if(blockmagic == PCAPNGMAGICNUMBERBE) endianness = 1;
}
if(endianness == 1)
{
blocktype = byte_swap_32(blocktype);
blocklen = byte_swap_32(blocklen);
}
if((blocklen > (2 *MAXPACPSNAPLEN)) || ((blocklen %4) != 0))
{
pcapreaderrors++;
fprintf(stdout, "failed to read pcapng block header\n");
if(fh_log != NULL) fprintf(fh_log, "failed to read pcapng block header:
%ld\n", rawpacketcount);
break;
}
resseek = lseek(fd, aktseek, SEEK_SET);
if(resseek < 0)
{
pcapreaderrors++;
fprintf(stdout, "failed to set file pointer\n");
if(fh_log != NULL) fprintf(fh_log, "failed to set file pointer: %s\n",
basename(pcapinname));
break;
}
res = read(fd, &pcpngblock, blocklen);
if((res < BH_SIZE) || (res != blocklen))
{
pcapreaderrors++;
fprintf(stdout, "failed to read pcapng block header\n");
if(fh_log != NULL) fprintf(fh_log, "failed to read pcapng block header:
%ld\n", rawpacketcount);
break;
}
if(memcmp(&pcpngblock[4], &pcpngblock[ blocklen -4], 4) != 0)
{
pcapreaderrors++;
fprintf(stdout, "failed to read pcapng block header \n");
if(fh_log != NULL) fprintf(fh_log, "failed to read pcapng block header:
%ld\n", rawpacketcount);
break;
}
if(blocktype == PCAPNGBLOCKTYPE)
{
pcapngshb = (section_header_block_t*)pcpngblock;
#ifdef BIG_ENDIAN_HOST
pcapngshb->major_version = byte_swap_16(pcapngshb->major_version);
pcapngshb->minor_version = byte_swap_16(pcapngshb->minor_version);
pcapngshb->section_length = byte_swap_64(pcapngshb-
>section_length);
#endif
if(endianness == 1)
{
pcapngshb->major_version = byte_swap_16(pcapngshb-
>major_version);
pcapngshb->minor_version = byte_swap_16(pcapngshb-
>minor_version);
pcapngshb->section_length = byte_swap_64(pcapngshb-
>section_length);
}
versionmajor = pcapngshb->major_version;
versionminor = pcapngshb->minor_version;
if(pcapngshb->major_version != PCAPNG_MAJOR_VER)
{
pcapreaderrors++;
fprintf(stdout, "unsupported major pcapng version\n");
if(fh_log != NULL) fprintf(fh_log, "unsupported major pcapng
version: %d\n", pcapngshb->major_version);
break;
}
if(pcapngshb->minor_version != PCAPNG_MINOR_VER)
{
pcapreaderrors++;
fprintf(stdout, "unsupported minor pcapng version\n");
if(fh_log != NULL) fprintf(fh_log, "unsupported minor pcapng
version: %d\n", pcapngshb->minor_version);
break;
}
if(pcapngoptionwalk(blocktype, pcapngshb->data, blocklen -SHB_SIZE) !=
0) pcapreaderrors++;
}
else if(blocktype == IDBID)
{
pcapngidb = (interface_description_block_t*)pcpngblock;
#ifdef BIG_ENDIAN_HOST
pcapngidb->linktype = byte_swap_16(pcapngidb->linktype);
pcapngidb->snaplen = byte_swap_32(pcapngidb->snaplen);
#endif
if(endianness == 1)
{
pcapngidb->linktype = byte_swap_16(pcapngidb->linktype);
pcapngidb->snaplen = byte_swap_32(pcapngidb->snaplen);
}
snaplen = pcapngidb->snaplen;
if(pcapngoptionwalk(blocktype, pcapngidb->data, blocklen -IDB_SIZE) !=
0) pcapreaderrors++;
if(snaplen > MAXPACPSNAPLEN)
{
pcapreaderrors++;
fprintf(stdout, "detected oversized snaplen (%d)\n", snaplen);
if(fh_log != NULL) fprintf(fh_log, "detected oversized snaplen:
%ld\n", rawpacketcount);
}
if(iface >= MAX_INTERFACE_ID)
{
pcapreaderrors++;
fprintf(stdout, "maximum of supported interfaces reached: %d\n",
iface);
if(fh_log != NULL) fprintf(fh_log, "maximum of supported
interfaces reached: %d\n", iface);
continue;
}
dltlinktype[iface] = pcapngidb->linktype;
timeresolval[iface] = pcapngtimeresolution;
iface++;
}
else if(blocktype == PBID)
{
pcapngpb = (packet_block_t*)pcpngblock;
#ifdef BIG_ENDIAN_HOST
pcapngpb->caplen = byte_swap_32(pcapngpb->caplen);
#endif
if(endianness == 1) pcapngpb->caplen = byte_swap_32(pcapngpb-
>caplen);
timestamppcapng = 0;
if(pcapngpb->caplen > MAXPACPSNAPLEN)
{
pcapreaderrors++;
fprintf(stdout, "caplen > MAXSNAPLEN (%d > %d)\n", pcapngpb-
>caplen, MAXPACPSNAPLEN);
if(fh_log != NULL) fprintf(fh_log, "caplen > MAXSNAPLEN: %ld\n",
rawpacketcount);
continue;
}
if(pcapngpb->caplen > blocklen)
{
pcapreaderrors++;
fprintf(stdout, "caplen > blocklen (%d > %d)\n", pcapngpb-
>caplen, blocklen);
if(fh_log != NULL) fprintf(fh_log, "caplen > blocklen: %ld\n",
rawpacketcount);
continue;
}
rawpacketcount++;
processlinktype(timestamppcapng, dltlinktype[0], pcapngpb->caplen,
pcapngpb->data);
}
else if(blocktype == SPBID) continue;
else if(blocktype == NRBID) continue;
else if(blocktype == ISBID) continue;
else if(blocktype == EPBID)
{
pcapngepb = (enhanced_packet_block_t*)pcpngblock;
#ifdef BIG_ENDIAN_HOST
pcapngepb->interface_id = byte_swap_32(pcapngepb->interface_id);
pcapngepb->timestamp_high = byte_swap_32(pcapngepb-
>timestamp_high);
pcapngepb->timestamp_low = byte_swap_32(pcapngepb->timestamp_low);
pcapngepb->caplen = byte_swap_32(pcapngepb->caplen);
pcapngepb->len = byte_swap_32(pcapngepb->len);
#endif
if(endianness == 1)
{
pcapngepb->interface_id = byte_swap_32(pcapngepb-
>interface_id);
pcapngepb->timestamp_high = byte_swap_32(pcapngepb-
>timestamp_high);
pcapngepb->timestamp_low = byte_swap_32(pcapngepb-
>timestamp_low);
pcapngepb->caplen = byte_swap_32(pcapngepb->caplen);
pcapngepb->len = byte_swap_32(pcapngepb->len);
}
if(pcapngepb->interface_id >= iface)
{
pcapreaderrors++;
fprintf(stdout, "maximum of supported interfaces reached: %d\n",
iface);
if(fh_log != NULL) fprintf(stdout, "maximum of supported
interfaces reached: %d\n", iface);
continue;
}
timestamppcapng = pcapngepb->timestamp_high;
timestamppcapng = (timestamppcapng << 32) +pcapngepb->timestamp_low;
if(timeresolval[pcapngepb->interface_id] == TSRESOL_USEC)
{
timestamppcapng = pcapngepb->timestamp_high;
timestamppcapng = (timestamppcapng << 32) +pcapngepb-
>timestamp_low;
timestamppcapng *= 1000;
}
if(pcapngepb->caplen != pcapngepb->len)
{
pcapreaderrors++;
fprintf(stdout, "caplen != len (%d != %d)\n", pcapngepb->caplen,
pcapngepb->len);
if(fh_log != NULL) fprintf(fh_log, "caplen != len: %ld\n",
rawpacketcount);
continue;
}
if(pcapngepb->caplen > MAXPACPSNAPLEN)
{
pcapreaderrors++;
fprintf(stdout, "caplen > MAXSNAPLEN (%d > %d)\n", pcapngepb-
>caplen, MAXPACPSNAPLEN);
if(fh_log != NULL) fprintf(fh_log, "caplen > MAXSNAPLEN: %ld\n",
rawpacketcount);
continue;
}
if(pcapngepb->caplen > blocklen)
{
pcapreaderrors++;
fprintf(stdout, "caplen > blocklen (%d > %d)\n", pcapngepb-
>caplen, blocklen);
if(fh_log != NULL) fprintf(fh_log, "caplen > blocklen: %ld\n",
rawpacketcount);
continue;
}
rawpacketcount++;
processlinktype(timestamppcapng, dltlinktype[pcapngepb->interface_id],
pcapngepb->caplen, pcapngepb->data);
padding = 0;
if((pcapngepb->caplen %4) != 0) padding = 4 -(pcapngepb->caplen %4);
if(pcapngoptionwalk(blocktype, pcapngepb->data +pcapngepb->caplen
+padding, blocklen -EPB_SIZE -pcapngepb->caplen -padding) != 0) pcapreaderrors++;
}
else if(blocktype == CBID)
{
pcapngcb = (custom_block_t*)pcpngblock;
if(blocklen < CB_SIZE)
{
skippedpacketcount++;
continue;
}
if(memcmp(pcapngcb->pen, &hcxmagic, 4) != 0)
{
skippedpacketcount++;
continue;
}
if(memcmp(pcapngcb->hcxm, &hcxmagic, 32) != 0)
{
skippedpacketcount++;
continue;
}
magicblockcount++;
if(pcapngoptionwalk(blocktype, pcapngcb->data, blocklen -CB_SIZE) != 0)
pcapreaderrors++;
}
else
{
skippedpacketcount++;
}
}
fprintf(stdout, "\nsummary capture file\n"
"--------------------\n"
"file name................................: %s\n"
"version (pcapng).........................: %d.%d\n"
"operating system.........................: %s\n"
"application..............................: %s\n"
"interface name...........................: %s\n"
"interface vendor.........................: %02x%02x%02x\n"
"openSSL version..........................: %d.%d\n"
"weak candidate...........................: %s\n"
"MAC ACCESS POINT.........................: %02x%02x%02x%02x%02x%02x
(incremented on every new client)\n"
"MAC CLIENT...............................: %02x%02x%02x%02x%02x%02x\n"
"REPLAYCOUNT..............................: %" PRIu64 "\n"
"ANONCE...................................: %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\n"
"SNONCE...................................: %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\n"
, basename(pcaporgname), versionmajor, versionminor,
pcapngosinfo, pcapngapplinfo, pcapnghwinfo, pcapngdeviceinfo[0],
pcapngdeviceinfo[1], pcapngdeviceinfo[2],
opensslversionmajor, opensslversionminor,
pcapngweakcandidate,
myaktap[0], myaktap[1], myaktap[2], myaktap[3], myaktap[4], myaktap[5],
myaktclient[0], myaktclient[1], myaktclient[2], myaktclient[3],
myaktclient[4], myaktclient[5],
myaktreplaycount,
myaktanonce[0], myaktanonce[1], myaktanonce[2], myaktanonce[3],
myaktanonce[4], myaktanonce[5], myaktanonce[6], myaktanonce[7],
myaktanonce[8], myaktanonce[9], myaktanonce[10], myaktanonce[11],
myaktanonce[12], myaktanonce[13], myaktanonce[14], myaktanonce[15],
myaktanonce[16], myaktanonce[17], myaktanonce[18], myaktanonce[19],
myaktanonce[20], myaktanonce[21], myaktanonce[22], myaktanonce[23],
myaktanonce[24], myaktanonce[25], myaktanonce[26], myaktanonce[27],
myaktanonce[28], myaktanonce[29], myaktanonce[30], myaktanonce[31],
myaktsnonce[0], myaktsnonce[1], myaktsnonce[2], myaktsnonce[3],
myaktsnonce[4], myaktsnonce[5], myaktsnonce[6], myaktsnonce[7],
myaktsnonce[8], myaktsnonce[9], myaktsnonce[10], myaktsnonce[11],
myaktsnonce[12], myaktsnonce[13], myaktsnonce[14], myaktsnonce[15],
myaktsnonce[16], myaktsnonce[17], myaktsnonce[18], myaktsnonce[19],
myaktsnonce[20], myaktsnonce[21], myaktsnonce[22], myaktsnonce[23],
myaktsnonce[24], myaktsnonce[25], myaktsnonce[26], myaktsnonce[27],
myaktsnonce[28], myaktsnonce[29], myaktsnonce[30], myaktsnonce[31]
);
printlinklayerinfo();
cleanupmac();
outputdeviceinfolist();
outputwpalists();
outputwordlists();
outputeapmd5hashlist();
outputeapleaphashlist();
outputeapmschapv2hashlist();
outputtacacsplist();
printcontentinfo();
return;
}
/*===========================================================================*/
static bool processcapfile(char *eigenname, char *pcapinname)
{
static int resseek;
static uint32_t magicnumber;
static char *pcapnameptr;
#ifdef WANTZLIB
static char *pcaptempnameptr;
static char tmpoutname[PATH_MAX +1];
#endif
#ifdef WANTZLIB
pcaptempnameptr = NULL;
#endif
pcapnameptr = pcapinname;
#ifdef WANTZLIB
ancientdumpfileformat = false;
radiotappresent = false;
if(testgzipfile(pcapinname) == true)
{
memset(&tmpoutname, 0, PATH_MAX);
snprintf(tmpoutname, PATH_MAX, "/tmp/%s.tmp", basename(pcapinname));
if(decompressgz(pcapinname, tmpoutname) == false) return false;
gzipstat++;
pcaptempnameptr = tmpoutname;
pcapnameptr = tmpoutname;
}
#endif
jtrbasenamedeprecated = pcapinname;
fd_pcap = open(pcapnameptr, O_RDONLY);
if(fd_pcap == -1)
{
perror("failed to open file");
return false;
}
magicnumber = getmagicnumber(fd_pcap);
resseek = lseek(fd_pcap, 0L, SEEK_SET);
if(resseek < 0)
{
pcapreaderrors++;
fprintf(stdout, "failed to set file pointer\n");
if(fh_log != NULL) fprintf(fh_log, "failed to set file pointer: %s\n",
pcapinname);
return false;
}
if(magicnumber == PCAPNGBLOCKTYPE)
{
if(initlists() == true)
{
processpcapng(fd_pcap, eigenname, pcapinname, pcapnameptr);
pcapngstat++;
close(fd_pcap);
closelists();
}
}
else if((magicnumber == PCAPMAGICNUMBER) || (magicnumber == PCAPMAGICNUMBERBE))
{
if(magicnumber == PCAPMAGICNUMBERBE) endianness = 1;
if(initlists() == true)
{
processcap(fd_pcap, eigenname, pcapinname, pcapnameptr);
capstat++;
close(fd_pcap);
closelists();
}
}
else
{
fprintf(stdout, "unsupported dump file format: %s\n", pcapinname);
return false;
}
#ifdef WANTZLIB
if(pcaptempnameptr != NULL) remove(pcaptempnameptr);
#endif
return true;
}
/*===========================================================================*/
static inline size_t chop(char *buffer, size_t len)
{
static char *ptr;
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
};
printlinklayerinfo();
cleanupmac();
outputdeviceinfolist();
outputwpalists();
outputwordlists();
outputeapmd5hashlist();
outputeapleaphashlist();
outputeapmschapv2hashlist();
printcontentinfo();
fclose(fh_raw_in);
return true ;
}
/*===========================================================================*/
static bool testfilename(char *filename1, char *filename2)
{
if(filename1 == NULL) return false;
if(filename2 == NULL) return false;
if(strcmp(filename1, filename2) != 0) return false;
fprintf(stdout, "same file names for different file types is not allowed: %s - %s\
n", filename1, filename2);
return true;
}
/*===========================================================================*/
static bool evpdeinitwpa(void)
{
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 true;
}
/*===========================================================================*/
static bool evpinitwpa(void)
{
static unsigned long opensslversion;
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
opensslversion = OpenSSL_version_num();
opensslversionmajor = (opensslversion & 0x10000000L) >> 28;
opensslversionminor = (opensslversion & 0x01100000L) >> 20;
hmac = NULL;
ctxhmac = NULL;
cmac = NULL;
ctxcmac = NULL;
exit(EXIT_SUCCESS);
}
/*---------------------------------------------------------------------------*/
__attribute__ ((noreturn))
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 exitcode;
static char *pmkideapoloutname;
static char *pmkidclientoutname;
static char *eapmd5outname;
static char *eapmd5johnoutname;
static char *eapleapoutname;
static char *tacacspoutname;
static char *essidoutname;
static char *essidproberequestoutname;
static char *deviceinfooutname;
static char *identityoutname;
static char *usernameoutname;
static char *nmeaoutname;
static char *csvoutname;
static char *logoutname;
static char *rawoutname;
static char *rawinname;
static char *pmkideapoljtroutnamedeprecated;
static char *pmkidoutnamedeprecated;
static char *hccapxoutnamedeprecated;
static char *hccapoutnamedeprecated;
pmkideapoloutname = NULL;
eapmd5outname = NULL;
eapmd5johnoutname = NULL;
eapleapoutname = NULL;
tacacspoutname = NULL;
essidoutname = NULL;
essidproberequestoutname = NULL;
identityoutname = NULL;
usernameoutname = NULL;
deviceinfooutname = NULL;
nmeaoutname = NULL;
csvoutname = NULL;
logoutname = NULL;
rawoutname = NULL;
rawinname = NULL;
prefixoutname = NULL;
pmkideapoljtroutnamedeprecated = NULL;
pmkidoutnamedeprecated = NULL;
hccapxoutnamedeprecated = NULL;
hccapoutnamedeprecated = NULL;
fh_pmkideapol = NULL;
fh_pmkideapolclient = NULL;
fh_eapmd5 = NULL;
fh_eapmd5john = NULL;
fh_eapleap = NULL;
fh_tacacsp = NULL;
fh_essid = NULL;
fh_essidproberequest = NULL;
fh_deviceinfo= NULL;
fh_identity = NULL;
fh_username = NULL;
fh_nmea = NULL;
fh_csv = NULL;
fh_log = NULL;
fh_raw_out = NULL;
fh_pmkideapoljtrdeprecated = NULL;
fh_pmkiddeprecated = NULL;
fh_hccapxdeprecated = NULL;
fh_hccapdeprecated = NULL;
gzipstat = 0;
capstat = 0;
pcapngstat = 0;
while((auswahl = getopt_long (argc, argv, short_options, long_options, &index)) !=
-1)
{
switch (auswahl)
{
case HCX_EAPOL_TIMEOUT:
eapoltimeoutvalue = strtoull(optarg, NULL, 10);
if(eapoltimeoutvalue <= 0)
{
fprintf(stderr, "EAPOL TIMEOUT must be > 0\n");
exit(EXIT_FAILURE);
}
eapoltimeoutvalue *= 1000000;
break;
case HCX_NC:
ncvalue = strtol(optarg, NULL, 10);
break;
case HCX_IE:
ignoreieflag = true;
break;
case HCX_CONVERT_ALL:
donotcleanflag = true;
break;
case HCX_ESSIDS:
essidsvalue = strtol(optarg, NULL, 10);
break;
case HCX_PMKIDEAPOL_OUT:
pmkideapoloutname = optarg;
break;
case HCX_PMKID_CLIENT_OUT:
pmkidclientoutname = optarg;
break;
case HCX_EAPMD5_OUT:
eapmd5outname = optarg;
break;
case HCX_EAPMD5_JOHN_OUT:
eapmd5johnoutname = optarg;
break;
case HCX_EAPLEAP_OUT:
eapleapoutname = optarg;
break;
case HCX_TACACSP_OUT:
tacacspoutname = optarg;
break;
case HCX_ESSID_OUT:
essidoutname = optarg;
break;
case HCX_ESSIDPROBEREQUEST_OUT:
essidproberequestoutname = optarg;
break;
case HCX_IDENTITY_OUT:
identityoutname = optarg;
break;
case HCX_USERNAME_OUT:
usernameoutname = optarg;
break;
case HCX_DEVICEINFO_OUT:
deviceinfooutname = optarg;
break;
case HCX_NMEA_OUT:
nmeaoutname = optarg;
break;
case HCX_CSV_OUT:
csvoutname = optarg;
break;
case HCX_RAW_OUT:
rawoutname = optarg;
break;
case HCX_RAW_IN:
rawinname = optarg;
break;
case HCX_LOG_OUT:
logoutname = optarg;
break;
case HCX_ADD_TIMESTAMP:
addtimestampflag = true;
break;
case HCX_PMKIDEAPOLJTR_OUT_DEPRECATED:
pmkideapoljtroutnamedeprecated = optarg;
break;
case HCX_PMKID_OUT_DEPRECATED:
pmkidoutnamedeprecated = optarg;
break;
case HCX_HCCAPX_OUT_DEPRECATED:
hccapxoutnamedeprecated = optarg;
break;
case HCX_HCCAP_OUT_DEPRECATED:
hccapoutnamedeprecated = optarg;
break;
case HCX_HELP:
usage(basename(argv[0]));
break;
case HCX_PREFIX_OUT:
prefixoutname = optarg;
if(strlen(prefixoutname) > PREFIX_BUFFER_MAX)
{
fprintf(stderr, "prefix must be < %d\n", PATH_MAX -12);
exit(EXIT_FAILURE);
}
break;
case HCX_VERSION:
version(basename(argv[0]));
break;
case '?':
usageerror(basename(argv[0]));
break;
}
}
gettimeofday(&tv, NULL);
timestampstart = ((uint64_t)tv.tv_sec *1000000) + tv.tv_usec;
if(argc < 2)
{
fprintf(stderr, "no option selected\nrun %s --help to get more information\
n", (basename(argv[0])));
exit(EXIT_FAILURE);
}
if(prefixoutname != NULL)
{
strncpy(pmkideapolprefix, prefixoutname, PREFIX_BUFFER_MAX);
strncat(pmkideapolprefix, pmkideapolsuffix, PREFIX_BUFFER_MAX);
pmkideapoloutname = pmkideapolprefix;
strncpy(essidprefix, prefixoutname, PREFIX_BUFFER_MAX);
strncat(essidprefix, essidsuffix, PREFIX_BUFFER_MAX);
essidoutname = essidprefix;
if(pmkideapoljtroutnamedeprecated != NULL)
{
if((fh_pmkideapoljtrdeprecated = fopen(pmkideapoljtroutnamedeprecated, "a"))
== NULL)
{
fprintf(stdout, "error opening file %s: %s\n",
pmkideapoljtroutnamedeprecated, strerror(errno));
exit(EXIT_FAILURE);
}
}
if(pmkidoutnamedeprecated != NULL)
{
if((fh_pmkiddeprecated = fopen(pmkidoutnamedeprecated, "a")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", pmkidoutnamedeprecated,
strerror(errno));
exit(EXIT_FAILURE);
}
}
if(hccapxoutnamedeprecated != NULL)
{
if((fh_hccapxdeprecated = fopen(hccapxoutnamedeprecated, "a")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", hccapxoutnamedeprecated,
strerror(errno));
exit(EXIT_FAILURE);
}
}
if(hccapoutnamedeprecated != NULL)
{
if((fh_hccapdeprecated = fopen(hccapoutnamedeprecated, "a")) == NULL)
{
fprintf(stdout, "error opening file %s: %s\n", hccapoutnamedeprecated,
strerror(errno));
exit(EXIT_FAILURE);
}
}
if(pmkideapoloutname != NULL)
{
if(stat(pmkideapoloutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(pmkideapoloutname);
}
}
if(pmkidclientoutname != NULL)
{
if(stat(pmkidclientoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(pmkidclientoutname);
}
}
if(eapmd5outname != NULL)
{
if(stat(eapmd5outname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(eapmd5outname);
}
}
if(eapmd5johnoutname != NULL)
{
if(stat(eapmd5johnoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(eapmd5johnoutname);
}
}
if(eapleapoutname != NULL)
{
if(stat(eapleapoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(eapleapoutname);
}
}
if(tacacspoutname != NULL)
{
if(stat(tacacspoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(tacacspoutname);
}
}
if(essidoutname != NULL)
{
if(stat(essidoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(essidoutname);
}
}
if(essidproberequestoutname != NULL)
{
if(stat(essidproberequestoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(essidproberequestoutname);
}
}
if(identityoutname != NULL)
{
if(stat(identityoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(identityoutname);
}
}
if(usernameoutname != NULL)
{
if(stat(usernameoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(usernameoutname);
}
}
if(deviceinfooutname != NULL)
{
if(stat(deviceinfooutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(deviceinfooutname);
}
}
if(nmeaoutname != NULL)
{
if(stat(nmeaoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(nmeaoutname);
}
}
if(csvoutname != NULL)
{
if(stat(csvoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(csvoutname);
}
}
if(rawoutname != NULL)
{
if(stat(rawoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(rawoutname);
}
}
if(logoutname != NULL)
{
if(stat(logoutname, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(logoutname);
}
}
if(pmkideapoljtroutnamedeprecated != NULL)
{
if(stat(pmkideapoljtroutnamedeprecated, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(pmkideapoljtroutnamedeprecated);
}
}
if(pmkidoutnamedeprecated != NULL)
{
if(stat(pmkidoutnamedeprecated, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(pmkidoutnamedeprecated);
}
}
if(hccapxoutnamedeprecated != NULL)
{
if(stat(hccapxoutnamedeprecated, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(hccapxoutnamedeprecated);
}
}
if(hccapoutnamedeprecated != NULL)
{
if(stat(hccapoutnamedeprecated, &statinfo) == 0)
{
if(statinfo.st_size == 0) remove(hccapoutnamedeprecated);
}
}
if((gzipstat == 0) && (pcapngstat == 0) && (capstat == 0)) return exitcode;
fprintf(stdout, "\nsession summary\n---------------\n");
if(gzipstat > 0) fprintf(stdout, "gzip compressed dump files............:
%d\n", gzipstat);
if(pcapngstat > 0) fprintf(stdout, "processed pcapng
files................: %d\n", pcapngstat);
if(capstat > 0) fprintf(stdout, "processed cap
files...................: %d\n", capstat);
fprintf(stdout, "\n");
if(evpdeinitwpa() == false) exit(EXIT_FAILURE);
return exitcode;
}
/*===========================================================================*/