3131class AttackPassivePMKID :
3232 """
3333 Passive PMKID capture attack that monitors all networks simultaneously.
34-
35- Uses hcxdumptool with --rds=3 flag for passive capture without deauth.
34+
35+ Uses hcxdumptool for passive capture without deauth.
3636 Periodically extracts PMKID hashes from the capture file and saves them
3737 to individual .22000 files for offline cracking.
3838 """
39-
39+
4040 def __init__ (self , tui_controller = None ):
4141 """
4242 Initialize passive PMKID attack.
43-
43+
4444 Sets up capture file path, statistics tracking, and state variables.
4545 Initializes captured_pmkids dictionary to track captured hashes by BSSID.
46-
46+
4747 Args:
4848 tui_controller: Optional TUIController instance for TUI mode
4949 """
5050 # Generate capture file path
5151 self .pcapng_file = Configuration .temp ('passive_pmkid.pcapng' )
52-
52+
5353 # Dictionary to track captured PMKIDs by BSSID
5454 # Format: {bssid: {'essid': str, 'hash': str, 'file': str, 'captured_at': float}}
5555 self .captured_pmkids = {}
56-
56+
5757 # Monitoring thread reference
5858 self .monitor_thread = None
59-
59+
6060 # HcxDumpToolPassive process reference
6161 self .dumptool = None
62-
62+
6363 # Statistics dictionary
6464 self .statistics = {
6565 'networks_detected' : 0 , # Total unique BSSIDs seen
@@ -69,7 +69,7 @@ def __init__(self, tui_controller=None):
6969 'capture_size_mb' : 0.0 , # Current capture file size in MB
7070 'duration_seconds' : 0 # Total capture duration
7171 }
72-
72+
7373 # TUI support
7474 self .tui_controller = tui_controller
7575 self .tui_view = None
@@ -78,45 +78,45 @@ def __init__(self, tui_controller=None):
7878 self .tui_view .set_extraction_interval (Configuration .pmkid_passive_interval )
7979 self .tui_view .set_duration_limit (Configuration .pmkid_passive_duration )
8080 self .tui_view .set_capture_file_path (self .pcapng_file )
81-
81+
8282 def validate_dependencies (self ):
8383 """
8484 Validate required tools are installed.
85-
85+
8686 Checks for hcxdumptool and hcxpcapngtool availability.
8787 Displays error message with installation instructions if tools are missing.
88-
88+
8989 Returns:
9090 bool: True if dependencies are satisfied, False otherwise
9191 """
9292 missing = []
93-
93+
9494 # Check for hcxdumptool
9595 if not Process .exists ('hcxdumptool' ):
9696 missing .append ('hcxdumptool' )
97-
97+
9898 # Check for hcxpcapngtool
9999 if not HcxPcapngTool .exists ():
100100 missing .append ('hcxpcapngtool' )
101-
101+
102102 if missing :
103103 Color .pl ('{!} {R}Missing required tools:{W} {O}%s{W}' % ', ' .join (missing ))
104104 Color .pl ('{!} {O}Install with:{W} {C}apt install hcxdumptool hcxtools{W}' )
105105 Color .pl ('{!} {O}Or visit:{W}' )
106106 Color .pl ('{!} {C}https://github.com/ZerBea/hcxdumptool{W}' )
107107 Color .pl ('{!} {C}https://github.com/ZerBea/hcxtools{W}' )
108108 return False
109-
109+
110110 return True
111-
111+
112112 def start_passive_capture (self ):
113113 """
114114 Start hcxdumptool in passive mode.
115-
115+
116116 Uses HcxDumpToolPassive context manager to ensure proper cleanup.
117117 Stores process reference for monitoring.
118118 Displays startup message with capture details.
119-
119+
120120 Returns:
121121 HcxDumpToolPassive: The passive capture instance
122122 """
@@ -126,7 +126,7 @@ def start_passive_capture(self):
126126 self .tui_view .add_log (f'Interface: { Configuration .interface } ' )
127127 self .tui_view .add_log (f'Capture file: { self .pcapng_file } ' )
128128 self .tui_view .add_log (f'Extraction interval: { Configuration .pmkid_passive_interval } seconds' )
129-
129+
130130 if Configuration .pmkid_passive_duration > 0 :
131131 self .tui_view .add_log (f'Duration: { Configuration .pmkid_passive_duration } seconds' )
132132 else :
@@ -137,25 +137,25 @@ def start_passive_capture(self):
137137 Color .pl ('{+} Interface: {G}%s{W}' % Configuration .interface )
138138 Color .pl ('{+} Capture file: {C}%s{W}' % self .pcapng_file )
139139 Color .pl ('{+} Extraction interval: {G}%d seconds{W}' % Configuration .pmkid_passive_interval )
140-
140+
141141 if Configuration .pmkid_passive_duration > 0 :
142142 Color .pl ('{+} Duration: {G}%d seconds{W}' % Configuration .pmkid_passive_duration )
143143 else :
144144 Color .pl ('{+} Duration: {G}infinite{W} (press Ctrl+C to stop)' )
145-
145+
146146 Color .pl ('' )
147-
147+
148148 # Create and return HcxDumpToolPassive instance
149149 # Will be used with context manager in run()
150150 return HcxDumpToolPassive (
151151 interface = Configuration .interface ,
152152 output_file = self .pcapng_file
153153 )
154-
154+
155155 def start_monitoring_thread (self ):
156156 """
157157 Start background thread for monitoring and extraction.
158-
158+
159159 Creates PassivePMKIDMonitor thread with self reference and extraction interval.
160160 Stores thread reference for cleanup.
161161 """
@@ -164,16 +164,16 @@ def start_monitoring_thread(self):
164164 interval = Configuration .pmkid_passive_interval
165165 )
166166 self .monitor_thread .start ()
167-
167+
168168 if self .tui_view :
169169 self .tui_view .add_log ('Monitoring thread started' )
170170 else :
171171 Color .pl ('{+} {G}Monitoring thread started{W}' )
172-
172+
173173 def extract_and_save_pmkids (self ):
174174 """
175175 Extract PMKID hashes from capture file and save them.
176-
176+
177177 Calls HcxPcapngTool.extract_all_pmkids() to get all PMKID hashes.
178178 Iterates through extracted hashes and saves new ones.
179179 Updates captured_pmkids dictionary with new entries.
@@ -182,17 +182,17 @@ def extract_and_save_pmkids(self):
182182 # Check if capture file exists and has data
183183 if not os .path .exists (self .pcapng_file ):
184184 return
185-
185+
186186 if os .path .getsize (self .pcapng_file ) == 0 :
187187 return
188-
188+
189189 try :
190190 # Extract all PMKIDs from capture file
191191 pmkids = HcxPcapngTool .extract_all_pmkids (self .pcapng_file )
192-
192+
193193 if not pmkids :
194194 return
195-
195+
196196 # Track new PMKIDs found in this extraction
197197 new_pmkids = 0
198198
0 commit comments