@@ -71,7 +71,7 @@ def init(self):
7171 else :
7272 self .tell ("Option '%s' not known. Ignoring..." % option )
7373
74- if self .options .file == "-" :
74+ if self .options .file == "-" or 'passthrough' in commands :
7575 self .options .verbose = False
7676
7777 self .essidstore = EssidStore (self .options .essidstore_path )
@@ -87,35 +87,40 @@ def init(self):
8787 'export_hashdb' : self .export_hashdb ,
8888 'export_passwords' : self .export_passwords ,
8989 'import_passwords' : self .import_passwords ,
90+ 'list_cores' : self .list_cores ,
9091 'list_essids' : self .list_essids ,
9192 'create_essid' : self .create_essid ,
9293 'eval' : self .eval_results ,
9394 'count_results' : self .count_results ,
9495 'batch' : self .batchprocess ,
9596 'batchprocess' : self .batchprocess ,
97+ 'passthrough' : self .passthrough ,
9698 'benchmark' : self .benchmark ,
9799 'help' : self .print_help
98100 }.setdefault (commands [0 ] if len (commands ) > 0 else 'help' , self .print_help )()
99101
100102 def print_help (self ):
101- self .tell ("usage: pyrit_cli [options] command " \
103+ self .tell ("usage: pyrit.py [options] command " \
102104 "\n \n Recognized options:" \
103- "\n -u : path to the ESSID-blobspace" \
104- "\n -v : path to the Password-blobspace" \
105- "\n -c : name of the core to use. 'Standard CPU' is default" \
106- "\n -e : ESSID for the command" \
107- "\n -f : filename for the command ('-' is stdin/stdout)" \
108- "\n -n : number of CPUs to use" \
109- "\n \n Recognized commands:" \
110- "\n benchmark : Benchmark a core (-c and -n are optional)" \
111- "\n batch : Start batchprocessing (-c, -u, -v, -n, -f and -e are optional)" \
112- "\n list_essids : List all ESSIDs in the ESSID-blobspace" \
113- "\n count_results : List all ESSIDs and count the PMKs in the ESSID-blobspace" \
114- "\n eval : Count the passwords available and the results already computed (-e is optional)" \
115- "\n import_passwords : Import passwords into the Password-blobspace (-f is mandatory)" \
116- "\n create_essid : Create a new ESSID (-e is mandatory)" \
117- "\n export_cowpatty : Export into a new cowpatty file (-e and -f are mandatory)" \
118- "\n export_hashdb : Export into an existing airolib database (-e is optional, -f is mandatory)" )
105+ "\n -c : name of the core to use. 'Standard CPU' is default" \
106+ "\n -e : ESSID for the command" \
107+ "\n -f : filename for the command ('-' is stdin/stdout)" \
108+ "\n -n : number of CPUs to use" \
109+ "\n -u : path to the ESSID-blobspace" \
110+ "\n -v : path to the Password-blobspace" \
111+ "\n \n Recognized commands (Possible options: M=must, C=can):" \
112+ "\n batch : Start batchprocessing (C: cefnuv)" \
113+ "\n benchmark : Benchmark a core (C: cn)" \
114+ "\n count_results : List all ESSIDs and count the PMKs in the ESSID-blobspace" \
115+ "\n create_essid : Create a new ESSID (M: e)" \
116+ "\n eval : Count the passwords available and matching results (C: e)" \
117+ "\n export_cowpatty : Export into a new cowpatty file (M: ef)" \
118+ "\n export_hashdb : Export into an existing airolib database (C: e; M: f)" \
119+ "\n import_passwords : Import passwords into the Password-blobspace (M: f)" \
120+ "\n list_cores : List available cores" \
121+ "\n list_essids : List all ESSIDs in the ESSID-blobspace" \
122+ "\n passthrough : Compute PMKs on the fly and write to stdout (M: cefn)" \
123+ "\n " )
119124
120125 def create_essid (self ):
121126 essid = self .options .essid
@@ -132,14 +137,19 @@ def count_results(self):
132137 for i , essid in enumerate (self .essidstore ):
133138 self .tell ("#%i: '%s' (%i PMKs)" % (i , essid , sum ((len (results ) for key ,results in self .essidstore [essid ]))))
134139
140+ def list_cores (self ):
141+ self .tell ("Listing available cores..." )
142+ for i , (corename , core ) in enumerate (cpyrit .CPyrit ()):
143+ self .tell ("#%i: '%s' (%s)" % (i , corename , core .ctype ))
144+
135145 def list_essids (self ):
136146 self .tell ("Listing ESSIDs..." )
137147 for i , essid in enumerate (self .essidstore ):
138148 self .tell ("#%i: '%s'" % (i , essid ))
139149
140150 def import_passwords (self ):
141151 if self .options .file is None :
142- self .tell ("One must specify a filename using the -f options . See 'help'" , stream = sys .stderr )
152+ self .tell ("One must specify a filename using the -f option . See 'help'" , stream = sys .stderr )
143153 else :
144154 self .tell ("Importing from " , end = None )
145155 if self .options .file == "-" :
@@ -187,7 +197,7 @@ def export_passwords(self):
187197 sys .stdout .write (row + "\n " )
188198 sys .stdout .flush ()
189199 else :
190- f = open (self .options .file ,"w " )
200+ f = open (self .options .file ,"wb " )
191201 self .tell ("Exporting to '%s'..." % self .options .file )
192202 max_idx = 0
193203 lines = 0
@@ -221,7 +231,7 @@ def export_cowpatty(self):
221231 except IOError :
222232 self .tell ("IOError while exporting to stdout ignored..." , stream = sys .stderr )
223233 else :
224- f = open (self .options .file , "w " )
234+ f = open (self .options .file , "wb " )
225235 self .tell ("Exporting to '%s'..." % self .options .file )
226236 lines = 0
227237 for row in self ._genCowpatty (self .essidstore [self .options .essid ]):
@@ -232,6 +242,43 @@ def export_cowpatty(self):
232242 self .tell ("\r %i entries written. All done." % lines )
233243 f .close ()
234244
245+ def passthrough (self ):
246+ cp = cpyrit .CPyrit (ncpus = self .options .ncpus )
247+ if self .options .core_name is not None :
248+ core = cp [self .options .core_name ]
249+ else :
250+ core = cp [None ]
251+ if self .options .essid is None :
252+ self .tell ("Specifiy a ESSID using the -e option. See 'help'" , stream = sys .stderr )
253+ return
254+ if self .options .file is None :
255+ self .tell ("Specify a filename using the -f option to read passwords from. See 'help'" , stream = sys .stderr )
256+ return
257+ if self .options .file == "-" :
258+ f = sys .stdin
259+ else :
260+ f = open (self .options .file , "r" )
261+ pwbuffer = []
262+ try :
263+ sys .stdout .write (struct .pack ("<i3s" , 0x43575041 , '\00 ' * 3 ))
264+ sys .stdout .write (struct .pack ("<b32s" , len (self .options .essid ), self .options .essid ))
265+ while True :
266+ pw = f .readline ().strip ()
267+ if not pw :
268+ break
269+ if len (pw ) >= 8 :
270+ pwbuffer .append (pw [:63 ])
271+ if len (pwbuffer ) > 20000 :
272+ for pw , pmk in core .solve (self .options .essid , pwbuffer ):
273+ sys .stdout .write (struct .pack ("<b%ss32s" % len (pw ), len (pw ) + 32 + 1 , pw , pmk ))
274+ pwbuffer = []
275+ for pw , pmk in core .solve (self .options .essid , pwbuffer ):
276+ sys .stdout .write (struct .pack ("<b%ss32s" % len (pw ), len (pw ) + 32 + 1 , pw , pmk ))
277+ except IOError :
278+ self .tell ("IOError while writing to stdout ignored..." , stream = sys .stderr )
279+ finally :
280+ f .close ()
281+
235282 def export_hashdb (self ):
236283 if 'sqlite' in locals ():
237284 self .tell ("Support for SQLite seems to be missing. Please check if the pysqlite2 module is available to python." , stream = sys .stderr )
@@ -282,10 +329,10 @@ def batchprocess(self):
282329
283330 cp = cpyrit .CPyrit (ncpus = self .options .ncpus )
284331 if self .options .core_name is not None :
285- core = cp . getCore ( self .options .core_name )
332+ core = cp [ self .options .core_name ]
286333 self .tell ("Selected core '%s'" % core .name , end = None )
287334 else :
288- core = cp . getCore ()
335+ core = cp [ None ]
289336 self .tell ("Using default core '%s'" % core .name , end = None )
290337 self .tell ("(Device '%s')" % core .devicename if core .ctype == 'GPU' else "(%i CPUs)" % cp .ncpus )
291338
@@ -368,9 +415,9 @@ def runbench(core):
368415 return (len (pws ) / t , md .hexdigest () == "ef747d123821851a9bd1d1e94ba048ac" )
369416
370417 c = cpyrit .CPyrit (ncpus = self .options .ncpus )
371- self .tell ("Available cores: " + ", " .join ([ "'%s'" % core [0 ] for core in c . listCores ()] ))
418+ self .tell ("Available cores: " + ", " .join (( "'%s'" % core [0 ] for core in c ) ))
372419
373- core = c . getCore ( 'Standard CPU' )
420+ core = c [ 'Standard CPU' ]
374421 self .tell ("Testing CPU-only core '%s' (%i CPUs)... " % (core .name , c .ncpus ), end = None , flush = True )
375422 perf , chk = runbench (core )
376423 if chk :
@@ -379,8 +426,8 @@ def runbench(core):
379426 self .tell ("FAILED" )
380427 self .tell ("" )
381428
382- if 'Nvidia CUDA' in [ x [0 ] for x in c . listCores ()] :
383- core = c . getCore ( 'Nvidia CUDA' )
429+ if 'Nvidia CUDA' in ( x [0 ] for x in c ) :
430+ core = c [ 'Nvidia CUDA' ]
384431 self .tell ("Testing GPU core '%s' (Device '%s')... " % (core .name , core .devicename ), end = None )
385432 sys .stdout .flush ()
386433 # For GPUs the benchmark runs twice as the core needs to be
@@ -396,8 +443,8 @@ def runbench(core):
396443 self .tell ("FAILED" )
397444 self .tell ("" )
398445
399- if 'AMD Stream' in [ x [0 ] for x in c . listCores ()] :
400- core = c . getCore ( 'AMD Stream' )
446+ if 'AMD Stream' in ( x [0 ] for x in c ) :
447+ core = c [ 'AMD Stream' ]
401448 self .tell ("Testing GPU core '%s' (Device '%s')... " % (core .name , core .devicename ), end = None )
402449 sys .stdout .flush ()
403450 # For GPUs the benchmark runs twice as the core needs to be
@@ -451,7 +498,7 @@ def __init__(self, essid, infile):
451498
452499 results = dict (zip (inp , pmkbuffer ))
453500 pick = random .choice (results .keys ())
454- assert cpyrit .CPyrit (). getCore ( 'Standard CPU' ) .solve (essid , pick ) == results [pick ]
501+ assert cpyrit .CPyrit ()[ 'Standard CPU' ] .solve (essid , pick ) == results [pick ]
455502 self .essid = essid
456503 self .results = results
457504 self .f = f
0 commit comments