-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscanner.py
More file actions
177 lines (144 loc) · 6.44 KB
/
scanner.py
File metadata and controls
177 lines (144 loc) · 6.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
import gradio as gr
import nmap
import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt
import os
import platform
import xml.dom.minidom # Biblioteca para formatar XML
# Verifica se o script está rodando como root (Linux/macOS)
executando_com_root = False
if platform.system() != "Windows":
executando_com_root = os.geteuid() == 0 if hasattr(os, "geteuid") else False
# Variável global para controle do scan
escaneamento_em_andamento = False
def formatar_saida_nmap(saida_bruta):
"""Formata a saída XML do Nmap para exibição legível."""#-
"""#+
Formata a saída XML do Nmap para exibição legível.#+
#+
Parameters:#+
saida_bruta (str or bytes): A saída bruta do Nmap em formato XML. Pode ser uma string ou bytes.#+
#+
Returns:#+
str: A saída formatada do Nmap. Retorna uma string com a saída formatada se bem-sucedida.#+
Retorna uma string de aviso de erro se ocorrer um problema durante a formatação.#+
"""#+
try:
saida_bruta = saida_bruta.decode("utf-8") if isinstance(saida_bruta, bytes) else saida_bruta
saida_xml = xml.dom.minidom.parseString(saida_bruta)
saida_formatada = saida_xml.toprettyxml(indent=" ")
return saida_formatada
except Exception:
return "Erro ao formatar saída do Nmap."
def escanear_rede(alvo, portas, tipo_escaneamento):
"""Executa o scan do Nmap e retorna os resultados formatados."""
global escaneamento_em_andamento
escaneamento_em_andamento = True
if not executando_com_root and tipo_escaneamento in ["-sS", "-A"]:
return "Erro: Este tipo de scan requer privilégios de root. Execute com `sudo`.", None, None, None
try:
scanner = nmap.PortScanner()
except AttributeError:
return "Erro: Biblioteca `python-nmap` não instalada corretamente!", None, None, None
try:
# Se o usuário não informar portas, não passamos o argumento
if portas.strip():
scanner.scan(alvo, portas, tipo_escaneamento) # Usa as portas fornecidas
else:
scanner.scan(alvo, arguments=tipo_escaneamento) # Usa o scan padrão do Nmap
if not scanner.all_hosts():
return "Nenhum host encontrado. Verifique o IP e as configurações.", None, None, None
resultados = []
mapa_rede = nx.Graph()
for host in scanner.all_hosts():
if not escaneamento_em_andamento:
return "Escaneamento interrompido!", None, None, None
sistema_operacional = scanner[host].get('osclass', [{"osfamily": "Desconhecido"}])[0].get('osfamily', "Desconhecido")
for protocolo in scanner[host].all_protocols():
for porta in scanner[host][protocolo]:
estado = scanner[host][protocolo][porta]["state"]
servico = scanner[host][protocolo][porta].get("name", "Desconhecido")
resultados.append({
"Host": host,
"Sistema Operacional": sistema_operacional,
"Protocolo": protocolo,
"Porta": porta,
"Serviço": servico,
"Estado": estado
})
mapa_rede.add_node(host)
mapa_rede.add_edge(host, f"Porta {porta} ({servico})")
if not resultados:
return "Nenhum resultado encontrado. O scan pode ter sido bloqueado pelo firewall.", None, None, None
df_resultados = pd.DataFrame(resultados)
# Criar e exibir o mapa de rede
caminho_imagem = "mapa_rede.png"
plt.figure(figsize=(10, 6))
nx.draw(mapa_rede, with_labels=True, node_color='lightblue', edge_color='gray')
plt.title("Mapa de Rede")
plt.savefig(caminho_imagem)
plt.close()
# Obtém a saída completa do comando Nmap e formata
saida_bruta = scanner.get_nmap_last_output()
saida_formatada = formatar_saida_nmap(saida_bruta)
return df_resultados, caminho_imagem, "✅ Escaneamento concluído!", saida_formatada
except Exception as e:
return f"Erro ao escanear: {str(e)}", None, None, None
def parar_escaneamento():
"""Interrompe o escaneamento"""
global escaneamento_em_andamento
escaneamento_em_andamento = False
return "Escaneamento interrompido pelo usuário!"
#frontend
estilo_css = """
footer {display: none !important;}
/* Rodapé fixo personalizado */
.custom-footer {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
background-color: #222;
color: white;
text-align: center;
padding: 10px 0;
font-size: 14px;
font-family: Arial, sans-serif;
}
/* Estiliza o link do GitHub */
.custom-footer a {
color: #007bff;
text-decoration: none;
font-weight: bold;
}
.custom-footer a:hover {
text-decoration: underline;
}
"""
# HTML do footer personalizado
custom_footer = """
<div class="custom-footer">
Desenvolvido por Anderson Bezerra Silva |
<a href="https://github.com/oanderoficial" target="_blank">GitHub</a>
</div>
"""
# Criar interface Gradio
with gr.Blocks(css=estilo_css) as interface:
gr.Markdown("## 🚀 **NetMapper - Scanner Nmap Gráfico**")
gr.Markdown("🔍 **Varredura Nmap gráfica.** Detecta sistemas operacionais, portas e serviços ativos na rede.")
with gr.Row():
alvo = gr.Textbox(label="Endereço IP ou Faixa de IPs", placeholder="Ex: 192.168.1.1 ou 192.168.1.0/24")
portas = gr.Textbox(label="Portas (opcional)", placeholder="Ex: 22,80,443 (ou deixe em branco para scan padrão)")
tipo_escaneamento = gr.Radio(["-sS", "-sT", "-sU", "-sV", "-A", "-sC"], label="Tipo de Escaneamento", value="-sS")
botao_escanear = gr.Button("Iniciar Escaneamento")
botao_parar = gr.Button("Parar Escaneamento")
tabela_resultados = gr.Dataframe()
imagem_mapa = gr.Image(type="filepath", label="Mapa da Rede")
mensagem_status = gr.Textbox(label="Status", interactive=False)
saida_nmap = gr.Textbox(label="Saída Completa do Nmap", interactive=False, lines=20)
botao_escanear.click(fn=escanear_rede, inputs=[alvo, portas, tipo_escaneamento], outputs=[tabela_resultados, imagem_mapa, mensagem_status, saida_nmap])
botao_parar.click(fn=parar_escaneamento, inputs=[], outputs=[mensagem_status])
# Adiciona o Footer na Interface
gr.Markdown(custom_footer)
interface.launch(share=False, show_api=False, server_name="0.0.0.0", server_port=7861)