ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

端口扫描工具-python

2022-07-07 17:03:40  阅读:196  来源: 互联网

标签:socket 端口扫描 端口 TCP python time 工具 port target


端口扫描工具

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

标签:socket,端口扫描,端口,TCP,python,time,工具,port,target
来源: https://www.cnblogs.com/liyu8/p/16455331.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有