python编写的端口扫描脚本

 实训项目制作的端口扫描脚本

附有详细的使用命令解释

可以实现单个端口进行扫描和端进行扫描

eg:1-65535

import optparse  # 导入用于解析命令行参数的模块
import socket  # 导入用于网络通信的模块

# 定义函数:扫描指定主机的指定端口
def PortScan(targetHost, targetPort):
    try:
        connSkt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 创建套接字对象,   # socket.AF_INET 表示地址族(Address Family),用于指定套接字使用的地址类型,这里是 IPv4 地址族。
                                                                                        # socket.SOCK_STREAM 表示套接字类型(Socket Type),用于指定套接字的传输类型,这里是 TCP。
        connSkt.settimeout(1)  # 设置连接超时时间为 1 秒
        connSkt.connect((targetHost, targetPort))  # 尝试连接指定的主机和端口
        connSkt.send(b'PortScan
')  # 发送字节数据到连接的套接字
        results = connSkt.recv(1000)  # 接收数据并存储结果
        print('[+] %d/tcp open' % targetPort)  # 输出端口开放信息
        print('[+] ' + str(results))  # 输出收到的数据
    except socket.error:
        print('[-] %d/tcp closed' % targetPort)  # 端口关闭或发生错误时输出信息
    finally:
        connSkt.close()  # 关闭套接字连接

# 定义函数:执行端口扫描
def Scan(targetHost, targetPorts):
    try:
        tgtIP = socket.getaddrinfo(targetHost, 0)[0][4][0]  # 获取目标主机的 IP 地址,socket.getaddrinfo(targetHost, 0) 返回一个包含解析信息的列表。
    except socket.gaierror:
        print('[-] Cannot resolve %s: Unknown host' % targetHost)  # 若无法解析主机名则输出错误信息并返回
        return
    try:
        tgtName = socket.gethostbyaddr(tgtIP)[0]    # 获取 IP 地址对应的主机名
                                                    # socket.gethostbyaddr() 函数用于执行 IP 地址到主机名的反向 DNS 解析。它接受一个 IP 地址作为参数,并返回与该地址关联的主机名。
        print("
[+] Scan results for: " + tgtName)  # 输出扫描结果的主机名
    except socket.herror:                       # 表示与主机和网络相关的错误。
        print("Scan Results for: " + tgtIP)  # 若无法获取主机名则输出 IP 地址
    for targetPort in targetPorts:  # 遍历指定的端口列表
        print("Scanning port: " + str(targetPort))  # 输出当前正在扫描的端口
        PortScan(targetHost, int(targetPort))  # 调用 PortScan 函数扫描各个端口

# 解析端口范围参数
def parse_port_range(port_range):
    ports = []
    try:
        if "-" in port_range:
            start, end = port_range.split("-")      #split("-") 方法通过分隔符 "-" 将字符串 port_range 拆分成两部分,左侧部分是起始端口,右侧部分是结束端口。这两部分被赋值给 start 和 end 变量。
            for port in range(int(start), int(end) + 1):
                ports.append(port)
        else:
            ports.append(int(port_range))
    except ValueError:
        print("Invalid port range specified. Please use format 'start-end' or 'port'.")
        exit(0)
    return ports

# 主函数
def main():
    parser = optparse.OptionParser("Usage prog -H <target host> -p <target ports>")        # 是 Python 中用于解析命令行参数的模块。它允许您编写带有选项和参数的命令行接口,并解析用户提供的输入
    parser.add_option('-H', dest='targetHost', type='string', help='specify target host')   # add_option() 方法用于添加选项,
                                                                                            # dest 参数用于指定选项被解析后存储的目标属性名称。当用户在命令行中使用选项时,解析器会将解析后的值存储到指定的目标属性中。
                                                                                            # type 参数用于指定在解析命令行参数时所期望的数据类型。这个参数允许您告诉解析器应该将参数解析为何种数据类型。
                                                                                            # string 是一个数据类型或一个表示字符类型的字符串
    parser.add_option('-p', dest='targetPort', type='string', help='specify target port▼显示 inside "" separated by commas(1-65535)')
    (options, args) = parser.parse_args()               #parse_args() 方法用于解析命令行参数,并返回解析后的结果。
    targetHost = options.targetHost  # 获取目标主机
    port_range = options.targetPort  # 获取端口范围参数

    if (targetHost is None) or (port_range is None):  # 如果未提供目标主机或端口范围,则输出用法信息并退出程序
        print(parser.usage)                     # parser.usage 是一个属性,用于获取程序使用说明的自定义文本。
        exit(0)

    targetPorts = parse_port_range(port_range)  # 解析端口范围参数

    Scan(targetHost, targetPorts)  # 调用 Scan 函数执行端口扫描

# 程序入口
if __name__ == "__main__":
    main()  # 调用主函数开始执行端口扫描