Skip to content

Commit 0a5bd8b

Browse files
authored
Merge pull request #208 from RealEnder/master
port hcxgrep.py to python3
2 parents a033de3 + d51d763 commit 0a5bd8b

File tree

2 files changed

+61
-95
lines changed

2 files changed

+61
-95
lines changed

Diff for: README.md

+8-22
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ Detailed description
6363
| hcxhashcattool | Convert old hashcat (<= 5.1.0) separate potfile (2500 and/or 16800) to new potfile format |
6464

6565

66-
Work flow
66+
Workflow
6767
--------------
6868

6969
hcxdumptool -> hcxpcapngtool -> hcxhashtool (additional hcxpsktool/hcxeiutool) -> hashcat or JtR
@@ -106,13 +106,15 @@ Or install via packet manager of your distribution
106106
[Arch Linux ARM ](https://archlinuxarm.org/)
107107
`pacman -S hcxtools`
108108

109-
### Black Arch
109+
### BlackArch
110110
[Black Arch](https://blackarch.org/) is an Arch Linux-based penetration testing distribution for penetration testers and security researchers
111111
`pacman -S hcxtools`
112112

113113
### Kali Linux
114114
`apt install hcxtools`
115115

116+
### OpenWRT
117+
`opkg install hcxtools`
116118

117119
### macOS
118120
[Homebrew](https://brew.sh/) is 3-rd party package manager for macOS
@@ -123,47 +125,31 @@ Requirements
123125
--------------
124126

125127
* knowledge of radio technology
126-
127128
* knowledge of electromagnetic-wave engineering
128-
129129
* detailed knowledge of 802.11 protocol
130-
131130
* detailed knowledge of key derivation functions
132-
133131
* detailed knowledge of Linux
134-
135132
* Linux (recommended Arch Linux, but other distros should work, too (no support for other distributions).
136-
137133
* gcc >= 11 recommended (deprecated versions are not supported: https://gcc.gnu.org/)
138-
139134
* libopenssl and openssl-dev installed
140-
141135
* librt and librt-dev installed (should be installed by default)
142-
143136
* zlib and zlib-dev installed (for gzip compressed cap/pcap/pcapng files)
144-
145137
* libcurl and curl-dev installed (used by whoismac and wlancap2wpasec)
146-
147138
* libpthread and pthread-dev installed (used by hcxhashcattool)
148-
149139
* pkg-config installed
150140

151141
To install requirements on Kali use the following 'apt-get install pkg-config libcurl4-openssl-dev libssl-dev zlib1g-dev'
152142

153143
If you decide to compile latest git head, make sure that your distribution is updated on latest version.
154144

155-
156-
157-
158-
159145
Useful scripts
160146
--------------
161147

162148
| Script | Description |
163149
| ------------ | -------------------------------------------------------- |
164150
| piwritecard | Example script to restore SD-Card |
165151
| piwreadcard | Example script to backup SD-Card |
166-
| hcxgrep.py | Extract records from hccapx/pmkid file based on regexp |
152+
| hcxgrep.py | Extract records from m22000 hashline/hccapx/pmkid file based on regexp |
167153

168154

169155
Notice
@@ -187,11 +173,11 @@ bit 0-2
187173

188174
010 = M2+M3, EAPOL from M2 (authorized)
189175

190-
011 = M2+M3, EAPOL from M3 (authorized) - unused"
176+
011 = M2+M3, EAPOL from M3 (authorized) - unused
191177

192-
100 = M3+M4, EAPOL from M3 (authorized) - unused"
178+
100 = M3+M4, EAPOL from M3 (authorized) - unused
193179

194-
101 = M3+M4, EAPOL from M4 if not zeroed (authorized)"
180+
101 = M3+M4, EAPOL from M4 if not zeroed (authorized)
195181

196182
3: reserved
197183

Diff for: usefulscripts/hcxgrep.py

+53-73
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
#!/usr/bin/env python2
1+
#!/usr/bin/env python3
22
'''
33
greps inside hccapx/pmkid structs by essid, mac_ap or mac_sta
44
5-
This software is Copyright (c) 2019-2020, Alex Stanev <alex at stanev.org> and it is
6-
hereby released to the general public under the following terms:
5+
This software is Copyright (c) 2019-2022, Alex Stanev <alex at stanev.org>
6+
and it is hereby released to the general public under the following terms:
77
88
Redistribution and use in source and binary forms, with or without
99
modification, are permitted.
1010
'''
1111

12-
from __future__ import print_function
1312
import argparse
1413
import os
1514
import sys
@@ -18,10 +17,8 @@
1817
import re
1918
import sre_constants
2019

21-
try:
22-
from string import maketrans
23-
except ImportError:
24-
maketrans = bytearray.maketrans # pylint: disable=no-member
20+
maketrans = bytearray.maketrans
21+
2522

2623
def parse_hccapx(hccapx):
2724
'''hccapx decompose
@@ -46,28 +43,25 @@ def parse_hccapx(hccapx):
4643
} __attribute__((packed));
4744
'''
4845

49-
hccapx_fmt = '< 4x 4x B B 32s B 16s 6s 32s 6s 32s H 256s'
46+
hccapx_fmt = '< 4x 4x x B 32s x 16x 6s 32x 6s 32x 2x 256x'
5047

5148
try:
52-
(message_pair,
53-
essid_len, essid,
54-
keyver, keymic,
55-
mac_ap, nonce_ap, mac_sta, nonce_sta,
56-
eapol_len, eapol) = struct.unpack(hccapx_fmt, hccapx)
57-
except struct.error as ex:
58-
sys.stderr.write(str(ex + '\n'))
59-
exit(1)
49+
(essid_len, essid,
50+
mac_ap, mac_sta) = struct.unpack(hccapx_fmt, hccapx)
51+
except struct.error:
52+
sys.stderr.write('Can\'t parse hcccapx struct!\n')
53+
sys.exit(1)
6054

6155
# fixup
62-
res = ''
6356
if args.t == 'essid':
64-
res = essid[:essid_len]
65-
elif args.t == 'mac_ap':
66-
res = binascii.hexlify(mac_ap).zfill(12)
67-
elif args.t == 'mac_sta':
68-
res = binascii.hexlify(mac_sta).zfill(12)
57+
return essid[:essid_len]
58+
if args.t == 'mac_ap':
59+
return binascii.hexlify(mac_ap).zfill(12)
60+
if args.t == 'mac_sta':
61+
return binascii.hexlify(mac_sta).zfill(12)
62+
63+
return None
6964

70-
return res
7165

7266
def parse_pmkid(pmkid):
7367
'''pmkid decompose
@@ -77,20 +71,20 @@ def parse_pmkid(pmkid):
7771
'''
7872

7973
arr = pmkid.split(b'*', 4)
80-
res = ''
8174
if len(arr) == 4:
8275
try:
8376
if args.t == 'essid':
84-
res = binascii.unhexlify(arr[3].strip())
85-
elif args.t == 'mac_ap':
86-
res = arr[1]
87-
elif args.t == 'mac_sta':
88-
res = arr[2]
89-
except TypeError as ex:
90-
sys.stderr.write(str(ex + '\n'))
91-
exit(1)
77+
return binascii.unhexlify(arr[3].strip())
78+
if args.t == 'mac_ap':
79+
return arr[1]
80+
if args.t == 'mac_sta':
81+
return arr[2]
82+
except TypeError:
83+
sys.stderr.write('Can\'t decode: {}\n'.format(arr[3].strip().decode()))
84+
sys.exit(1)
85+
86+
return None
9287

93-
return res
9488

9589
def parse_combined(hashline):
9690
'''m22000 hashline decompose
@@ -100,25 +94,23 @@ def parse_combined(hashline):
10094
'''
10195

10296
arr = hashline.split(b'*', 9)
103-
res = ''
10497
if len(arr) == 9:
10598
try:
10699
if args.t == 'essid':
107-
res = binascii.unhexlify(arr[5].strip())
108-
elif args.t == 'mac_ap':
109-
res = arr[3]
110-
elif args.t == 'mac_sta':
111-
res = arr[4]
112-
except TypeError as ex:
113-
sys.stderr.write(str(ex + '\n'))
114-
exit(1)
100+
return binascii.unhexlify(arr[5].strip())
101+
if args.t == 'mac_ap':
102+
return arr[3]
103+
if args.t == 'mac_sta':
104+
return arr[4]
105+
except TypeError:
106+
sys.stderr.write('Can\'t decode: {}\n'.format(arr[5].strip().decode()))
107+
sys.exit(1)
115108

116-
return res
109+
return None
117110

118111
if __name__ == "__main__":
119112
parser = argparse.ArgumentParser(
120-
description='Extract records from wpa combined hashline/hccapx/pmkid file based on regexp')
121-
#group = parser.add_mutually_exclusive_group(required=True)
113+
description='Extract records from m22000 hashline/hccapx/pmkid file with regexp')
122114
parser.add_argument(
123115
'-f', '--file', type=argparse.FileType('r'),
124116
help='Obtain patterns from FILE, one per line.')
@@ -130,7 +122,8 @@ def parse_combined(hashline):
130122
'-v', '--invert-match', dest='v', action='store_true',
131123
help='Invert the sense of matching, to select non-matching nets')
132124
parser.add_argument(
133-
'-t', '--type', dest='t', choices=['essid','mac_ap','mac_sta'], default='essid',
125+
'-t', '--type', dest='t',
126+
choices=['essid', 'mac_ap', 'mac_sta'], default='essid',
134127
help='Field to apply matching, default essid')
135128
parser.add_argument(
136129
'infile', type=str, nargs='?',
@@ -141,11 +134,6 @@ def parse_combined(hashline):
141134
except IOError as ex:
142135
parser.error(str(ex))
143136

144-
# workaround encoding issues with python2
145-
if sys.version_info[0] == 2:
146-
reload(sys) # pylint: disable=undefined-variable
147-
sys.setdefaultencoding('utf-8') # pylint: disable=no-member
148-
149137
# shift parameters
150138
if args.file and args.PATTERNS:
151139
args.infile = args.PATTERNS
@@ -155,50 +143,42 @@ def parse_combined(hashline):
155143
if args.PATTERNS is None and args.file is None:
156144
parser.print_help(sys.stderr)
157145
sys.stderr.write('You must provide PATTERNS or -f FILE\n')
158-
exit(1)
146+
sys.exit(1)
159147

160148
# read patterns from file
161149
if args.PATTERNS is None:
162150
args.PATTERNS = '|'.join('(?:{0})'.format(x.strip()) for x in args.file)
163151

164152
try:
165153
regexp = re.compile(args.PATTERNS)
166-
except sre_constants.error as e:
167-
sys.stderr.write('Wrong regexp {0}: {1} \n'.format(args.PATTERNS, e))
168-
exit(1)
154+
except sre_constants.error as ex:
155+
sys.stderr.write('Wrong regexp {0}: {1} \n'.format(args.PATTERNS, ex))
156+
sys.exit(1)
169157

170158
if args.infile is not None and os.path.isfile(args.infile):
171159
fd = open(args.infile, 'rb')
172160
else:
173161
fd = sys.stdin
174-
175-
structformat = ''
162+
176163
while True:
177164
buf = fd.read(4)
178-
if buf == 'WPA*':
165+
if buf == b'WPA*':
179166
buf = buf + fd.readline()
180-
structformat = 'combined'
181-
elif buf == 'HCPX':
167+
target = parse_combined(buf)
168+
elif buf == b'HCPX':
182169
buf = buf + fd.read(393 - 4)
183-
structformat = 'hccapx'
170+
target = parse_hccapx(buf)
184171
else:
185172
buf = buf + fd.readline()
186-
structformat = 'pmkid'
173+
target = parse_pmkid(buf)
187174

188175
if not buf:
189176
break
190177

191-
if structformat == 'combined':
192-
target = parse_combined(buf)
193-
elif structformat == 'hccapx':
194-
target = parse_hccapx(buf)
195-
elif structformat == 'pmkid':
196-
target = parse_pmkid(buf)
197-
else:
178+
if target is None:
198179
sys.stderr.write('Unrecognized input format\n')
199-
exit(1)
180+
sys.exit(1)
200181

201182
res = regexp.search(str(target))
202183
if (res is not None and not args.v) or (res is None and args.v):
203-
sys.stdout.write(buf)
204-
184+
sys.stdout.buffer.write(buf)

0 commit comments

Comments
 (0)