• 端口扫描工具python


    端口扫描工具

    TCP模式-socket

    原理

    目标主机的一个端口如果是监听状态(LISTENING或者LINSTEN),那么当我connect目标主机时就能成功,否则说明端口是关闭的。
    优点: 编程简单,是需要一个API connect(),比较可靠,因为TCP是可靠协议,当丢包的时候,会重传SYN帧。
    缺点: 正因为TCP的可靠性,所以当端口不存在的时候,源主机会不断尝试发SYN帧企图得到ack的应答,多次尝试后才会放弃,因此造成了扫描的时间较长。并且,connect的扫描方式可能较容易被目标主机发现。
    

    主要是一个编程思路,代码很简单

    1、定义portscan函数,创建socke对象,进行TCP端口扫描
    2、启动多线程运行PortScan函数
    3、记录并输出扫描结果与时间
    

    主要还是利用了三次握手来判断目标端口是否开启:

    image-20220704220447269

    创建端口扫描函数

    def portscan(target,port):
        # 定义portscan函数,进行TCP端口扫描
        try:
            client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  #创建socket对象
            client.connect((target,port))  #建立socket连接,判断端口是否开放
            print("[*] %s:%d端口开放" % (target,port))
            client.close()
        except:
            pass  #捕获异常,避免socket连接建立失败造成程序退出
    

    直接测试调用函数,简单完善一次,测试100个端口:

    import socket
    import time
    
    
    def portscan(target,port):
        # 定义portscan函数,进行TCP端口扫描
        try:
            client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  #创建socket对象
            client.connect((target,port))  #建立socket连接,判断端口是否开放
            print("[*] %s:%d端口开放" % (target,port))
            client.close()
        except:
            pass  #捕获异常,避免socket连接建立失败造成程序退出
    
    start_time = time.time()
    for i in range(0,1001,1):
    
        print('正在进行第{}个端口'.format(i))
        portscan('127.0.0.1',i)
    
    print('end')
    end_time = time.time()
    print("[*] All done in %.2f s" % (end_time - start_time))
    

    image-20220704221050939

    可以看到非常的慢,看下用时,50个端口用了近100秒

    image-20220704221302606

    加入多线程

    for port in range(1,9999):
            # 启动多线程运行PortScan函数
            t = Thread(target=portscan,args=(target,port))  #创建线程对象
            t.start()  #开始线程
    

    完整代码

    扫描1-65535

    import socket  #创建TCP连接
    from threading import Thread  #多线程模块,进行多线程扫描
    import time  #时间模块,记录扫描所需时间
    
    def main():
        target = input("IP:")
        start_time = time.time()
        s_time = time.ctime()
        print("[*] Start port scan at %s" % s_time)
        for port in range(1,65536):  #定义扫描的端口范围
            # 2、启动多线程运行PortScan函数
            t = Thread(target=portscan, args=(target, port))  # 创建线程对象
            t.start()  # 开始线程
    
        end_time = time.time()
        print("[*] All done in %.2f s" % (end_time - start_time))
    
    
    def portscan(target,port):
        # 定义portscan函数,进行TCP端口扫描
        try:
            client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  #创建socket对象
            client.connect((target,port))  #建立socket连接,判断端口是否开放
            print("[*] %s:%d端口开放" % (target,port))
            client.close()
        except:
            pass  #捕获异常,避免socket连接建立失败造成程序退出
    
    if __name__ == '__main__':
        main()
    

    image-20220704221448827

    可以看到多线程快了很多,只用了9秒钟

    完善功能

    import socket  #创建TCP连接
    from threading import Thread  #多线程模块,进行多线程扫描
    import time  #时间模块,记录扫描所需时间
    
    def main():
        target = input("IP:")
        start_time = time.time()
        s_time = time.ctime()
        port_tmp = int(input("选择全端口(数字1)还是指定端口(数字2):"))
        if port_tmp==1:
            print("[*] Start port scan at %s" % s_time)
            for port in range(1,65536):  #定义扫描的端口范围
                # 2、启动多线程运行PortScan函数
                t = Thread(target=portscan, args=(target, port))  # 创建线程对象
                t.start()  # 开始线程
        elif port_tmp==2:
            port_tmp2 = input("请输入端口列表,以逗号分割,列如80,8080,7001:")
            prot_list=port_tmp2.split(',')
            print(prot_list)
            for port_i in prot_list:
                t = Thread(target=portscan, args=(target, int(port_i)))  # 创建线程对象
                t.start()  # 开始线程
    
        end_time = time.time()
        print("[*] All done in %.2f s" % (end_time - start_time))
    
    
    def portscan(target,port):
        # 定义portscan函数,进行TCP端口扫描
        try:
            client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  #创建socket对象
            client.connect((target,port))  #建立socket连接,判断端口是否开放
            print("[*] %s:%d端口开放" % (target,port))
            client.close()
        except:
            pass  #捕获异常,避免socket连接建立失败造成程序退出
    
    if __name__ == '__main__':
        main()
    

    image-20220704222304548

    image-20220704222718402

    SYN扫描

    原理

    TCP SYN 扫描也就是半开扫描(半开式扫描),这种扫描方式与全连接扫描类似,但客户端不会和服务端建立完整的连接。
    
    扫描过程为:客户端会发送一个带有 SYN 标识和端口号的 TCP 数据包给服务器,如果服务器这个端口是开放的,则会接受这个连接并返回一个带有 SYN 和 ACK 标识的数据包给客户端,随后客户端会返回带有 RST 标识的数据包,而不是像全连接扫描一样返回一个带有 ACK和 RST 标识的数据包,这样就不会与服务端建立完整的连接了。如果目标端口处于关闭状态,则服务端会返回一个 RST 标识的数据包。
    

    代码(多线程)

    import threading,time
    import sys
    from scapy.all import *
    from scapy.layers.inet import IP, TCP, ICMP
    
    
    
    def get_ip():
        '''从命令行参数中获取 IP'''
        try:
            parameter = sys.argv
            ip = parameter[1]
            print('The IP you test is : ', end = '')
            font.print_YELLOW(ip)
        except Exception as e:
            print(e)
        return ip
    
    
    def port_scan(port):
        '''扫描端口'''
        try:
            packet = IP(dst=ip)/TCP(dport=port,flags='S')   # 构造一个 flags 的值为 S 的报文
            send = sr1(packet,timeout=2,verbose=0)
            if send.haslayer('TCP'):
                if send['TCP'].flags == 'SA':   # 判断目标主机是否返回 SYN+ACK
                    send_1 = sr1(IP(dst=ip)/TCP(dport=port,flags='R'),timeout=2,verbose=0) # 只向目标主机发送 RST
                    font.print_GREEN('[+] %d is open' % port)
                elif send['TCP'].flags == 'RA':
                    pass
        except:
            pass
    
    def main():
    
        packet_ping = IP(dst=ip)/ICMP()     # 在扫描端口之前先用 ICMP 协议探测一下主机是否存活
        ping = sr1(packet_ping,timeout=2,verbose=0)
        if ping is not None:
            for p in range(1,65535):   # 默认扫描1-1000的端口,可以手动修改这里的端口范围
                t = threading.Thread(target=port_scan,args=(p,))
                t.start()
    
    
        elif ping is None:
            font.print_RED('该主机处于关闭状态或本机被该主机过滤,无法对其使用 ping 探测')
    
    
    if __name__ == '__main__':
        ip = get_ip()
        start_time = time.time()
        main()
        end_time = time.time()
        print('[time cost] : ' + str(end_time-start_time) + ' 秒')
    

    image-20220707163857256

  • 相关阅读:
    祝各位博友新年快乐,全家幸福,大展宏图,财源滚滚!
    Android中级第五讲GPRS定位的实现
    Android高级开发第二讲Android中API翻译之Activity
    Android 图标、音频、颜色RGB工具集
    Android初级开发第八讲之startActivityForResult方法讲解
    Android高级开发第三讲应用程序基础
    Android高级开发第四讲API之Service
    Android高级开发第五讲API之Content Providers
    物联网操作系统是否需要基于Java和虚拟机进行构筑
    Android高级开发第四讲API之Intents and Intent Filters
  • 原文地址:https://www.cnblogs.com/liyu8/p/16455331.html
Copyright © 2020-2023  润新知