![]() |
Port Scanner em Python com PyQt |
|
Canal de Programação |
Introdução
Um port scanner é uma ferramenta essencial para administradores de rede e profissionais de segurança. Neste tutorial, vamos criar um scanner de portas completo com interface gráfica usando Python e PyQt5.
Instalação Necessária
Antes de começar, instale o PyQt5:
pip install pyqt5
Versão Básica do Port Scanner
Este é um scanner TCP simples que verifica portas individuais:
import sys
import threading
import socket
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QLineEdit
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Port Scanner")
self.setGeometry(100, 100, 500, 300)
# Interface básica
self.label_host = QLabel("Host:", self)
self.label_host.move(50, 50)
self.textbox_host = QLineEdit(self)
self.textbox_host.move(150, 50)
self.textbox_host.resize(200, 30)
self.label_portas = QLabel("Portas (separadas por vírgula):", self)
self.label_portas.move(50, 100)
self.textbox_portas = QLineEdit(self)
self.textbox_portas.move(150, 100)
self.textbox_portas.resize(200, 30)
self.label_resultado = QLabel("", self)
self.label_resultado.move(50, 200)
self.button = QPushButton("Scan", self)
self.button.move(150, 150)
self.button.clicked.connect(self.scan)
def scan(self):
host = self.textbox_host.text()
portas = self.textbox_portas.text().split(",")
self.label_resultado.setText("Scanning...")
for porta in portas:
t = threading.Thread(target=self.scan_porta, args=(host, int(porta)))
t.start()
def scan_porta(self, host, porta):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
resultado = sock.connect_ex((host, porta))
if resultado == 0:
self.label_resultado.setText(f"Porta {porta} aberta")
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
Versão Avançada com Suporte TCP/UDP
Esta versão inclui suporte para ambos os protocolos:
import socket
import threading
from PyQt5 import QtWidgets
class Portscan(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
self.setWindowTitle('Port Scanner Avançado')
self.setGeometry(100, 100, 400, 300)
# Elementos da interface
self.host_input = QtWidgets.QLineEdit(self)
self.start_port_input = QtWidgets.QLineEdit(self)
self.end_port_input = QtWidgets.QLineEdit(self)
self.results_list = QtWidgets.QListWidget(self)
# Botões
self.tcp_scan_button = QtWidgets.QPushButton('Scan TCP', self)
self.tcp_scan_button.clicked.connect(self.scan_tcp_ports)
self.udp_scan_button = QtWidgets.QPushButton('Scan UDP', self)
self.udp_scan_button.clicked.connect(self.scan_udp_ports)
# Layout
layout = QtWidgets.QVBoxLayout()
layout.addWidget(QtWidgets.QLabel('Host:'))
layout.addWidget(self.host_input)
layout.addWidget(QtWidgets.QLabel('Porta Inicial:'))
layout.addWidget(self.start_port_input)
layout.addWidget(QtWidgets.QLabel('Porta Final:'))
layout.addWidget(self.end_port_input)
button_layout = QtWidgets.QHBoxLayout()
button_layout.addWidget(self.tcp_scan_button)
button_layout.addWidget(self.udp_scan_button)
layout.addLayout(button_layout)
layout.addWidget(QtWidgets.QLabel('Resultados:'))
layout.addWidget(self.results_list)
self.setLayout(layout)
def scan_tcp_ports(self):
self.scan_ports('TCP')
def scan_udp_ports(self):
self.scan_ports('UDP')
def scan_ports(self, protocol):
host = self.host_input.text()
start_port = int(self.start_port_input.text())
end_port = int(self.end_port_input.text())
self.results_list.clear()
for port in range(start_port, end_port + 1):
t = threading.Thread(target=self.scan_port, args=(host, port, protocol))
t.start()
def scan_port(self, host, port, protocol):
try:
if protocol == 'TCP':
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.settimeout(0.5)
if s.connect_ex((host, port)) == 0:
self.results_list.addItem(f'Porta {port} aberta (TCP)')
else:
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.settimeout(0.5)
s.sendto(b'', (host, port))
if s.recvfrom(1024):
self.results_list.addItem(f'Porta {port} aberta (UDP)')
except:
pass
app = QtWidgets.QApplication([])
portscan = Portscan()
portscan.show()
app.exec_()
Versão com ListBox e Design Aprimorado
Para uma experiência mais profissional:
import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QLabel, QGridLayout,
QWidget, QGroupBox, QListWidget, QLineEdit,
QVBoxLayout, QHBoxLayout, QPushButton)
from PyQt5.QtGui import QFont
import socket
import threading
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Port Scanner Profissional")
self.setGeometry(100, 100, 600, 400)
# Configuração da interface
self.create_input_group()
self.create_results_group()
# Layout principal
main_widget = QWidget()
main_layout = QVBoxLayout()
main_layout.addWidget(self.input_groupbox)
main_layout.addWidget(self.results_groupbox)
main_widget.setLayout(main_layout)
self.setCentralWidget(main_widget)
def create_input_group(self):
self.input_groupbox = QGroupBox("Configurações do Scan")
layout = QGridLayout()
self.ip_edit = QLineEdit()
self.ip_edit.setPlaceholderText("Ex: 192.168.1.1")
self.start_port_edit = QLineEdit()
self.start_port_edit.setPlaceholderText("Porta inicial")
self.end_port_edit = QLineEdit()
self.end_port_edit.setPlaceholderText("Porta final")
scan_button = QPushButton("Iniciar Scan")
scan_button.clicked.connect(self.start_scan)
layout.addWidget(QLabel("Endereço IP:"), 0, 0)
layout.addWidget(self.ip_edit, 0, 1)
layout.addWidget(QLabel("Porta Inicial:"), 1, 0)
layout.addWidget(self.start_port_edit, 1, 1)
layout.addWidget(QLabel("Porta Final:"), 2, 0)
layout.addWidget(self.end_port_edit, 2, 1)
layout.addWidget(scan_button, 3, 0, 1, 2)
self.input_groupbox.setLayout(layout)
def create_results_group(self):
self.results_groupbox = QGroupBox("Resultados")
layout = QVBoxLayout()
self.results_list = QListWidget()
layout.addWidget(self.results_list)
self.results_groupbox.setLayout(layout)
def start_scan(self):
host = self.ip_edit.text()
start_port = int(self.start_port_edit.text())
end_port = int(self.end_port_edit.text())
self.results_list.clear()
for port in range(start_port, end_port + 1):
t = threading.Thread(target=self.check_port, args=(host, port))
t.start()
def check_port(self, host, port):
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.settimeout(1)
if s.connect_ex((host, port)) == 0:
self.results_list.addItem(f"Porta {port} - aberta")
else:
self.results_list.addItem(f"Porta {port} - fechada")
except Exception as e:
self.results_list.addItem(f"Erro na porta {port}: {str(e)}")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
Considerações de Segurança
Ao usar um port scanner, lembre-se:
- Nunca escane redes sem permissão explícita
- O uso indevido pode violar leis de privacidade
- Configure tempos de timeout adequados para não sobrecarregar sistemas
Para mais informações sobre sockets em Python, consulte a documentação oficial.