前言
仅用于交流学习,不可用于商业用途开发环境,不可非法测试。
本文章将利用python中的模块,以达到端口扫描的目的。
端口扫描的原理也很好理解,就是去连接目标主机和端口来进行判断是否开发了该端口。
我们会用到socket(套接字)这个模块,套接字是什么,它是计算机之间进行通信的一种约定或一种方式。通过 socket 这种约定,一台计算机可以向其他计算机发送数据,也可以接收其他计算机的数据。
Python 中,我们用 socket()函数来创建套接字,语法格式如下:
socket.socket([family[, type[, proto]]])
参数
- family: 套接字家族可以使 AF_UNIX 或者 AF_INET。
- type: 套接字类型可以根据是面向连接的还是非连接分为
SOCK_STREAM
或SOCK_DGRAM
。 - protocol: 一般不填默认为 0。
简单的学习一下socket模块中的函数,我们就开始写代码。
import socket
def tcp_scan(host, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建套接字
sock.settimeout(3) # 设置超时时间
res = sock.connect_ex((host, port)) # 连接主机和端口
sock.close() # 关闭套接字
if res == 0:
print(f"{host}:{port} open")
else:
pass
host = "127.0.0.1"
port = 445
tcp_scan(host, port)
运行效果
这里只能扫描一个端口
我们在后面修改一下加个循环就能扫描多个端口了
for port in range(1, 65536):
tcp_scan(host, port)
这时候扫描的速度很慢,可能扫完需要几分钟
这时候我们可以去增加线程,达到多线程的效果去扫描端口
我们使用threading模块,这边还是要先去了解这个模块的一些使用方法,还有一些线程的概念,这边我们就直接开始写代码了
import socket
import threading
class MyThread(threading.Thread): # 继承
def __init__(self, host, port):
threading.Thread.__init__(self) # self用于引用当前实例化的
self.host = host
self.port = port # 用于存储传入的 host 和 port 参数值
def run(self): # 它是threading.Thread类的重载方法,也是子线程的主要执行代码
tcp_scan(host, self.port)
def tcp_scan(host, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建套接字
sock.settimeout(3) # 设置超时时间
res = sock.connect_ex((host, port)) # 连接主机跟端口
sock.close() # 关闭套接字
if res == 0:
print(f"{host}:{port} open")
else:
pass
host = "127.0.0.1"
thread_task = [MyThread(host, port) for port in range(1, 65536)] # 定义一个线程池任务
for t in thread_task:
t.start() # 开启线程
for t in thread_task:
t.join() # 关闭线程
运行看看效果
扫描一次大概在30秒左右,我们可以利用time模块,在代码开始处和结尾处加上时间,就能判断扫描这些端口所用的时间是多少。
总结
到这里本文就结束了,代码还是蛮简单的,主要还是要去理解一下socket的使用方法,还有一些参数的作用,其次就是要去理解一下线程的一些原理。😁😁😁