From 79383d9a396d5c6e2c8dcce6d7f8fc0b953a59ac Mon Sep 17 00:00:00 2001 From: Dhiru Kholia Date: Sun, 27 Jan 2013 10:11:01 +0530 Subject: [PATCH] Implement wpacap2john program --- src/Makefile | 3 + src/aircrack_byteorder.h | 447 ++++++++++++++++++++++++++ src/pcap.h | 111 +++++++ src/wpacap2john.c | 792 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1353 insertions(+) create mode 100644 src/aircrack_byteorder.h create mode 100644 src/pcap.h create mode 100644 src/wpacap2john.c diff --git a/src/Makefile b/src/Makefile index 1e5191e..2523776 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1808,6 +1808,9 @@ dmg2john: office2john: $(CC) `xml2-config --cflags` `pkg-config --cflags libgsf-1` office2john.c common.o base64.o `pkg-config --libs libgsf-1` `xml2-config --libs` -o ../run/office2john +wpacap2john: wpacap2john.o + $(LD) wpacap2john.o $(LDFLAGS) -o ../run/wpacap2john + ../run/tgtsnarf: tgtsnarf.o $(LD) tgtsnarf.o $(LDFLAGS) -o ../run/tgtsnarf diff --git a/src/aircrack_byteorder.h b/src/aircrack_byteorder.h new file mode 100644 index 0000000..78ca655 --- /dev/null +++ b/src/aircrack_byteorder.h @@ -0,0 +1,447 @@ +/* + * Compatibility header + * + * Copyright (C) 2009 Thomas d'Otreppe + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * You must obey the GNU General Public License in all respects + * for all of the code used other than OpenSSL. * If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. * If you + * do not wish to do so, delete this exception statement from your + * version. * If you delete this exception statement from all source + * files in the program, then also delete it here. + */ + +#ifndef _AIRCRACK_NG_BYTEORDER_H_ +#define _AIRCRACK_NG_BYTEORDER_H_ + + #define ___my_swab16(x) \ + ((u_int16_t)( \ + (((u_int16_t)(x) & (u_int16_t)0x00ffU) << 8) | \ + (((u_int16_t)(x) & (u_int16_t)0xff00U) >> 8) )) + #define ___my_swab32(x) \ + ((u_int32_t)( \ + (((u_int32_t)(x) & (u_int32_t)0x000000ffUL) << 24) | \ + (((u_int32_t)(x) & (u_int32_t)0x0000ff00UL) << 8) | \ + (((u_int32_t)(x) & (u_int32_t)0x00ff0000UL) >> 8) | \ + (((u_int32_t)(x) & (u_int32_t)0xff000000UL) >> 24) )) + #define ___my_swab64(x) \ + ((u_int64_t)( \ + (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x00000000000000ffULL) << 56) | \ + (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x000000000000ff00ULL) << 40) | \ + (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x0000000000ff0000ULL) << 24) | \ + (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x00000000ff000000ULL) << 8) | \ + (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x000000ff00000000ULL) >> 8) | \ + (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x0000ff0000000000ULL) >> 24) | \ + (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x00ff000000000000ULL) >> 40) | \ + (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0xff00000000000000ULL) >> 56) )) + + + /* + * Linux + */ + #if defined(linux) || defined(Linux) || defined(__linux__) || defined(__linux) || defined(__gnu_linux__) + #include + #include + #include + + #ifndef __int8_t_defined + typedef uint64_t u_int64_t; + typedef uint32_t u_int32_t; + typedef uint16_t u_int16_t; + typedef uint8_t u_int8_t; + #endif + + #endif + + /* + * Cygwin + */ + #if defined(__CYGWIN32__) + #include + #include + + #define __be64_to_cpu(x) ___my_swab64(x) + #define __be32_to_cpu(x) ___my_swab32(x) + #define __be16_to_cpu(x) ___my_swab16(x) + #define __cpu_to_be64(x) ___my_swab64(x) + #define __cpu_to_be32(x) ___my_swab32(x) + #define __cpu_to_be16(x) ___my_swab16(x) + #define __le64_to_cpu(x) (x) + #define __le32_to_cpu(x) (x) + #define __le16_to_cpu(x) (x) + #define __cpu_to_le64(x) (x) + #define __cpu_to_le32(x) (x) + #define __cpu_to_le16(x) (x) + + #define AIRCRACK_NG_BYTE_ORDER_DEFINED + + #endif + + /* + * mingw32 ( added by me ) + */ + #if defined(__MINGW_H) | defined(MINGW_SDK_INIT) + #include + #include + + #ifndef u_int16_t + #define u_int16_t uint16_t + #endif + #endif + + /* + * Windows (DDK) + */ + #if defined(__WIN__) + + #include + + #define __be64_to_cpu(x) ___my_swab64(x) + #define __be32_to_cpu(x) ___my_swab32(x) + #define __be16_to_cpu(x) ___my_swab16(x) + #define __cpu_to_be64(x) ___my_swab64(x) + #define __cpu_to_be32(x) ___my_swab32(x) + #define __cpu_to_be16(x) ___my_swab16(x) + #define __le64_to_cpu(x) (x) + #define __le32_to_cpu(x) (x) + #define __le16_to_cpu(x) (x) + #define __cpu_to_le64(x) (x) + #define __cpu_to_le32(x) (x) + #define __cpu_to_le16(x) (x) + + #define AIRCRACK_NG_BYTE_ORDER_DEFINED + + #endif + + /* + * MAC (Darwin) + */ + #if defined(__APPLE_CC__) + #if defined(__x86_64__) && defined(__APPLE__) + + #include + + #define __swab64(x) (unsigned long long) OSSwapInt64((uint64_t)x) + #define __swab32(x) (unsigned long) OSSwapInt32((uint32_t)x) + #define __swab16(x) (unsigned short) OSSwapInt16((uint16_t)x) + #define __be64_to_cpu(x) (unsigned long long) OSSwapBigToHostInt64((uint64_t)x) + #define __be32_to_cpu(x) (unsigned long) OSSwapBigToHostInt32((uint32_t)x) + #define __be16_to_cpu(x) (unsigned short) OSSwapBigToHostInt16((uint16_t)x) + #define __le64_to_cpu(x) (unsigned long long) OSSwapLittleToHostInt64((uint64_t)x) + #define __le32_to_cpu(x) (unsigned long) OSSwapLittleToHostInt32((uint32_t)x) + #define __le16_to_cpu(x) (unsigned short) OSSwapLittleToHostInt16((uint16_t)x) + #define __cpu_to_be64(x) (unsigned long long) OSSwapHostToBigInt64((uint64_t)x) + #define __cpu_to_be32(x) (unsigned long) OSSwapHostToBigInt32((uint32_t)x) + #define __cpu_to_be16(x) (unsigned short) OSSwapHostToBigInt16((uint16_t)x) + #define __cpu_to_le64(x) (unsigned long long) OSSwapHostToLittleInt64((uint64_t)x) + #define __cpu_to_le32(x) (unsigned long) OSSwapHostToLittleInt32((uint32_t)x) + #define __cpu_to_le16(x) (unsigned short) OSSwapHostToLittleInt16((uint16_t)x) + + #else + + #include + + #define __swab64(x) NXSwapLongLong(x) + #define __swab32(x) NXSwapLong(x) + #define __swab16(x) NXSwapShort(x) + #define __be64_to_cpu(x) NXSwapBigLongLongToHost(x) + #define __be32_to_cpu(x) NXSwapBigLongToHost(x) + #define __be16_to_cpu(x) NXSwapBigShortToHost(x) + #define __le64_to_cpu(x) NXSwapLittleLongLongToHost(x) + #define __le32_to_cpu(x) NXSwapLittleLongToHost(x) + #define __le16_to_cpu(x) NXSwapLittleShortToHost(x) + #define __cpu_to_be64(x) NXSwapHostLongLongToBig(x) + #define __cpu_to_be32(x) NXSwapHostLongToBig(x) + #define __cpu_to_be16(x) NXSwapHostShortToBig(x) + #define __cpu_to_le64(x) NXSwapHostLongLongToLittle(x) + #define __cpu_to_le32(x) NXSwapHostLongToLittle(x) + #define __cpu_to_le16(x) NXSwapHostShortToLittle(x) + + #endif + + #define __LITTLE_ENDIAN 1234 + #define __BIG_ENDIAN 4321 + #define __PDP_ENDIAN 3412 + #define __BYTE_ORDER __BIG_ENDIAN + + #define AIRCRACK_NG_BYTE_ORDER_DEFINED + + #endif + + /* + * Solaris + * ------- + */ + #if defined(__sparc__) + #include + #include + #include + + #define __be64_to_cpu(x) (x) + #define __be32_to_cpu(x) (x) + #define __be16_to_cpu(x) (x) + #define __cpu_to_be64(x) (x) + #define __cpu_to_be32(x) (x) + #define __cpu_to_be16(x) (x) + #define __le64_to_cpu(x) ___my_swab64(x) + #define __le32_to_cpu(x) ___my_swab32(x) + #define __le16_to_cpu(x) ___my_swab16(x) + #define __cpu_to_le64(x) ___my_swab64(x) + #define __cpu_to_le32(x) ___my_swab32(x) + #define __cpu_to_le16(x) ___my_swab16(x) + + typedef uint64_t u_int64_t; + typedef uint32_t u_int32_t; + typedef uint16_t u_int16_t; + typedef uint8_t u_int8_t; + + #define AIRCRACK_NG_BYTE_ORDER_DEFINED + + #endif + + /* + * Custom stuff + */ + #if defined(__MACH__) && !defined(__APPLE_CC__) + #include + #define __cpu_to_be64(x) = OSSwapHostToBigInt64(x) + #define __cpu_to_be32(x) = OSSwapHostToBigInt32(x) + + #define AIRCRACK_NG_BYTE_ORDER_DEFINED + + #endif + + + // FreeBSD + #ifdef __FreeBSD__ + #include + #endif + + // XXX: Is there anything to include on OpenBSD/NetBSD/DragonFlyBSD/...? + + + // XXX: Mac: Check http://www.opensource.apple.com/source/CF/CF-476.18/CFByteOrder.h + // http://developer.apple.com/DOCUMENTATION/CoreFoundation/Reference/CFByteOrderUtils/Reference/reference.html + // Write to apple to ask what should be used. + + #if defined(LITTLE_ENDIAN) + #define AIRCRACK_NG_LITTLE_ENDIAN LITTLE_ENDIAN + #elif defined(__LITTLE_ENDIAN) + #define AIRCRACK_NG_LITTLE_ENDIAN __LITTLE_ENDIAN + #elif defined(_LITTLE_ENDIAN) + #define AIRCRACK_NG_LITTLE_ENDIAN _LITTLE_ENDIAN + #endif + + #if defined(BIG_ENDIAN) + #define AIRCRACK_NG_BIG_ENDIAN BIG_ENDIAN + #elif defined(__BIG_ENDIAN) + #define AIRCRACK_NG_BIG_ENDIAN __BIG_ENDIAN + #elif defined(_BIG_ENDIAN) + #define AIRCRACK_NG_BIG_ENDIAN _BIG_ENDIAN + #endif + + #if !defined(AIRCRACK_NG_LITTLE_ENDIAN) && !defined(AIRCRACK_NG_BIG_ENDIAN) + #error Impossible to determine endianness (Little or Big endian), please contact the author. + #endif + + #if defined(BYTE_ORDER) + #if (BYTE_ORDER == AIRCRACK_NG_LITTLE_ENDIAN) + #define AIRCRACK_NG_BYTE_ORDER AIRCRACK_NG_LITTLE_ENDIAN + #elif (BYTE_ORDER == AIRCRACK_NG_BIG_ENDIAN) + #define AIRCRACK_NG_BYTE_ORDER AIRCRACK_NG_BIG_ENDIAN + #endif + #elif defined(__BYTE_ORDER) + #if (__BYTE_ORDER == AIRCRACK_NG_LITTLE_ENDIAN) + #define AIRCRACK_NG_BYTE_ORDER AIRCRACK_NG_LITTLE_ENDIAN + #elif (__BYTE_ORDER == AIRCRACK_NG_BIG_ENDIAN) + #define AIRCRACK_NG_BYTE_ORDER AIRCRACK_NG_BIG_ENDIAN + #endif + #elif defined(_BYTE_ORDER) + #if (_BYTE_ORDER == AIRCRACK_NG_LITTLE_ENDIAN) + #define AIRCRACK_NG_BYTE_ORDER AIRCRACK_NG_LITTLE_ENDIAN + #elif (_BYTE_ORDER == AIRCRACK_NG_BIG_ENDIAN) + #define AIRCRACK_NG_BYTE_ORDER AIRCRACK_NG_BIG_ENDIAN + #endif + #endif + + #ifndef AIRCRACK_NG_BYTE_ORDER + #error Impossible to determine endianness (Little or Big endian), please contact the author. + #endif + + #if (AIRCRACK_NG_BYTE_ORDER == AIRCRACK_NG_LITTLE_ENDIAN) + + #ifndef AIRCRACK_NG_BYTE_ORDER_DEFINED + #define __be64_to_cpu(x) ___my_swab64(x) + #define __be32_to_cpu(x) ___my_swab32(x) + #define __be16_to_cpu(x) ___my_swab16(x) + #define __cpu_to_be64(x) ___my_swab64(x) + #define __cpu_to_be32(x) ___my_swab32(x) + #define __cpu_to_be16(x) ___my_swab16(x) + #define __le64_to_cpu(x) (x) + #define __le32_to_cpu(x) (x) + #define __le16_to_cpu(x) (x) + #define __cpu_to_le64(x) (x) + #define __cpu_to_le32(x) (x) + #define __cpu_to_le16(x) (x) + #endif + + #ifndef htobe16 + #define htobe16 ___my_swab16 + #endif + #ifndef htobe32 + #define htobe32 ___my_swab32 + #endif + #ifndef htobe64 + #define htobe64 ___my_swab64 + #endif + #ifndef betoh16 + #define betoh16 ___my_swab16 + #endif + #ifndef betoh32 + #define betoh32 ___my_swab32 + #endif + #ifndef betoh64 + #define betoh64 ___my_swab64 + #endif + + #ifndef htole16 + #define htole16(x) (x) + #endif + #ifndef htole32 + #define htole32(x) (x) + #endif + #ifndef htole64 + #define htole64(x) (x) + #endif + #ifndef letoh16 + #define letoh16(x) (x) + #endif + #ifndef letoh32 + #define letoh32(x) (x) + #endif + #ifndef letoh64 + #define letoh64(x) (x) + #endif + + #endif + + #if (AIRCRACK_NG_BYTE_ORDER == AIRCRACK_NG_BIG_ENDIAN) + + #ifndef AIRCRACK_NG_BYTE_ORDER_DEFINED + #define __be64_to_cpu(x) (x) + #define __be32_to_cpu(x) (x) + #define __be16_to_cpu(x) (x) + #define __cpu_to_be64(x) (x) + #define __cpu_to_be32(x) (x) + #define __cpu_to_be16(x) (x) + #define __le64_to_cpu(x) ___my_swab64(x) + #define __le32_to_cpu(x) ___my_swab32(x) + #define __le16_to_cpu(x) ___my_swab16(x) + #define __cpu_to_le64(x) ___my_swab64(x) + #define __cpu_to_le32(x) ___my_swab32(x) + #define __cpu_to_le16(x) ___my_swab16(x) + #endif + + #ifndef htobe16 + #define htobe16(x) (x) + #endif + #ifndef htobe32 + #define htobe32(x) (x) + #endif + #ifndef htobe64 + #define htobe64(x) (x) + #endif + #ifndef betoh16 + #define betoh16(x) (x) + #endif + #ifndef betoh32 + #define betoh32(x) (x) + #endif + #ifndef betoh64 + #define betoh64(x) (x) + #endif + + #ifndef htole16 + #define htole16 ___my_swab16 + #endif + #ifndef htole32 + #define htole32 ___my_swab32 + #endif + #ifndef htole64 + #define htole64 ___my_swab64 + #endif + #ifndef letoh16 + #define letoh16 ___my_swab16 + #endif + #ifndef letoh32 + #define letoh32 ___my_swab32 + #endif + #ifndef letoh64 + #define letoh64 ___my_swab64 + #endif + + #endif + + // Common defines + #define cpu_to_le64 __cpu_to_le64 + #define le64_to_cpu __le64_to_cpu + #define cpu_to_le32 __cpu_to_le32 + #define le32_to_cpu __le32_to_cpu + #define cpu_to_le16 __cpu_to_le16 + #define le16_to_cpu __le16_to_cpu + #define cpu_to_be64 __cpu_to_be64 + #define be64_to_cpu __be64_to_cpu + #define cpu_to_be32 __cpu_to_be32 + #define be32_to_cpu __be32_to_cpu + #define cpu_to_be16 __cpu_to_be16 + #define be16_to_cpu __be16_to_cpu + + #ifndef le16toh + #define le16toh le16_to_cpu + #endif + #ifndef be16toh + #define be16toh be16_to_cpu + #endif + #ifndef le32toh + #define le32toh le32_to_cpu + #endif + #ifndef be32toh + #define be32toh be32_to_cpu + #endif + + + #ifndef htons + #define htons be16_to_cpu + #endif + #ifndef htonl + #define htonl cpu_to_be16 + #endif + #ifndef ntohs + #define ntohs cpu_to_be16 + #endif + #ifndef ntohl + #define ntohl cpu_to_be32 + #endif + +#endif diff --git a/src/pcap.h b/src/pcap.h new file mode 100644 index 0000000..b49c16b --- /dev/null +++ b/src/pcap.h @@ -0,0 +1,111 @@ +/* + * + * Copyright (C) 2001-2004 Christophe Devine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * You must obey the GNU General Public License in all respects + * for all of the code used other than OpenSSL. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you + * do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source + * files in the program, then also delete it here. + + */ +#ifndef _AIRCRACK_NG_PCAP_H_ +#define _AIRCRACK_NG_PCAP_H_ + +#define FORMAT_CAP 1 +#define FORMAT_IVS 2 +#define FORMAT_IVS2 3 + +#define TCPDUMP_MAGIC 0xA1B2C3D4 +#define TCPDUMP_CIGAM 0xD4C3B2A1 +#define IVSONLY_MAGIC "\xBF\xCA\x84\xD4" +#define IVS2_MAGIC "\xAE\x78\xD1\xFF" +#define IVS2_EXTENSION "ivs" +#define IVS2_VERSION 1 + +#define PCAP_VERSION_MAJOR 2 +#define PCAP_VERSION_MINOR 4 + +#define LINKTYPE_ETHERNET 1 +#define LINKTYPE_IEEE802_11 105 +#define LINKTYPE_PRISM_HEADER 119 +#define LINKTYPE_RADIOTAP_HDR 127 +#define LINKTYPE_PPI_HDR 192 + +#define uchar unsigned char +#define ushort unsigned short +#define uint unsigned int +#define ulong unsigned long + +//BSSID const. length of 6 bytes; can be together with all the other types +#define IVS2_BSSID 0x0001 + +//ESSID var. length; alone, or with BSSID +#define IVS2_ESSID 0x0002 + +//wpa structure, const. length; alone, or with BSSID +#define IVS2_WPA 0x0004 + +//IV+IDX+KEYSTREAM, var. length; alone or with BSSID +#define IVS2_XOR 0x0008 + +/* [IV+IDX][i][l][XOR_1]..[XOR_i][weight] * + * holds i possible keystreams for the same IV with a length of l for each keystream (l max 32) * + * and an array "int weight[16]" at the end */ +#define IVS2_PTW 0x0010 + +//unencrypted packet +#define IVS2_CLR 0x0020 + +struct pcap_file_header +{ + uint magic; + ushort version_major; + ushort version_minor; + int thiszone; + uint sigfigs; + uint snaplen; + uint linktype; +}; + +struct pcap_pkthdr +{ + int tv_sec; + int tv_usec; + uint caplen; + uint len; +}; + +struct ivs2_filehdr +{ + unsigned short version; +}; + +struct ivs2_pkthdr +{ + unsigned short flags; + unsigned short len; +}; + +#endif /* common.h */ diff --git a/src/wpacap2john.c b/src/wpacap2john.c new file mode 100644 index 0000000..29ea293 --- /dev/null +++ b/src/wpacap2john.c @@ -0,0 +1,792 @@ +/* This software is Copyright (c) 2012 Lukas Odzioba + * and it is hereby released to the general public under the following terms: + * Redistribution and use in source and binary forms, with or without modification, are permitted. + * + * Is this license valid for this mashup? + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef UINT16 + #define u_int16_t UINT16; +#endif +#include "pcap.h" +#include "aircrack_byteorder.h" +#define BROADCAST (uchar*)"\xFF\xFF\xFF\xFF\xFF\xFF" +#define SWAP32(x) \ + x = ( ( ( x >> 24 ) & 0x000000FF ) | \ + ( ( x >> 8 ) & 0x0000FF00 ) | \ + ( ( x << 8 ) & 0x00FF0000 ) | \ + ( ( x << 24 ) & 0xFF000000 ) ); +/* workaround for arm compiling */ +#ifndef O_BINARY + #define O_BINARY 0 +#endif +#define MAX_BUFF (PATH_MAX) + +typedef struct +{ + int off1; + int off2; + void *buf1; + void *buf2; +} +read_buf; + +typedef struct +{ + char essid[36]; + + unsigned char mac1[6]; + unsigned char mac2[6]; + unsigned char nonce1[32]; + unsigned char nonce2[32]; + + unsigned char eapol[256]; + int eapol_size; + + int keyver; + unsigned char keymic[16]; + +} hccap_t; + +struct wpa_hdsk +{ + unsigned char stmac[6]; + unsigned char snonce[32]; + unsigned char anonce[32]; + unsigned char keymic[16]; + unsigned char eapol[256]; + int eapol_size; + int keyver; + int state; +}; + +struct apoint +{ + unsigned char bssid[6]; + char essid[33]; + int crypt; + struct station *st_lst; + hccap_t wpa; + struct apoint *next; +}; + +struct station +{ + unsigned char mac[6]; + struct apoint *parent; + struct wpa_hdsk wpa; + struct station *next; +}; + +char *essid; // essid filter + +char itoa64[64] = + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +static void code_block(unsigned char *in, unsigned char b) +{ + putchar(itoa64[in[0] >> 2]); + putchar(itoa64[((in[0] & 0x03) << 4) | (in[1] >> 4)]); + if (b) { + putchar(itoa64[((in[1] & 0x0f) << 2) | (in[2] >> 6)]); + putchar(itoa64[in[2] & 0x3f]); + } else + putchar(itoa64[((in[1] & 0x0f) << 2)]); +} + +static void print_hccap(hccap_t * cap) +{ + int i; + unsigned char *w = (unsigned char *) cap; + printf("$WPAPSK$%s#", cap->essid); + for (i = 36; i + 3 < sizeof(hccap_t); i += 3) + code_block(&w[i], 1); + code_block(&w[i], 0); + puts(""); +} + + +int atomic_read( read_buf *rb, int fd, int len, void *buf ) +{ + int n; + + if( rb->buf1 == NULL ) + { + rb->buf1 = malloc( 65536 ); + rb->buf2 = malloc( 65536 ); + + if( rb->buf1 == NULL || rb->buf2 == NULL ) + return( 0 ); + + rb->off1 = 0; + rb->off2 = 0; + } + + if( len > 65536 - rb->off1 ) + { + rb->off2 -= rb->off1; + + memcpy( rb->buf2, rb->buf1 + rb->off1, rb->off2 ); + memcpy( rb->buf1, rb->buf2, rb->off2 ); + + rb->off1 = 0; + } + + if( rb->off2 - rb->off1 >= len ) + { + memcpy( buf, rb->buf1 + rb->off1, len ); + rb->off1 += len; + return( 1 ); + } + else + { + n = read( fd, rb->buf1 + rb->off2, 65536 - rb->off2 ); + + if( n <= 0 ) + return( 0 ); + + rb->off2 += n; + + if( rb->off2 - rb->off1 >= len ) + { + memcpy( buf, rb->buf1 + rb->off1, len ); + rb->off1 += len; + return( 1 ); + } + } + + return( 0 ); +} + +enum _log_level +{ + quiet, + error, + warning, + info, + verbose, + verbose2, + verbose3, + debug +}; + +enum _log_level log_level = info; +char err_buff[MAX_BUFF]; + +void w_report_error(const char *msg, const char *file, int line_no, const char *caller, int use_perror, int fatal, enum _log_level call_level) +{ + char format[MAX_BUFF]; + FILE *stream; + static const char *log_level_str[] = + { + "quiet", + "error", + "warning", + "info", + "verbose", + "verbose2", + "verbose3", + "debug", + }; + static int max_level_len = 8; + static int max_file_len = 11; + static int max_line_len = 4; + + file = basename((char *)file); + if(log_level == debug) + snprintf( format,MAX_BUFF, + "[%*s:%*d - %-*s] %s: %s", + max_file_len,file,max_line_len,line_no,max_level_len,log_level_str[call_level],caller,msg); + else + snprintf( format,MAX_BUFF, + "[%-*s]\t%s",max_level_len,log_level_str[call_level],msg); + + if(call_level < info) + stream = stderr; + else + stream = stdout; + + if(use_perror) + perror(format); + else if( call_level <= log_level ) + { + fprintf(stream,"%s",format); + fprintf(stream,"\n"); + } + + + if(fatal) + { + #ifdef _PTHREAD_H + pthread_exit((void *) EXIT_FAILURE); + #else + exit(EXIT_FAILURE); + #endif + } + return; +} + +void *w_malloc(size_t bytes, const char *file, int line_no) +{ + void *memory = NULL; + memory = malloc(bytes); + if (!memory) + w_report_error("", file, line_no,__func__, 0, 1, error); + memset(memory,'\0',bytes); + return memory; +} + +#define report_error(m,p,f,l) (w_report_error((m),__FILE__,__LINE__,__func__,(p),(f),(l))) +#define malloc(s) (w_malloc((s),__FILE__,__LINE__)) +void cap2hccap(const char *src, const char *dst) +{ + int fd, n, z; + read_buf rb; + // FILE *fp_hccap; + uchar *buffer, + *h80211, + *p; + static uchar ZERO[32] = + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00"; + unsigned char bssid[6],dest[6],stmac[6]; + + struct pcap_pkthdr pkh; + struct pcap_file_header pfh; + struct apoint *ap_lst=NULL,*ap_cur,*ap_prev; + struct station *st_cur,*st_prev; + + memset( &rb, 0, sizeof( rb ) ); + fd = 0; + + buffer = (uchar *) malloc( 65536 ); + + h80211 = buffer; + err_buff[0] = '\0'; + + if( src == NULL || dst == NULL ) + report_error("called with NULL argument.",0,1,error); + else if( ( fd = open( src, O_RDONLY | O_BINARY ) ) < 0 ) + strncpy(err_buff, src,MAX_BUFF); + else if( ! atomic_read( &rb, fd, 4, &pfh ) ) + strncpy(err_buff, src,MAX_BUFF); + else if( pfh.magic != TCPDUMP_MAGIC && pfh.magic != TCPDUMP_CIGAM ) + snprintf(err_buff,MAX_BUFF,"file \"%s\" is not a valid pcap file.", src); + else if( ! atomic_read( &rb, fd, 20, (uchar *) &pfh + 4 ) ) + snprintf(err_buff,MAX_BUFF,"reading header from file \"%s\".", src); +#if defined(F_SETFL) && defined(O_NONBLOCK) + else if( fcntl( fd, F_SETFL, O_NONBLOCK ) < 0 ) + snprintf(err_buff,MAX_BUFF,"setting non blocking access on file \"%s\".", src); +#endif + else + { + if( pfh.magic == TCPDUMP_CIGAM ) + SWAP32( pfh.linktype ); + + if( pfh.linktype != LINKTYPE_IEEE802_11 && + pfh.linktype != LINKTYPE_PRISM_HEADER && + pfh.linktype != LINKTYPE_RADIOTAP_HDR && + pfh.linktype != LINKTYPE_PPI_HDR ) + snprintf(err_buff,MAX_BUFF,"file \"%s\" is not a 802.11 (wireless) capture.", src); + } + + if(err_buff[0] != '\0') + { + if(strncmp(err_buff,src,MAX_BUFF) == 0 || strncmp(err_buff,dst,MAX_BUFF) == 0) + report_error(err_buff,1,0,error); + else + report_error(err_buff,0,0,error); + + if(fd != 0) + close(fd); + return; + } + + while( atomic_read( &rb, fd, sizeof( pkh ), &pkh )) + { + if( pfh.magic == TCPDUMP_CIGAM ) + SWAP32( pkh.caplen ); + + if( pkh.caplen <= 0 || pkh.caplen > 65535 ) + { + report_error("invalid packet capture length.",0,0,error); + report_error("probably capture file is corrupted.",0,0,verbose); + break; + } + + if( ! atomic_read( &rb, fd, pkh.caplen, buffer ) ) + { + report_error("cannot read packet data.",0,0,error); + break; + } + + h80211 = buffer; + + if( pfh.linktype == LINKTYPE_PRISM_HEADER ) + { + /* remove the prism header */ + + if( h80211[7] == 0x40 ) + n = 64; + else + { + n = *(int *)( h80211 + 4 ); + + if( pfh.magic == TCPDUMP_CIGAM ) + SWAP32( n ); + } + + if( n < 8 || n >= (int) pkh.caplen ) + continue; + + h80211 += n; pkh.caplen -= n; + } + + if( pfh.linktype == LINKTYPE_RADIOTAP_HDR ) + { + /* remove the radiotap header */ + + n = *(unsigned short *)( h80211 + 2 ); + + if( n <= 0 || n >= (int) pkh.caplen ) + continue; + + h80211 += n; pkh.caplen -= n; + } + + if( pfh.linktype == LINKTYPE_PPI_HDR ) + { + /* Remove the PPI header */ + + n = le16_to_cpu(*(unsigned short *)( h80211 + 2)); + + if( n <= 0 || n>= (int) pkh.caplen ) + continue; + + /* for a whole Kismet logged broken PPI headers */ + if ( n == 24 && le16_to_cpu(*(unsigned short *)(h80211 + 8)) == 2 ) + n = 32; + + if( n <= 0 || n>= (int) pkh.caplen ) + continue; + + h80211 += n; pkh.caplen -= n; + } + + /* skip packets smaller than a 802.11 header */ + + if( pkh.caplen < 24 ) + continue; + + /* skip (uninteresting) control frames */ + + if( ( h80211[0] & 0x0C ) == 0x04 ) + continue; + + /* locate the access point's MAC address */ + + switch( h80211[1] & 3 ) + { + case 0: memcpy( bssid, h80211 + 16, 6 ); break; //Adhoc + case 1: memcpy( bssid, h80211 + 4, 6 ); break; //ToDS + case 2: memcpy( bssid, h80211 + 10, 6 ); break; //FromDS + case 3: memcpy( bssid, h80211 + 10, 6 ); break; //WDS -> Transmitter taken as BSSID + } + + switch( h80211[1] & 3 ) + { + case 0: memcpy( dest, h80211 + 4, 6 ); break; //Adhoc + case 1: memcpy( dest, h80211 + 16, 6 ); break; //ToDS + case 2: memcpy( dest, h80211 + 4, 6 ); break; //FromDS + case 3: memcpy( dest, h80211 + 16, 6 ); break; //WDS -> Transmitter taken as BSSID + } + + if( memcmp( bssid, BROADCAST, 6 ) == 0 ) + continue; + + /* locate the station MAC in the 802.11 header */ + + memcpy(stmac,BROADCAST,6); // used as flag + + switch( h80211[1] & 3 ) + { + case 0: memcpy( stmac, h80211 + 10, 6 ); break; + case 1: memcpy( stmac, h80211 + 10, 6 ); break; + case 2: + if( (h80211[4]%2) == 0 ) /* if is a broadcast packet */ + memcpy( stmac, h80211 + 4, 6 ); + break; + } + + /* search if access point already exist */ + + ap_prev = NULL; + ap_cur = ap_lst; + for(ap_cur=ap_lst;ap_cur!=NULL;ap_prev=ap_cur,ap_cur=ap_cur->next) + if( ! memcmp( ap_cur->bssid, bssid, 6 ) ) + break; + + if(ap_cur == NULL) + { + ap_cur = malloc(sizeof(struct apoint)); + if(ap_lst == NULL) + ap_lst = ap_cur; + else + ap_prev->next = ap_cur; + + memcpy(ap_cur->bssid,bssid,6); + ap_cur->crypt = -1; + } + + /* search if station already exist */ + + st_cur = NULL; + + if(memcmp(stmac,BROADCAST,6) != 0 && memcmp(ap_cur->bssid, stmac,6) != 0) + { + + for(st_prev = NULL, st_cur=ap_cur->st_lst; + st_cur != NULL; st_prev = st_cur, st_cur = st_cur->next) + if( ! memcmp( st_cur->mac, stmac, 6) ) + break; + + /* if it's a new supplicant, add it */ + + if( st_cur == NULL ) + { + st_cur = malloc(sizeof(struct station)); + + if( ap_cur->st_lst == NULL ) + ap_cur->st_lst = st_cur; + else + st_prev->next = st_cur; + + memcpy( st_cur->mac, stmac, 6 ); + } + } + + /* packet parsing: Beacon or Probe Response */ + + if( h80211[0] == 0x80 || + h80211[0] == 0x50 ) + { + if( ap_cur->crypt < 0 ) + ap_cur->crypt = ( h80211[34] & 0x10 ) >> 4; + + p = h80211 + 36; + + while( p < h80211 + pkh.caplen ) + { + if( p + 2 + p[1] > h80211 + pkh.caplen ) + break; + + if( p[0] == 0x00 && p[1] > 0 && p[2] != '\0' ) + { + /* found a non-cloaked ESSID */ + + n = ( p[1] > 32 ) ? 32 : p[1]; + + memset( ap_cur->essid, 0, 33 ); + memcpy( ap_cur->essid, p + 2, n ); + } + + p += 2 + p[1]; + } + } + + /* packet parsing: Association Request */ + + if( h80211[0] == 0x00 ) + { + p = h80211 + 28; + + while( p < h80211 + pkh.caplen ) + { + if( p + 2 + p[1] > h80211 + pkh.caplen ) + break; + + if( p[0] == 0x00 && p[1] > 0 && p[2] != '\0' ) + { + n = ( p[1] > 32 ) ? 32 : p[1]; + + memset( ap_cur->essid, 0, 33 ); + memcpy( ap_cur->essid, p + 2, n ); + } + st_cur->wpa.state = 0; + p += 2 + p[1]; + } + } + + /* packet parsing: Association Response */ + + if( h80211[0] == 0x10 ) + if(st_cur != NULL) + st_cur->wpa.state = 0; + + /* check if data and station isn't the bssid */ + + if( ( h80211[0] & 0x0C ) != 0x08 || st_cur == NULL ) + continue; + + /* check minimum size */ + + z = ( ( h80211[1] & 3 ) != 3 ) ? 24 : 30; + if ( ( h80211[0] & 0x80 ) == 0x80 ) + z+=2; /* 802.11e QoS */ + + if( z + 16 > (int) pkh.caplen ) + continue; + + /* check the SNAP header to see if data is WEP encrypted */ + + if( ( h80211[z] != h80211[z + 1] || h80211[z + 2] != 0x03 ) && (h80211[z + 3] & 0x20) != 0) + ap_cur->crypt = 3; + + /* no encryption */ + if( ap_cur->crypt < 0 ) + ap_cur->crypt = 0; + + z += 6; + + /* check ethertype == EAPOL */ + + if( h80211[z] != 0x88 || h80211[z + 1] != 0x8E ) + continue; + + z += 2; + + /* type == 3 (key), desc. == 254 (WPA) or 2 (RSN) */ + + if( h80211[z + 1] != 0x03 || + ( h80211[z + 4] != 0xFE && h80211[z + 4] != 0x02 ) ) + continue; + + ap_cur->crypt = 3; /* set WPA */ + + /* frame 1: Pairwise == 1, Install == 0, Ack == 1, MIC == 0 */ + + if( ( h80211[z + 6] & 0x08 ) != 0 && + ( h80211[z + 6] & 0x40 ) == 0 && + ( h80211[z + 6] & 0x80 ) != 0 && + ( h80211[z + 5] & 0x01 ) == 0 ) + { + memcpy( st_cur->wpa.anonce, &h80211[z + 17], 32 ); + + /* authenticator nonce set */ + st_cur->wpa.state = 1; + } + + /* frame 2 or 4: Pairwise == 1, Install == 0, Ack == 0, MIC == 1 */ + + if(( h80211[z + 6] & 0x08 ) != 0 && + ( h80211[z + 6] & 0x40 ) == 0 && + ( h80211[z + 6] & 0x80 ) == 0 && + ( h80211[z + 5] & 0x01 ) != 0 ) + { + if( memcmp( &h80211[z + 17], ZERO, 32 ) != 0 ) + { + memcpy( st_cur->wpa.snonce, &h80211[z + 17], 32 ); + + /* supplicant nonce set */ + st_cur->wpa.state |= 2; + } + + //if( (st_cur->wpa.state & 4) != 4 ) + //{ + /* copy the MIC & eapol frame */ + + st_cur->wpa.eapol_size = ( h80211[z + 2] << 8 ) + + h80211[z + 3] + 4; + + if ((int)pkh.len - z < st_cur->wpa.eapol_size ) + // Ignore the packet trying to crash us. + continue; + + memcpy( st_cur->wpa.keymic, &h80211[z + 81], 16 ); + memcpy( st_cur->wpa.eapol, &h80211[z], st_cur->wpa.eapol_size ); + memset( st_cur->wpa.eapol + 81, 0, 16 ); + + /* eapol frame & keymic set */ + st_cur->wpa.state |= 4; + + /* copy the key descriptor version */ + + st_cur->wpa.keyver = h80211[z + 6] & 7; + //} + } + + /* frame 3: Pairwise == 1, Install == 1, Ack == 1, MIC == 1 */ + + if( ( h80211[z + 6] & 0x08 ) != 0 && + ( h80211[z + 6] & 0x40 ) != 0 && + ( h80211[z + 6] & 0x80 ) != 0 && + ( h80211[z + 5] & 0x01 ) != 0 ) + { + if( memcmp( &h80211[z + 17], ZERO, 32 ) != 0 ) + { + memcpy( st_cur->wpa.anonce, &h80211[z + 17], 32 ); + + /* authenticator nonce set */ + st_cur->wpa.state |= 1; + } + + //if( (st_cur->wpa.state & 4) != 4 ) + //{ + /* copy the MIC & eapol frame */ + + st_cur->wpa.eapol_size = ( h80211[z + 2] << 8 ) + + h80211[z + 3] + 4; + + if ((int)pkh.len - z < st_cur->wpa.eapol_size ) + continue; + + memcpy( st_cur->wpa.keymic, &h80211[z + 81], 16 ); + memcpy( st_cur->wpa.eapol, &h80211[z], st_cur->wpa.eapol_size ); + memset( st_cur->wpa.eapol + 81, 0, 16 ); + + /* eapol frame & keymic set */ + st_cur->wpa.state |= 4; + + /* copy the key descriptor version */ + + st_cur->wpa.keyver = h80211[z + 6] & 7; + //} + } + + if( st_cur->wpa.state == 7 ) + { + /* got one valid handshake */ + /* TODO: write this handshake only if it's quality ( how to know it ? ) is better then the previous one. */ + // use n as boolean switch: 1 => write, 0=>skip + if(essid!=NULL) // essid filter active + if(strncmp(essid,ap_cur->essid,33)) + n=0; + else + n=1; + else + n=1; + if(n==1) + { + memcpy (&(ap_cur->wpa.essid), &ap_cur->essid, sizeof (ap_cur->essid)); + memcpy (&(ap_cur->wpa.mac1), &ap_cur->bssid, sizeof (ap_cur->bssid)); + memcpy (&(ap_cur->wpa.mac2), &stmac, sizeof (st_cur->wpa.stmac)); + memcpy (&(ap_cur->wpa.nonce1), &st_cur->wpa.snonce, sizeof (st_cur->wpa.snonce)); + memcpy (&(ap_cur->wpa.nonce2), &st_cur->wpa.anonce, sizeof (st_cur->wpa.anonce)); + memcpy (&(ap_cur->wpa.eapol), &st_cur->wpa.eapol, sizeof (st_cur->wpa.eapol)); + memcpy (&(ap_cur->wpa.eapol_size), &st_cur->wpa.eapol_size, sizeof (st_cur->wpa.eapol_size)); + memcpy (&(ap_cur->wpa.keyver), &st_cur->wpa.keyver, sizeof (st_cur->wpa.keyver)); + memcpy (&(ap_cur->wpa.keymic), &st_cur->wpa.keymic, sizeof (st_cur->wpa.keymic)); + } + /* reset wpa handshake completation */ + st_cur->wpa.state = 0; + } + } + + /* write unique handshakes to file */ + // use n as write counter. +#ifdef MAX_NETWORKS + for(ap_cur=ap_lst,n=0;ap_cur!=NULL && n < MAX_NETWORKS;ap_cur=ap_cur->next) +#else + for(ap_cur=ap_lst,n=0;ap_cur!=NULL;ap_cur=ap_cur->next) +#endif + if(memcmp(&(ap_cur->wpa), ZERO, 32) != 0) + { + print_hccap(&(ap_cur->wpa)); + n++; + } + + if(n==0) // if no valid handshakes were found. + report_error("unable to find valid handshakes.",0,0,error); + + if(rb.buf1 != NULL) + { + free(rb.buf1); + rb.buf1 = NULL; + } + if(rb.buf2 != NULL) + { + free(rb.buf2); + rb.buf2 = NULL; + } + if(buffer != NULL) + { + free(buffer); + buffer = NULL; + } + + return; + +} + +int main(int argc,char *argv[]) +{ + int i,j,skip[2]; + char *opt="-e"; + + if(argc < 3) + { + snprintf(err_buff,MAX_BUFF,"Usage:\t%s [input.pcap] [input.pcap] dummy", basename(argv[0])); + report_error(err_buff,0,0,error); + printf( "\n" + "this prgram convert one or more pcap capture files into an JtR-jumbo capture one.\n" + "the only option is '-e' for filter handshakes by essid.\n" +#ifdef MAX_NETWORKS + "in this version the maximum number of ESSID is %d\n" + "look at \"OPTFLAGS\" in \"Makefile\" for change or disable this.\n" +#endif + "\n" + "\n" + "main developer:\n" + "\tmassimo dragano - massimo.dragano@gmail.com\n" + "\n" + "NOTE:\n" + "part of this code has been taken from \"aircrack-ng\" suite.\n" + "i will include all legal stuff as soon as i understand what they means. :)\n" +#ifdef MAX_NETWORKS + , MAX_NETWORKS +#endif + ); + exit(EXIT_FAILURE); + } + + memset(&skip,0,2); + + for(essid=NULL,i=1;i 2) // -eESSID + { + skip[0] = i; + skip[1] = 0; + essid=(argv[i] +2); + } + else // -e ESSID + { + skip[0] = i; + skip[1] = i+1; + essid=argv[i+1]; + } + } + + j= argc-1; + if(skip[1] == j) // ... outfile -e ESSID + j-=2; + else if(skip[0] == j) // ... outfile -eESSID + j--; + + for(i=1;i