Skip to content

Commit

Permalink
Merge pull request #150 from s0lst1c3/captive-portal-revamp
Browse files Browse the repository at this point in the history
Captive portal revamp
  • Loading branch information
s0lst1c3 authored Sep 9, 2020
2 parents 7bb390d + 98052b3 commit e39b613
Show file tree
Hide file tree
Showing 42 changed files with 2,418 additions and 56 deletions.
3 changes: 3 additions & 0 deletions Changelog
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,6 @@ Fixed kali-setup file, updated kali-dependencies.txt file

1.12.3 - Gabriel Ryan <gabriel@specterops.io>
Added official support for Parot OS (Security)

1.13.0 - Gabriel Ryan <gabriel@solstice.sh>
Revamped captive portal system. Added integrated website cloaner. Added raspbian support.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ by Gabriel Ryan ([s0lst1c3](https://twitter.com/s0lst1c3))(gabriel[at]solstice|d

[![Foo](https://rawcdn.githack.com/toolswatch/badges/8bd9be6dac2a1d445367001f2371176cc50a5707/arsenal/usa/2017.svg)](https://www.blackhat.com/us-17/arsenal.html#eaphammer)

Current release: [v1.12.3](https://github.com/s0lst1c3/eaphammer/releases/tag/v1.12.3)
Current release: [v1.13.0](https://github.com/s0lst1c3/eaphammer/releases/tag/v1.13.0)

Supports _Python 3.5+_.

Expand Down Expand Up @@ -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.7.0)(latest):
### New (as of Version 1.13.0)(latest):
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)
EAPHammer now supports WPA/2-PSK along with WPA handshake captures.

### OWE (added as of Version 1.5.0):
Expand Down
6 changes: 3 additions & 3 deletions __version__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__version__ = '1.12.3'
__version__ = '1.13.0'
__codename__ = 'Power Overwhelming'
__author__ = '@s0lst1c3'
__contact__ = 'gabriel@specterops.io'
__tagline__ = 'Rogue AP attacks for operators.'
__contact__ = 'gabriel<<at>>solstice(doT)me'
__tagline__ = 'A nice shiny new access point.'
51 changes: 51 additions & 0 deletions base/module.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import sys

class Module(object):

def __init__(self):

self.required_attrs([

'name',
'mtype',
'author',
'description',
])

def required_attrs(self, attrs):

if hasattr(self, '_required_attrs'):

self._required_attrs += attrs

else:

self._required_attrs = attrs



def validate(self):

for ra in self._required_attrs:
if not hasattr(self, ra):
sys.exit('Missing attribute' + ra)

def __str__(self):

return f'{self.name:<16} - {self.description}'

def __getitem__(self, key):

for k,v in self.options.items():

if k.lower() == key.lower():
return self.options[k]['Value']

def __setitem__(self, key, value):

for k,v in self.options.items():

if k.lower() == key.lower():

self.options[k]['Value'] = value

3 changes: 3 additions & 0 deletions core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@
from . import cli
from . import interface
from . import iw_parse
from . import wskeyloggerd
from . import portal_server
from . import module_maker
173 changes: 173 additions & 0 deletions core/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
BASIC_OPTIONS = [

'cert_wizard',
'list_templates',
'reap_creds',
'capture_wpa_handshakes',
'psk_capture_file',
Expand All @@ -21,21 +22,32 @@
'ssid_whitelist',
'ssid_blacklist',
'hostile_portal',
'dl_form_message',
'captive_portal',
'payload',
'debug',
'interface',
'essid',
'bssid',
'pmf',
'owe_transition_bssid',
'add_download_form',
'owe_transition_ssid',
'portal_user_template',
'channel',
'hw_mode',
'cloaking',
'auth',
'lhost',
'lport',
'karma',
'mana',
'loud',
'create_template',
'delete_template',
'name',
'description',
'author',
'known_beacons',
'channel_width',
'auth_alg',
Expand All @@ -45,6 +57,7 @@
'remote_rig',
'wordlist',
'pivot',
'captive_portal_server_only',
'eap_spray',
'password',
'interface_pool',
Expand Down Expand Up @@ -96,6 +109,23 @@ def set_options():
'to manually regenerate eaphammer\'s dh '
'parameters.')

modes_group_.add_argument('--list-templates',
dest='list_templates',
action='store_true',
help=('List available templates for the '
'captive portal'))

modes_group_.add_argument('--create-template',
dest='create_template',
action='store_true',
help=('Create a template by cloaning '
'a login page'))

modes_group_.add_argument('--delete-template',
dest='delete_template',
action='store_true',
help=('Delete a captive portal template.'))

modes_group_.add_argument('--bootstrap',
dest='bootstrap',
action='store_true',
Expand Down Expand Up @@ -133,6 +163,12 @@ def set_options():
help='Force clients to connect '
'to hostile portal')

modes_group_.add_argument('--captive-portal-server-only',
dest='captive_portal_server_only',
action='store_true',
help='Run the captive portal server as a'
'standalone service.')

modes_group_.add_argument('--captive-portal',
dest='captive_portal',
action='store_true',
Expand Down Expand Up @@ -328,6 +364,13 @@ def set_options():

access_point_group = parser.add_argument_group('Access Point')

access_point_group.add_argument('--lhost',
dest='lhost',
type=str,
default='10.0.0.1',
required=False,
help='Your AP\'s IP address')

access_point_group.add_argument('-i', '--interface',
dest='interface',
default=None,
Expand Down Expand Up @@ -792,6 +835,104 @@ def set_options():
help='Specify the wordlist to use with '
'the autocrack feature.')

ctmp_group = parser.add_argument_group('Create / Delete Template Options',
('Only applicable if --create-template '
'or --delete-template is used.'))

ctmp_group.add_argument('--url',
dest='url',
type=str,
default=None,
required=False,
help='Specify url from which to clone captive portal')

ctmp_group.add_argument('--name',
dest='name',
type=str,
default=None,
required=False,
help='Specify name of resulting portal template module')

ctmp_group.add_argument('--description',
dest='description',
type=str,
default='',
required=False,
help='Specify description of resulting portal template module')

ctmp_group.add_argument('--author',
dest='author',
type=str,
default='',
required=False,
help='Specify author of resulting portal template module')

ctmp_group.add_argument('--add-download-form',
dest='add_download_form',
action='store_true',
help='Add a download form to your captive portal.')

ctmp_group.add_argument('--dl-form-message',
dest='dl_form_message',
type=str,
default='Please download our secure profile to continue.',
required=False,
help='Specify download form text.')

cptl_group = parser.add_argument_group('Captive Portal Options',
'Only applicable if --captive-portal is used')

cptl_group.add_argument('--lport',
dest='lport',
type=int,
default=80,
required=False,
help='Port on which to run captive portal.')

cptl_group.add_argument('--payload',
dest='payload',
type=str,
default='profile.msi',
required=False,
help='Specify payload name (defaults to payload.msi test file)')

cptl_group.add_argument('--portal-template',
dest='portal_user_template',
type=str,
default='login',
required=False,
help='Specify template directory')

cptl_group.add_argument('--portal-debug',
dest='portal_debug',
action='store_true',
required=False,
help='Show debug for portal server only')

cptl_group.add_argument('--portal-https',
dest='portal_https',
action='store_true',
required=False,
help='Use HTTPS')

cptl_group.add_argument('--portal-priv-key',
dest='portal_private_key',
type=str,
required=False,
help='private key')

cptl_group.add_argument('--portal-fullchain',
dest='portal_fullchain',
type=str,
required=False,
help='fullchain')

cptl_group.add_argument('--portal-cert',
dest='portal_cert',
type=str,
required=False,
help='cert')

hp_group = parser.add_argument_group('Hostile Portal Options',
'Only applicable if --hostile-portal is used')

Expand Down Expand Up @@ -847,6 +988,10 @@ def set_options():
options['advanced_help'] is False and
options['eap_spray'] is False and
options['bootstrap'] is False and
options['list_templates'] is False and
options['captive_portal_server_only'] is False and
options['delete_template'] is False and
options['create_template'] is False and
options['interface'] is None):

parser.print_usage()
Expand Down Expand Up @@ -898,6 +1043,34 @@ def set_options():
print(msg, end='')
sys.exit()

if options['delete_template']:

if options['name'] is None:
parser.print_usage()
print()
msg = ('[!] Please specify a name for your template '
'using the --name flag.')
print(msg, end='')
sys.exit()

if options['create_template']:

if options['name'] is None:
parser.print_usage()
print()
msg = ('[!] Please specify a name for your template '
'using the --name flag.')
print(msg, end='')
sys.exit()

if options['url'] is None:
parser.print_usage()
print()
msg = ('[!] Please specify a url from which to clone '
'clone your template using the --url flag.')
print(msg, end='')
sys.exit()

if options['loud'] and not options['karma']:

parser.print_usage()
Expand Down
16 changes: 9 additions & 7 deletions core/cnf_templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -2028,15 +2028,16 @@
port=0
# DHCP configs
dhcp-range=10.0.0.100,10.0.0.254,1h
dhcp-option=6,10.0.0.1 #DNS
dhcp-option=3,10.0.0.1 #Gateway
dhcp-range=%s,%s,1h
dhcp-option=6,%s #DNS
dhcp-option=3,%s #Gateway
dhcp-authoritative
log-queries
log-dhcp
log-facility=%s
dhcp-script=%s
'''
# % (interface, dhcp_start, dhcp_end, lhost, lhost, log_file, dhcp_script))

dnsmasq_captive_portal = '''
# general configs
Expand All @@ -2045,18 +2046,19 @@
except-interface=lo
# DHCP configs
dhcp-range=10.0.0.100,10.0.0.254,1h
dhcp-option=6,10.0.0.1 #DNS
dhcp-option=3,10.0.0.1 #Gateway
dhcp-range=%s,%s,1h
dhcp-option=6,%s #DNS
dhcp-option=3,%s #Gateway
dhcp-authoritative
log-queries
log-dhcp
log-facility=%s
dhcp-script=%s
# DNS configs
address=/#/10.0.0.1
address=/#/%s
'''
# % (interface, dhcp_start, dhcp_end, lhost, lhost, log_file, dhcp_script, lhost)

responder_cnf = '''
[Responder Core]
Expand Down
Loading

0 comments on commit e39b613

Please sign in to comment.