Skip to content

Commit eac33fc

Browse files
authored
Merge pull request #124 from s0lst1c3/known-ssids-flag
Added --known-ssids flag
2 parents 45d1350 + f3bfd09 commit eac33fc

8 files changed

Lines changed: 143 additions & 8 deletions

File tree

Changelog

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,6 @@ Added ssid and mac address level ACLs.
150150

151151
1.11.0 - Gabriel Ryan <gryan@specterops.io>
152152
Added beacon forger for executing known SSID bursts
153+
154+
1.12.0 - Gabriel Ryan <gryan@specterops.io>
155+
Added --known-ssids flag that can be used instead of --known-ssids-file flag.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ by Gabriel Ryan ([s0lst1c3](https://twitter.com/s0lst1c3))(gryan[at]specterops.i
44

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

7-
Current release: [v1.11.0](https://github.com/s0lst1c3/eaphammer/releases/tag/v1.11.0)
7+
Current release: [v1.12.0](https://github.com/s0lst1c3/eaphammer/releases/tag/v1.12.0)
88

99
Supports _Python 3.5+_.
1010

__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = '1.11.0'
1+
__version__ = '1.12.0'
22
__codename__ = 'Power Overwhelming'
33
__author__ = '@s0lst1c3'
44
__contact__ = 'gryan@specterops.io'

core/cli.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
'user_list',
5151
'bootstrap',
5252
'known_ssids_file',
53+
'known_ssids',
5354
'negotiate',
5455
]
5556

@@ -467,6 +468,13 @@ def set_options():
467468
help='Specify the wordlist to use with '
468469
'the --known-beacons features.')
469470

471+
karma_group.add_argument('--known-ssids',
472+
dest='known_ssids',
473+
nargs='+',
474+
default=None,
475+
type=str,
476+
help='Specify known ssids via the CLI')
477+
470478
ap_advanced_subgroup = parser.add_argument_group('AP Advanced Options')
471479

472480
ap_advanced_subgroup.add_argument('--wmm',
@@ -908,18 +916,32 @@ def set_options():
908916
print(msg, end='')
909917
sys.exit()
910918

911-
if options['known_ssids_file'] is None:
919+
if options['known_ssids_file'] is None and \
920+
options['known_ssids'] is None:
912921

913922
parser.print_usage()
914923
print()
915-
msg = ('[!] Cannot use --known-beacons without known SSIDS file. '
916-
'Please specify path to known SSIDS file with --known-ssids flag.')
924+
msg = ('[!] Cannot use --known-beacons '
925+
'without list of known SSIDS. '
926+
'Please specify path to known SSIDS '
927+
'file with the --known-ssids-file flag, '
928+
'or provide a list of known SSIDS '
929+
'using the --known-ssids flag.')
917930
print(msg, end='')
918931
sys.exit()
919932

920-
933+
if options['known_ssids_file'] is not None and \
934+
options['known_ssids'] is not None:
935+
936+
parser.print_usage()
937+
print()
938+
msg = ('[!] Cannot use --known-ssids-file '
939+
'and --known-ssids flags simultaneously.')
940+
print(msg, end='')
941+
sys.exit()
921942

922-
if not Path(options['known_ssids_file']).is_file():
943+
if options['known_ssids_file'] is not None and \
944+
not Path(options['known_ssids_file']).is_file():
923945

924946
parser.print_usage()
925947
print()

core/hostapd_config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ def populate_general(self, settings, options):
526526

527527
if options['known_beacons']:
528528
general_configs['known_beacons'] = '1'
529-
general_configs['known_ssids_file'] = options['known_ssids_file']
529+
general_configs['known_ssids_file'] = settings.dict['paths']['hostapd']['known_ssids']
530530
else:
531531
general_configs['known_beacons'] = settings.dict['core']['hostapd']['general']['known_beacons']
532532

core/known_ssids_file.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import os
2+
import shutil
3+
import sys
4+
5+
class KnownSSIDSFile(object):
6+
7+
def __init__(self,
8+
settings,
9+
options):
10+
11+
self.debug = options['debug']
12+
self.known_ssids = []
13+
self.output_path = settings.dict['paths']['hostapd']['known_ssids']
14+
15+
# having to do this makes me wish that python had a
16+
# logic XOR operator... or even a NAND operator for
17+
# that matter...
18+
assert not (options['known_ssids_file'] is None and options['known_ssids'] is None)
19+
assert not (options['known_ssids_file'] is not None and options['known_ssids'] is not None)
20+
21+
if options['known_ssids_file'] is not None:
22+
23+
with open(options['known_ssids_file']) as fd:
24+
25+
for line in fd:
26+
27+
# remove '\n' from end of line
28+
ssid = line.rstrip('\n')
29+
if ssid.strip() != ssid:
30+
print('[eaphammer] WARNING: whitespace detected '
31+
'at beginning or end of known-ssids-file. '
32+
'Assuming this is intentional.')
33+
self.known_ssids.append(ssid)
34+
35+
elif options['known_ssids'] is not None:
36+
37+
self.known_ssids = options['known_ssids']
38+
39+
else:
40+
raise Exception('[KnownSSIDSFile] this should never happen')
41+
42+
43+
if self.debug:
44+
print('[KnownSSIDSFile] self.known_ssids: ', self.known_ssids)
45+
print('[KnownSSIDSFile] self.output_path: ', self.output_path)
46+
47+
def remove(self):
48+
49+
if not self.debug:
50+
51+
try:
52+
53+
os.remove(self.output_path)
54+
55+
except FileNotFoundError:
56+
57+
print('[KnownSSIDSFile] Cannot remove file that does not exist')
58+
59+
def path(self, path=None):
60+
61+
if path is not None:
62+
self.output_path = path
63+
64+
return self.output_path
65+
66+
def generate(self):
67+
68+
69+
with open(self.output_path, 'w') as fd:
70+
for ssid in self.known_ssids:
71+
fd.write('{}\n'.format(ssid))
72+
73+
return self.path()

eaphammer

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ from core.hostapd_config import HostapdConfig
2121
from core.eap_user_file import EAPUserFile
2222
from core.hostapd_mac_acl import HostapdMACACL
2323
from core.hostapd_ssid_acl import HostapdSSIDACL
24+
from core.known_ssids_file import KnownSSIDSFile
2425
from core.responder_config import ResponderConfig
2526
from core.lazy_file_reader import LazyFileReader
2627
from core.redirect_server import RedirectServer
@@ -74,6 +75,10 @@ def hostile_portal():
7475
hostapd_ssid_acl = HostapdSSIDACL(settings, options)
7576
hostapd_ssid_acl.generate()
7677

78+
if options['known_beacons']:
79+
known_ssids_file = KnownSSIDSFile(settings, options)
80+
known_ssids_file.generate()
81+
7782
# write hostapd config file to tmp directory
7883
hostapd_conf = HostapdConfig(settings, options)
7984
hostapd_conf.write()
@@ -247,6 +252,10 @@ def captive_portal():
247252
hostapd_ssid_acl = HostapdSSIDACL(settings, options)
248253
hostapd_ssid_acl.generate()
249254

255+
if options['known_beacons']:
256+
known_ssids_file = KnownSSIDSFile(settings, options)
257+
known_ssids_file.generate()
258+
250259
# write hostapd config file to tmp directory
251260
hostapd_conf = HostapdConfig(settings, options)
252261
hostapd_conf.write()
@@ -303,6 +312,9 @@ def captive_portal():
303312

304313
# remove acl file from tmp directory
305314
hostapd_ssid_acl.remove()
315+
316+
if options['known_beacons']:
317+
known_ssids_file.remove()
306318

307319
# restore iptables to a clean state (policy, flush tables)
308320
utils.Iptables.accept_all()
@@ -341,6 +353,9 @@ def captive_portal():
341353

342354
# remove acl file from tmp directory
343355
hostapd_ssid_acl.remove()
356+
357+
if options['known_beacons']:
358+
known_ssids_file.remove()
344359

345360
# restore iptables to a clean state (policy, flush tables)
346361
utils.Iptables.accept_all()
@@ -378,6 +393,10 @@ def troll_defender():
378393
hostapd_ssid_acl = HostapdSSIDACL(settings, options)
379394
hostapd_ssid_acl.generate()
380395

396+
if options['known_beacons']:
397+
known_ssids_file = KnownSSIDSFile(settings, options)
398+
known_ssids_file.generate()
399+
381400
# write hostapd config file to tmp directory
382401
hostapd_conf = HostapdConfig(settings, options)
383402
hostapd_conf.write()
@@ -421,6 +440,9 @@ def troll_defender():
421440
# remove acl file from tmp directory
422441
hostapd_ssid_acl.remove()
423442

443+
if options['known_beacons']:
444+
known_ssids_file.remove()
445+
424446
# cleanly allow network manager to regain control of interface
425447
interface.nm_on()
426448

@@ -462,6 +484,10 @@ def reap_creds():
462484
hostapd_ssid_acl = HostapdSSIDACL(settings, options)
463485
hostapd_ssid_acl.generate()
464486

487+
if options['known_beacons']:
488+
known_ssids_file = KnownSSIDSFile(settings, options)
489+
known_ssids_file.generate()
490+
465491
# write hostapd config file to tmp directory
466492
hostapd_conf = HostapdConfig(settings, options)
467493
hostapd_conf.write()
@@ -497,6 +523,9 @@ def reap_creds():
497523
# remove acl file from tmp directory
498524
hostapd_ssid_acl.remove()
499525

526+
if options['known_beacons']:
527+
known_ssids_file.remove()
528+
500529
# cleanly allow network manager to regain control of interface
501530
interface.nm_on()
502531

@@ -526,6 +555,9 @@ def reap_creds():
526555
# remove acl file from tmp directory
527556
hostapd_ssid_acl.remove()
528557

558+
if options['known_beacons']:
559+
known_ssids_file.remove()
560+
529561
# cleanly allow network manager to regain control of interface
530562
interface.nm_on()
531563

settings/paths.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ def __str__(self):
9898
PHASE1_ACCOUNTS = os.path.join(DB_DIR, 'phase1.accounts')
9999
PHASE2_ACCOUNTS = os.path.join(DB_DIR, 'phase2.accounts')
100100

101+
# known ssids file
102+
output_file = OutputFile(ext='known_ssids').string()
103+
KNOWN_SSIDS_FILE = os.path.join(TMP_DIR, output_file)
104+
101105
# ACL Files
102106
output_file = OutputFile(ext='accept').string()
103107
HOSTAPD_MAC_WHITELIST = os.path.join(TMP_DIR, output_file)
@@ -193,6 +197,7 @@ def __str__(self):
193197
'mac_blacklist' : HOSTAPD_MAC_BLACKLIST,
194198
'ssid_whitelist' : HOSTAPD_SSID_WHITELIST,
195199
'ssid_blacklist' : HOSTAPD_SSID_BLACKLIST,
200+
'known_ssids' : KNOWN_SSIDS_FILE,
196201
},
197202

198203
'certs' : {

0 commit comments

Comments
 (0)