Python笔记(三)--socket实现端口扫描(多线程版)

版权声明:本文为博主原创文章,未经博主允许不得转载。 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中运行了

以上内容仅供学习研究,请勿用于进行违法犯罪

猜你喜欢

转载自blog.csdn.net/coloson/article/details/89037090