Este blog é um complemento do nosso canal no YouTube. Clique em @CanalQb para seguir e acompanhar nossos vídeos!

Sugestões de pesquisas

Como Criar um Port Scanner em Python com Interface Gráfica PyQt

#Python; #Segurança; #Redes
@CanalQb

Port Scanner em Python com PyQt

Canal de Programação
@CanalQb

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:

@CanalQb
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:

@CanalQb
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.

Postar um comentário

Comente só assim vamos crescer juntos!
CanalQb mais próximo Quer falar com o CanalQb?
Em que posso te ajudar?
Fale comigo