版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/coloson/article/details/89037090
Python笔记(三)–socket实现端口扫描(多线程版)
上一次写了有一个单线程的端口扫描器,但是用for循环一个一个去连接测试,效率实在是太慢了,所以我特地去了解了一下多线程这部分的知识,其中要用到threading。
单线程扫描器: https://blog.csdn.net/coloson/article/details/88959755
多线程的基本用法
通过这篇文章,我对多线程的有了进一步的了解,而在这里我是用threading模块来创建线程(https://blog.csdn.net/fw19940314/article/details/79737214)
import threading # 导入threading包
import datetime
thread = []#线程列表
def Print(i,time):
print(str(i)+'<====>'+time)
print('*'*12+'多线程开始'+'*'*12)
Start_Time = datetime.datetime.now()#获取开始时间
for i in range(1,65536):
time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')#获取当前系统时间,Y-m-d H-M-S
t = threading.Thread(target=Print,args=(i,time))#创建一个线程,target为线程需要执行的函数,args为函数的参数
thread.append(t)#把线程保存到线程列表
for t in range(len(thread)):#获取thread线程列表的长度,并用for循环开启线程
thread[t].start()#运行一个线程
for t in range(len(thread)):
thread[t].join()#表示当主进程中断时,所有的线程也会停止执行
End_Time = datetime.datetime.now()#获取结束时间
Time = End_Time-Start_Time
print('*'*12+'多线程结束'+'*'*12)
print('线程耗时%s秒'%Time)
在了解了多线程之后,我们可以初步编写多线程端口扫描器了
现在给出我的核心源码
# -*- coding: utf-8 -*-
import threading # 导入threading包
import datetime
from socket import *
import re
thread = []#线程列表
openNum = 0#处于开放状态的端口数,默认为0
A_port = []#主机存活的端口列表
def PortScaner(host,port):
global openNum
s = socket(AF_INET, SOCK_STREAM) # 创建套接字
s.settimeout(0.1)#设置socket连接超时,避免socket重复操作
try:
s.connect((host,port))
print('[+]The port %s is open' % (port))
openNum += 1#如果socket连接成功,openNum加1
A_port.append(port)#并把该端口号添加到主机存活的端口列表中
except:
pass #如果连接失败,则pass
s.close()
def ChecK_Host(host): # 利用正侧表达式匹配host,判断是否符合IP地址的格式 并且输入不为空
compile_ip = re.compile(
'^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$')
if compile_ip.match(host) and len(host) != 0: # host符合IP地址的格式且不为空值返回True,否则返回False
return True
else:
return False
def Save_Data(): #保存扫描结果
for i in range(len(A_port)):
d =str(A_port[i])
data = open('Active_Port.txt', 'a')
data.write(d+'\n')
data.close()
def main():
host = input('please input a valid IPv4 address:')
if ChecK_Host(host) and len(host) != 0:
Start_Time = datetime.datetime.now() # 获取开始时间
print('*' * 12 + 'Scanning start=======>%s' % Start_Time + '*' * 12)
for port in range(1, 65536):
t = threading.Thread(target=PortScaner, args=(host, port)) # 创建一个线程,target为线程需要执行的函数,args为函数的参数
thread.append(t) # 把线程保存到线程列表
for t in range(len(thread)): # 先获取thread线程列表的长度,遍历线程列表
thread[t].start() # 运行一个线程,即运行target指定的函数
for t in range(len(thread)):
thread[t].join() # 表示当主进程中断时,所有的线程也会停止执行
End_Time = datetime.datetime.now() # 获取结束时间
Time = End_Time - Start_Time #得出扫描过程花费了多少时间
print('*' * 12 + 'Scanning done=======>%s' % End_Time + '*' * 12)
print('[*]The scanning process consumed %s second' % Time)
print('[*]Scan results:'+'>'*10+'the target host %s opened %s ports in total'%(host,openNum))
print('[*]%s is opening\n'%A_port)
print('[*]The scan results are saved to the Active_Port.txt')
try:
Save_Data()
print('>>>>Save Done!!!')#若保存结果成功,则打印Save Done!!!
except:
print('Save failed!!!')#若保存结果失败,则打印Save failed!!!
else:
print('The IP address is invalid,Please input again!!!')#若输入IP地址为空或不符合格式,则打印The IP address is invalid,Please input again!!!
main()#并重新执行main()函数,实现输入错误则重新输入
if __name__ == '__main__':
main()
无论是单线程还是多线程,我们的最终目的都是,通过扫描收集到目标主机开放了哪些端口,然后进行更深一层的分析利用
另外,可以通过pyinstaller对脚本进行封装,将它打包成exe可执行文件,这样就可以在任意一台没有安装python环境的Windows中运行了
以上内容仅供学习研究,请勿用于进行违法犯罪