11import os
2+ import re
23import logging
34import requests
45from datetime import datetime
@@ -27,26 +28,25 @@ def __init__(self):
2728
2829 def _upload_to_wpasec (self , path , timeout = 30 ):
2930 """
30- Uploads the file to https://wpa-sec.stanev.org, or another endpoint.
31+ Uploads the file to wpasec
3132 """
3233 with open (path , 'rb' ) as file_to_upload :
3334 cookie = {'key' : self .options ['api_key' ]}
3435 payload = {'file' : file_to_upload }
3536
36- try :
37- result = requests .post (self .options ['api_url' ],
38- cookies = cookie ,
39- files = payload ,
40- timeout = timeout )
41- if ' already submitted' in result .text :
42- logging .debug ("%s was already submitted." , path )
43- except requests .exceptions .RequestException as req_e :
44- raise req_e
37+ logging .info ("WPA_SEC: Uploading %s..." , path )
4538
39+ result = requests .post (self .options ['api_url' ],
40+ cookies = cookie ,
41+ files = payload ,
42+ timeout = timeout )
43+
44+ result .raise_for_status ()
45+ logging .info ("WPA_SEC: Uploaded %s. Response was: %s." , path , result .text .partition ('\n ' )[0 ])
4646
4747 def _download_from_wpasec (self , output , timeout = 30 ):
4848 """
49- Downloads the results from wpasec and safes them to output
49+ Downloads the results from wpasec and saves them to output
5050
5151 Output-Format: bssid, station_mac, ssid, password
5252 """
@@ -56,33 +56,56 @@ def _download_from_wpasec(self, output, timeout=30):
5656 api_url = f"{ api_url } ?api&dl=1"
5757
5858 cookie = {'key' : self .options ['api_key' ]}
59- try :
60- result = requests .get (api_url , cookies = cookie , timeout = timeout )
61- with open (output , 'wb' ) as output_file :
62- output_file .write (result .content )
63- except requests .exceptions .RequestException as req_e :
64- raise req_e
65- except OSError as os_e :
66- raise os_e
6759
60+ logging .info ("WPA_SEC: Downloading cracked passwords..." )
61+
62+ result = requests .get (api_url , cookies = cookie , timeout = timeout )
63+ result .raise_for_status ()
64+
65+ with open (output , 'wb' ) as output_file :
66+ output_file .write (result .content )
67+
68+ logging .info ("WPA_SEC: Downloaded cracked passwords." )
69+
70+ def _write_cracked_single_files (self , cracked_file_path , handshake_dir ):
71+ """
72+ Splits download results from wpasec into individual .pcap..cracked files in handshake_dir
73+
74+ Each .pcap.cracked file will contain the cracked handshake password
75+ """
76+ logging .info ("WPA_SEC: Writing cracked single files..." )
77+
78+ with open (cracked_file_path , 'r' ) as cracked_file :
79+ for line in cracked_file :
80+ try :
81+ bssid ,station_mac ,ssid ,password = line .split (":" )
82+ if password :
83+ filename = re .sub (r'[^a-zA-Z0-9]' , '' , ssid ) + '_' + bssid
84+ if os .path .exists ( os .path .join (handshake_dir , filename + '.pcap' ) ) and not os .path .exists ( os .path .join (handshake_dir , filename + '.pcap.cracked' ) ):
85+ with open (os .path .join (handshake_dir , filename + '.pcap.cracked' ), 'w' ) as f :
86+ f .write (password )
87+ except Exception :
88+ logging .exception ("WPA_SEC: Exception writing cracked single file." )
89+
90+ logging .info ("WPA_SEC: Wrote cracked single files." )
6891
6992 def on_loaded (self ):
7093 """
7194 Gets called when the plugin gets loaded
7295 """
7396 if 'api_key' not in self .options or ('api_key' in self .options and not self .options ['api_key' ]):
74- logging .error ("WPA_SEC: API-KEY isn't set. Can't upload to wpa-sec.stanev.org " )
97+ logging .error ("WPA_SEC: API-KEY isn't set. Can't upload. " )
7598 return
7699
77100 if 'api_url' not in self .options or ('api_url' in self .options and not self .options ['api_url' ]):
78- logging .error ("WPA_SEC: API-URL isn't set. Can't upload, no endpoint configured ." )
101+ logging .error ("WPA_SEC: API-URL isn't set. Can't upload." )
79102 return
80103
81104 if 'whitelist' not in self .options :
82105 self .options ['whitelist' ] = list ()
83106
84107 self .ready = True
85- logging .info ("WPA_SEC: plugin loaded" )
108+ logging .info ("WPA_SEC: plugin loaded. " )
86109
87110 def on_webhook (self , path , request ):
88111 from flask import make_response , redirect
@@ -109,35 +132,31 @@ def on_internet_available(self, agent):
109132 handshake_new = set (handshake_paths ) - set (reported ) - set (self .skip )
110133
111134 if handshake_new :
112- logging .info ("WPA_SEC: Internet connectivity detected. Uploading new handshakes to wpa-sec.stanev.org " )
135+ logging .info ("WPA_SEC: Internet connectivity detected. Uploading new handshakes... " )
113136 for idx , handshake in enumerate (handshake_new ):
114- display .on_uploading (f"wpa-sec.stanev.org ({ idx + 1 } /{ len (handshake_new )} )" )
137+ display .on_uploading (f"WPA-SEC ({ idx + 1 } /{ len (handshake_new )} )" )
115138
116139 try :
117140 self ._upload_to_wpasec (handshake )
118141 reported .append (handshake )
119142 self .report .update (data = {'reported' : reported })
120- logging .debug ("WPA_SEC: Successfully uploaded %s" , handshake )
121- except requests .exceptions .RequestException as req_e :
122- self .skip .append (handshake )
123- logging .debug ("WPA_SEC: %s" , req_e )
124- continue
125- except OSError as os_e :
126- logging .debug ("WPA_SEC: %s" , os_e )
127- continue
143+ except Exception :
144+ logging .exception ("WPA_SEC: Exception uploading %s." , handshake )
128145
129146 display .on_normal ()
130147
131148 if 'download_results' in self .options and self .options ['download_results' ]:
132- cracked_file = os .path .join (handshake_dir , 'wpa-sec.cracked.potfile' )
133- if os .path .exists (cracked_file ):
134- last_check = datetime .fromtimestamp (os .path .getmtime (cracked_file ))
135- if last_check is not None and ((datetime .now () - last_check ).seconds / (60 * 60 )) < 1 :
149+ cracked_file_path = os .path .join (handshake_dir , 'wpa-sec.cracked.potfile' )
150+
151+ if os .path .exists (cracked_file_path ):
152+ last_check = datetime .fromtimestamp (os .path .getmtime (cracked_file_path ))
153+ download_interval = int (self .options .get ('download_interval' , 3600 ))
154+ if last_check is not None and ((datetime .now () - last_check ).seconds / download_interval ) < 1 :
136155 return
156+
137157 try :
138- self ._download_from_wpasec (os .path .join (handshake_dir , 'wpa-sec.cracked.potfile' ))
139- logging .info ("WPA_SEC: Downloaded cracked passwords." )
140- except requests .exceptions .RequestException as req_e :
141- logging .debug ("WPA_SEC: %s" , req_e )
142- except OSError as os_e :
143- logging .debug ("WPA_SEC: %s" , os_e )
158+ self ._download_from_wpasec (cracked_file_path )
159+ if 'single_files' in self .options and self .options ['single_files' ]:
160+ self ._write_cracked_single_files (cracked_file_path , handshake_dir )
161+ except Exception :
162+ logging .exception ("WPA_SEC: Exception downloading results." )
0 commit comments