python实现端口扫描器
设计今下午终于验收了,╰(°▽°)╯
本文主要实现一个带界面的端口扫描器
一篇特别好的博客https://thief.one/2018/05/17/1/
扫描原理
端口扫描方式主要以下几种:tcp全连接、tcp syn、fin、udp扫描
TCP全连接扫描
利用tcp的三次握手,如果能建立连接,则说明端口开放。扫描过程:
如果该端口是开放的,就能完成TCP三次握手。但是这些样会记录发送者的IP地址,所以很容易被发现。本次使用socket实现这种扫描。
TCP SYN扫描
不建立完整的TCP连接。端口扫描工具生成一个SYN包,如果目标端口开放,则会返回 SYN-ACK 包,扫描端回应一个RST包,然后在握手完成前关闭连接。
关于实现有以下几个设想:
- 开始本来想使用原生套接字实现,但是出现各种原因
- 后来又想借助impacket构造包,再用原生套接字发送,但是也存在问题
- 最后只好使用scapy,确实简单方便不少,最后成功
FIN扫描
发送FIN包,如果响应RST包,则端口是关闭的
UDP扫描
发送udp包,如果没有响应,可能是开放的
遇到的问题
QT desinger 设计ui界面
参考:
http://code.py40.com/2561.html
QProgressBar使用
如果将进度条的最大最小值设为0,则进度条会变为繁忙状态,参考:
https://blog.csdn.net/liang19890820/article/details/52302879
QT界面运行假死
运用线程,主界面一个线程,处理程序一个线程,中间通过信号传递消息。参考:
https://www.jb51.net/article/176310.htm
https://zhuanlan.zhihu.com/p/62988456
https://www.jianshu.com/p/ed47a8959854
https://blog.csdn.net/djstavav/article/details/88942098
QT界面转换为代码
开始配过pyuic,可以直接转换,但是重装了pycharm后没有了,重新配置后出现问题,所以采用如下命令,将设计好的界面转换为代码:
pyuic5 -o my.py my.ui
socket编程
参考:
https://www.liaoxuefeng.com/wiki/1016959663602400/1017788916649408
原始套接字
参考:
https://blog.csdn.net/u011580175/article/details/80761274
该文说原始套接字在win10不可使用,但是我验证可以使用,只是运行程序时需要管理员权限,但是用原始套接字自己构造包最后有错误,还是不能完成程序,可能是构造包时出现问题,主要是如下报错
WinError 10022 提供了一个无效的参数
python-nmap使用
python-nmap是一个可以在Python程序中使用nmap端口扫描器的Python包。参考:
https://www.cnblogs.com/aylin/p/5996229.html
https://blog.csdn.net/qq_36119192/article/details/83717690
impacket使用
https://blog.csdn.net/CubieLee/article/details/105041275
使用impacket最后能发出包,但是不太对,可能是构造包还是有问题
scapy使用
https://zhuanlan.zhihu.com/p/51002301
https://www.jianshu.com/p/025337816217
导入包时出现如下报错,可能是包中命名与其它有错误,将导入它的语句放在了导入其它包语句的前面就解决了
'module' object is not callable
IPy使用
主要用于分割cidr类型的ip段,参考
https://www.cnblogs.com/cherishry/p/5916935.html
扫描实现
最简单的全连接扫描
import sys
from socket import *
host = sys.argv[1]
portStr = sys.argv[2].split('-')
startPort = int(portStr[0])
endPort = int(portStr[1])
openPort = []
ip = gethostbyname(host)
for port in range(startPort, endPort + 1):
# 创建套接字,第一个为协议族名,第二个为套接字。TCP套接字的名字SOCK_STREAM,UDP套接字的名字SOCK_DGRAM
sock = socket(AF_INET, SOCK_STREAM)
sock.settimeout(10)
#s.connect()主动初始化TCP服务器连接。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
#connect_ex()为connect()函数的扩展版本,出错时返回出错码,而不是抛出异常
result = sock.connect_ex((ip, port))
if result == 0:
openPort.append(port)
print("开放的端口有")
for port in openPort:
print(port)
多线程的全连接扫描
使用多线程加快扫描速度
import sys
import _thread as thread
from socket import *
def scan(port):
sock = socket(AF_INET, SOCK_STREAM)
sock.settimeout(10)
result = sock.connect_ex((ip, port))
#print输出时候需要加锁,如果不加锁可能会出现多个输出混合在一起的错误状态,而锁需要在程序启动时创建,从而能让新建的线程共享这个锁:
if result == 0:
lock.acquire()
print("开放的端口", port)
lock.release()
if __name__ == '__main__':
host = sys.argv[1]
portStr = sys.argv[2].split('-')
startPort = int(portStr[0])
endPort = int(portStr[1])
ip = gethostbyname(host)
#创建锁
lock = thread.allocate_lock()
for port in range(startPort, endPort + 1):
#创建线程
thread.start_new_thread(scan, (port,))
带界面的端口扫描器
支持对一个ip或者一个ip段的一个端口或者端口范围进行全连接、syn、nmap扫描。
并且采用多线程提高扫描速度,可以设置扫描间隔进一步提高隐蔽性,最后可以将扫描结果保存为文件。
界面设计
自动转换的代码:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'my.ui'
#
# Created by: PyQt5 UI code generator 5.13.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_widget(object):
def setupUi(self, widget):
widget.setObjectName("widget")
widget.resize(936, 745)
widget.setMinimumSize(QtCore.QSize(936, 745))
widget.setMaximumSize(QtCore.QSize(936, 745))
self.gridLayout = QtWidgets.QGridLayout(widget)
self.gridLayout.setObjectName("gridLayout")
self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
self.label_6 = QtWidgets.QLabel(widget)
self.label_6.setObjectName("label_6")
self.horizontalLayout_4.addWidget(self.label_6)
self.progressBar = QtWidgets.QProgressBar(widget)
self.progressBar.setProperty("value", 0)
self.progressBar.setObjectName("progressBar")
self.horizontalLayout_4.addWidget(self.progressBar)
self.gridLayout.addLayout(self.horizontalLayout_4, 1, 0, 1, 1)
self.gridLayout_2 = QtWidgets.QGridLayout()
self.gridLayout_2.setObjectName("gridLayout_2")
self.scrollArea = QtWidgets.QScrollArea(widget)
self.scrollArea.setMinimumSize(QtCore.QSize(700, 0))
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setObjectName("scrollArea")
self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 698, 687))
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.verticalLayout = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents)
self.verticalLayout.setObjectName("verticalLayout")
self.textBrowser = QtWidgets.QTextBrowser(self.scrollAreaWidgetContents)
self.textBrowser.setObjectName("textBrowser")
self.verticalLayout.addWidget(self.textBrowser)
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
self.gridLayout_2.addWidget(self.scrollArea, 0, 1, 1, 1)
self.gridLayout_3 = QtWidgets.QGridLayout()
self.gridLayout_3.setObjectName("gridLayout_3")
self.gridLayout_4 = QtWidgets.QGridLayout()
self.gridLayout_4.setObjectName("gridLayout_4")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.label = QtWidgets.QLabel(widget)
self.label.setObjectName("label")
self.horizontalLayout.addWidget(self.label)
self.lineEdit_2 = QtWidgets.QLineEdit(widget)
self.lineEdit_2.setObjectName("lineEdit_2")
self.horizontalLayout.addWidget(self.lineEdit_2)
self.gridLayout_4.addLayout(self.horizontalLayout, 0, 0, 1, 1)
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.label_3 = QtWidgets.QLabel(widget)
self.label_3.setMaximumSize(QtCore.QSize(100, 16777215))
self.label_3.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
self.label_3.setObjectName("label_3")
self.horizontalLayout_3.addWidget(self.label_3)
self.comboBox = QtWidgets.QComboBox(widget)
self.comboBox.setMinimumSize(QtCore.QSize(50, 0))
self.comboBox.setMaximumSize(QtCore.QSize(1000, 16777215))
self.comboBox.setObjectName("comboBox")
self.comboBox.addItem("")
self.comboBox.addItem("")
self.comboBox.addItem("")
self.horizontalLayout_3.addWidget(self.comboBox)
self.gridLayout_4.addLayout(self.horizontalLayout_3, 4, 0, 1, 1)
self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
self.horizontalLayout_5.setObjectName("horizontalLayout_5")
self.label_4 = QtWidgets.QLabel(widget)
self.label_4.setMaximumSize(QtCore.QSize(100, 16777215))
self.label_4.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
self.label_4.setObjectName("label_4")
self.horizontalLayout_5.addWidget(self.label_4)
self.lineEdit_4 = QtWidgets.QLineEdit(widget)
self.lineEdit_4.setMaximumSize(QtCore.QSize(50, 16777215))
self.lineEdit_4.setObjectName("lineEdit_4")
self.horizontalLayout_5.addWidget(self.lineEdit_4)
self.label_5 = QtWidgets.QLabel(widget)
self.label_5.setMaximumSize(QtCore.QSize(100, 16777215))
self.label_5.setLayoutDirection(QtCore.Qt.LeftToRight)
self.label_5.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
self.label_5.setObjectName("label_5")
self.horizontalLayout_5.addWidget(self.label_5)
self.lineEdit_3 = QtWidgets.QLineEdit(widget)
self.lineEdit_3.setMaximumSize(QtCore.QSize(50, 16777215))
self.lineEdit_3.setObjectName("lineEdit_3")
self.horizontalLayout_5.addWidget(self.lineEdit_3)
self.gridLayout_4.addLayout(self.horizontalLayout_5, 6, 0, 1, 1)
self.horizontalLayout_8 = QtWidgets.QHBoxLayout()
self.horizontalLayout_8.setObjectName("horizontalLayout_8")
self.gridLayout_4.addLayout(self.horizontalLayout_8, 9, 0, 1, 1)
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.label_2 = QtWidgets.QLabel(widget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth())
self.label_2.setSizePolicy(sizePolicy)
self.label_2.setMinimumSize(QtCore.QSize(10, 10))
self.label_2.setMaximumSize(QtCore.QSize(60, 100))
self.label_2.setLineWidth(-1)
self.label_2.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
self.label_2.setObjectName("label_2")
self.horizontalLayout_2.addWidget(self.label_2)
self.lineEdit = QtWidgets.QLineEdit(widget)
self.lineEdit.setEnabled(True)
self.lineEdit.setMinimumSize(QtCore.QSize(162, 24))
self.lineEdit.setMaximumSize(QtCore.QSize(162, 24))
self.lineEdit.setInputMask("")
self.lineEdit.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)
self.lineEdit.setObjectName("lineEdit")
self.horizontalLayout_2.addWidget(self.lineEdit)
self.gridLayout_4.addLayout(self.horizontalLayout_2, 2, 0, 1, 1)
self.horizontalLayout_9 = QtWidgets.QHBoxLayout()
self.horizontalLayout_9.setObjectName("horizontalLayout_9")
self.pushButton_3 = QtWidgets.QPushButton(widget)
self.pushButton_3.setObjectName("pushButton_3")
self.horizontalLayout_9.addWidget(self.pushButton_3)
self.pushButton = QtWidgets.QPushButton(widget)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout_9.addWidget(self.pushButton)
self.gridLayout_4.addLayout(self.horizontalLayout_9, 8, 0, 1, 1)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.gridLayout_4.addItem(spacerItem, 3, 0, 1, 1)
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.gridLayout_4.addItem(spacerItem1, 1, 0, 1, 1)
spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.gridLayout_4.addItem(spacerItem2, 5, 0, 1, 1)
spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.gridLayout_4.addItem(spacerItem3, 7, 0, 1, 1)
self.gridLayout_3.addLayout(self.gridLayout_4, 0, 0, 1, 1)
self.gridLayout_2.addLayout(self.gridLayout_3, 0, 0, 1, 1)
self.gridLayout.addLayout(self.gridLayout_2, 0, 0, 1, 1)
self.retranslateUi(widget)
QtCore.QMetaObject.connectSlotsByName(widget)
def retranslateUi(self, widget):
_translate = QtCore.QCoreApplication.translate
widget.setWindowTitle(_translate("widget", "端口扫描工具"))
self.label_6.setText(_translate("widget", "进度"))
self.textBrowser.setHtml(_translate("widget",
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'SimSun\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p align=\"center\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'SimSun\';\"><br /></p>\n"
"<p align=\"center\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'SimSun\'; font-size:20pt;\"><br /></p>\n"
"<p align=\"center\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'SimSun\'; font-size:20pt;\"><br /></p>\n"
"<p align=\"center\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'SimSun\'; font-size:20pt;\"><br /></p>\n"
"<p align=\"center\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'SimSun\'; font-size:20pt;\"><br /></p>\n"
"<p align=\"center\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'SimSun\'; font-size:20pt;\"><br /></p>\n"
"<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'SimSun\'; font-size:20pt;\">端口扫描工具</span></p>\n"
"<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'SimSun\'; font-size:20pt;\"> by 启林</span></p>\n"
"<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'SimSun\'; font-size:14pt;\">支持全连接扫描和syn扫描,集成nmap工具</span></p>\n"
"<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'SimSun\'; font-size:14pt;\">扫描目标可以为单个ip或者host/掩码的ip网段的形式</span></p>\n"
"<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'SimSun\'; font-size:14pt;\">端口可以为单个端口或者以“-”连接的端口范围</span></p>\n"
"<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'SimSun\'; font-size:14pt;\">延迟选项为每次扫描新建连接的间隔时间</span></p>\n"
"<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'SimSun\'; font-size:14pt;\">timeout只针对syn扫描,为其等待响应的等待时间</span></p>\n"
"<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'SimSun\'; font-size:14pt;\">扫描结果可保存为result.txt文档</span></p></body></html>"))
self.label.setText(_translate("widget", "目标"))
self.label_3.setText(_translate("widget", "扫描方式"))
self.comboBox.setItemText(0, _translate("widget", "full"))
self.comboBox.setItemText(1, _translate("widget", "syn"))
self.comboBox.setItemText(2, _translate("widget", "nmap"))
self.label_4.setText(_translate("widget", "延迟"))
self.label_5.setText(_translate("widget", "timeout"))
self.label_2.setText(_translate("widget", "端口"))
self.lineEdit.setText(_translate("widget", "1-65535"))
self.pushButton_3.setText(_translate("widget", "保存"))
self.pushButton.setText(_translate("widget", "开始"))
处理程序
from my import Ui_widget
from PyQt5 import QtWidgets
from scapy.all import *
from socket import *
import nmap
import threading
import sys
from PyQt5.QtCore import *
import IPy
import time
class RunThread(QThread):
# 用于工作线程与界面线程传递信息
_signal = pyqtSignal(str, int)
_signal2 = pyqtSignal(str)
def __init__(self, host, startPort, endPort, mode, delay, timeout):
super(RunThread, self).__init__()
self.host = host
self.startPort = startPort
self.endPort = endPort
self.mode = mode
self.delay = delay
self.timeout = timeout
def run(self):
# 全连接扫描
if (self.mode == 'full'):
# 将ip段分为单个ip的列表,如果是单个ip则为单个ip的列表
ipList = IPy.IP(self.host)
# 遍历每个ip
for ip in ipList:
# 遍历每个端口
for port in range(self.startPort, self.endPort + 1):
# 对于延迟设置判断,如果没有设置,不管
if self.delay != '':
time.sleep(eval(self.delay))
# 新建线程
t = threading.Thread(target=self.fullScan, args=(port, str(ip)))
t.start()
# nmap扫描
elif (self.mode == 'nmap'):
self.nmap(self.host, self.startPort, self.endPort)
# syn扫描
elif (self.mode == 'syn'):
ipList = IPy.IP(self.host)
for ip in ipList:
for port in range(self.startPort, self.endPort + 1):
if self.delay != '':
time.sleep(eval(self.delay))
t = threading.Thread(target=self.synScan, args=(port, str(ip)))
t.start()
else:
return 0
# 全连接扫描函数
def fullScan(self, port, ip):
# 建立套接字
sock = socket(AF_INET, SOCK_STREAM)
sock.settimeout(10)
# 建立连接
result = sock.connect_ex((ip, port))
# 传递信号
if result == 0:
self._signal.emit(ip + ' ' + str(port), 0)
else:
self._signal.emit('unknow', 0)
# syn扫描
def synScan(self, dPort, desIP):
# 设置原地址和端口
srcIP = '192.168.1.13'
sPort = 4444
# 使用scapy构造数据包
ipLayer = IP(src=srcIP, dst=desIP)
# 设置为syn包
tcpLayer = TCP(sport=sPort, dport=dPort, flags="S")
packet = ipLayer / tcpLayer
# 对于timeout设置判断,如果没有设置,默认为1
if self.timeout != '':
time = eval(self.timeout)
else:
time = 1
# 使用sr发送数据包,通过ans得到响应
ans, unans = sr(packet, timeout=time)
if ans:
# 判断响应包是否为syn、ack包
if (ans[0][1].getlayer(TCP).flags == 'SA'):
self._signal.emit(desIP + ' ' + str(dPort), 0)
# 之后构造rset包,中断连接
ipLayer = IP(src=srcIP, dst=desIP)
tcpLayer = TCP(sport=sPort, dport=dPort, flags="R")
packet = ipLayer / tcpLayer
send(packet)
else:
self._signal.emit('unknow', 0)
else:
self._signal.emit('unknow', 0)
return 0
# 使用nmap扫描
def nmap(self, host, startPort, endPort):
port = str(startPort) + '-' + str(endPort)
nm = nmap.PortScanner()
self._signal.emit('s', 1)
# 扫描
nm.scan(host, port)
# 显示扫描的具体命令
self._signal.emit(nm.command_line(), 1)
# 分解显示扫描结果
for i in nm.all_hosts():
self._signal2.emit(i)
for protocal in nm[i].all_protocols():
for p in nm[i][protocal].keys():
result = str(p) + " " + nm[i][protocal][p]['state'] + " " + nm[i][protocal][p]['product'] + " " + \
nm[i][protocal][p]['version']
self._signal.emit(result, 1)
self._signal.emit('e', 1)
class myWin(QtWidgets.QWidget, Ui_widget):
def __init__(self):
super(myWin, self).__init__()
self.setupUi(self)
# 两个函数的点击函数
self.pushButton.clicked.connect(self.button)
self.pushButton_3.clicked.connect(self.button3)
# 取得界面输入的值
def get(self):
host = self.lineEdit_2.text()
port = self.lineEdit.text()
mode = self.comboBox.currentText()
delay = self.lineEdit_4.text()
timeout = self.lineEdit_3.text()
return host, port, mode, delay, timeout
# 开始按钮点击函数
def button(self):
host, port, mode, delay, timeout = self.get()
port = port.split('-')
startPort = int(port[0])
# 判断是对单个端口,还是端口范围扫描
if (len(port) == 2):
endPort = int(port[1])
else:
endPort = int(port[0])
# 设置界面进度条的最大值
max = (endPort - startPort + 1) * len(IPy.IP(host))
self.textBrowser.clear()
self.progressBar.setMaximum(max)
self.progressBar.setValue(0)
self.thread = RunThread(host, startPort, endPort, mode, delay, timeout)
self.thread._signal.connect(self.call_backlog)
self.thread._signal2.connect(self.call_backlog2)
self.thread.start()
# 保存点击按钮
def button3(self):
result = str(self.textBrowser.toPlainText())
with open(r'C:\Users\Desktop\result.txt', 'w') as f:
f.write(result)
# 信号处理函数2
def call_backlog2(self, msg):
self.textBrowser.append(str(msg))
# 信号处理函数1
def call_backlog(self, msg, flag):
# 通过flag值判断,0为syn与full,1为nmap
if (flag == 0):
if (msg == 'unknow'):
# 进度条更新
self.progressBar.setValue(self.progressBar.value() + 1)
else:
self.textBrowser.append(str(msg))
self.progressBar.setValue(self.progressBar.value() + 1)
elif (flag == 1):
# 开始扫描,进度条设置为忙状态
if (msg == 's'):
self.progressBar.setMaximum(0)
self.progressBar.setMinimum(0)
# 扫描结束,设置为100%
elif (msg == 'e'):
self.progressBar.setMaximum(1)
self.progressBar.setValue(1)
else:
self.textBrowser.append(str(msg))
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
Widget = myWin()
Widget.show()
sys.exit(app.exec_())
运行结果
对192.168.1.0/24网段的1-100端口全连接扫描
通过抓取流量可以进一步验证过程
对192.168.1.58网段的1-100端口syn扫描
抓取的流量
对21端口的扫描过程
对192.168.1.58网段的1-100端口调用nmap扫描