python3-端口扫描(TCP connect扫描,SYN扫描,FIN扫描)

利用python3进行端口扫描,TCP的方式有connect扫描,SYN扫描,FIN扫描,NULL扫描,ACK扫描,Xmas,windows扫描。本次展示前三种,代码仅供参数:

  • 扫描方式 1:TCP connect扫描

扫描端与目标主机建立tcp连接,完成三次握手后,扫描端主动关闭连接(缺点:目标主机会记录下连接内容)

# -*- coding: utf-8 -*-
import queue
import socket
import threading

'''
功能介绍:
    通过TCPconnect进行端口扫描,需要用户输入ip,port,线程数(默认10)
函数介绍:
    Portscan_print(ip)                              #结果排序打印
    Portscan_Threadfun(ip)                          #线程分配函数
    Portscan_TCPconnect(ip, p)                      #扫描功能实现
    Portscan_threadnum(ip,num=10)                   #控制线程数量
    Portscan_portlist(ip,userport)                  #扫描端口处理
'''

def Portscan_Threadfun(ip):                         # 工具人
    while True:
        if q.empty():                               # 判断队列是否为空
            break
        else:
            port = q.get()                          # 取出一个端口
            Portscan_TCPconnect(ip, port)


def Portscan_TCPconnect(ip, p):                     # TCPconnect功能实现
    try:
        port = int(p)
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        if port == 3306 or port == 22 or port == 23 or port == 1521:
            s.settimeout(4)
        else:
            s.settimeout(1)
        s.connect((ip, port))
        openport_list.append(port)
    except Exception as e:
        closeport_list.append(port)
    finally:
        s.close()


def Portscan_print(ip):                             # 打印函数,排序
    openport_list.sort()
    for i in openport_list:
        print(ip + "	" + str(i) + " Open		")
    closeport_list.sort()
    for i in closeport_list:
        print(ip + "	" + str(i) + " Close")


def Portscan_threadnum(ip, num=10):                 # 控制线程函数
    thread_joinlist = []
    for i in range(0, num):                         # 控制线程数
        new_thread = threading.Thread(target=Portscan_Threadfun, args=(ip,))
        new_thread.start()
        thread_joinlist.append(new_thread)
    for i in thread_joinlist:
        i.join()                                    # 循环等待每个线程完成任务,之后在进行打印工作


def Portscan_portlist(ip, threadnum, userport=0):   # 端口处理函数
    global q
    global openport_list
    global closeport_list
    q = queue.Queue()
    openport_list = []
    closeport_list = []
    if userport:
        if ',' in userport:
            ports = userport.split(',')
        elif '-' in userport:
            ports = userport.split('-')
            tmpports = []
            [tmpports.append(i) for i in range(int(ports[0]), int(ports[1]) + 1)]
            ports = tmpports
        else:
            ports = [userport]
    else:
        print('Default Ports')
        ports = [21, 22, 23, 53, 80, 111, 139, 161, 389, 443, 445, 512, 513, 514,
                 873, 1025, 1433, 1521, 3128, 3306, 3311, 3312, 3389, 5432, 5900,
                 5984, 6082, 6379, 7001, 7002, 8000, 8080, 8081, 8090, 9000, 9090,
                 8888, 9200, 9300, 10000, 11211, 27017, 27018, 50000, 50030, 50070]
    [q.put(i) for i in ports]                       # 将端口加入queue队列
    Portscan_threadnum(ip, threadnum)
    Portscan_print(ip)                              # 打印输出函数


if __name__ == '__main__':
    ip = '104.193.88.77'
    userport = '443'
    threadnum = 20
    Portscan_portlist(ip, threadnum, userport)
  • 扫描方式 2:SYN扫描

扫描主机主动向目标主机指定端口发送SYN数据,表示建立连接请求,如果目标主机回应SYN+ACK,说明端口活动。回复RST说明目标端口不存活。接着扫描主机回一个RST给目标主机拒绝连接。导致三次握手失败(不会留下连接记录)

# -*- coding: utf-8 -*-
import queue
import threading
from scapy.sendrecv import sr
from scapy.layers.inet import IP, TCP

'''
功能介绍:
    通过TCPSYN进行端口扫描,需要用户输入ip,port,线程数(默认10)
'''


def Portscan_Threadfun(ip):                         # 工具人
    while True:
        if q.empty():                               # 判断队列是否为空
            break
        else:
            port = q.get()                          # 取出一个端口
            Portscan_SYN(ip, port)


def Portscan_SYN(ip, port):
    try:
        temp = sr(IP(dst=ip) /
                  TCP(dport=(int(port)), flags='S'),
                  timeout=2, verbose=False)
        if temp[0].res:
            result = temp[0].res                    # temp分回复和无回显
            if (result[0][1].payload.flags) == 'SA':
                print('端口开放')
                openport_list.append(port)
                return 1
            else:
                closeport_list.append(port)
        else:
            closeport_list.append(port)
            return 0
    except:
        closeport_list.append(port)
        return 0

def Portscan_print(ip):                             # 打印函数,排序
    openport_list.sort()
    for i in openport_list:
        print(ip + "	" + str(i) + " Open		")
    closeport_list.sort()
    for i in closeport_list:
        print(ip + "	" + str(i) + " Close")


def Portscan_threadnum(ip, num=10):                 # 控制线程函数
    thread_joinlist = []
    for i in range(0, num):                         # 控制线程数
        new_thread = threading.Thread(target=Portscan_Threadfun, args=(ip,))
        new_thread.start()
        thread_joinlist.append(new_thread)
    for i in thread_joinlist:
        i.join()                                    # 循环等待每个线程完成任务,之后在进行打印工作

def Portscan_synport(ip,userport,threadnum=50):
    global q
    global openport_list
    global closeport_list
    openport_list = []
    closeport_list = []
    q = queue.Queue()
    if userport:
        if ',' in userport:
            ports = userport.split(',')
        elif '-' in userport:
            ports = userport.split('-')
            tmpports = []
            [tmpports.append(i) for i in range(int(ports[0]), int(ports[1]) + 1)]
            ports = tmpports
        else:
            ports = [userport]
    else:
        print('Default Ports')
        ports = [21, 22, 23, 53, 80, 111, 139, 161, 389, 443, 445, 512, 513, 514,
                 873, 1025, 1433, 1521, 3128, 3306, 3311, 3312, 3389, 5432, 5900,
                 5984, 6082, 6379, 7001, 7002, 8000, 8080, 8081, 8090, 9000, 9090,
                 8888, 9200, 9300, 10000, 11211, 27017, 27018, 50000, 50030, 50070]

    [q.put(i) for i in ports]                           #将端口加入队列
    Portscan_threadnum(ip,threadnum)
    Portscan_print(ip)



if __name__ == '__main__':
    ip = '192.168.0.110'
    port = '400-500'
    Portscan_synport(ip,port)
  • 扫描方式 3:FIN扫描

FIN扫描和NULL扫描类似,将标志位FIN置1,如果端口开放,则没有反应,端口关闭,目标主机会发送RST,同样在windows上不适用

from scapy.layers.inet import IP, TCP
from scapy.sendrecv import sr, sr1

'''
适用于Linux设备
通过设置flags位为'FIN',不回复则表示端口开启,回复并且回复的标志位为RST表示端口关闭
'''
def fin_scan(ip, port):
    p = IP(dst=ip) / TCP(dport=int(port), flags="F")
    ans = sr1(p, timeout=1, verbose=1)
    print(ans)
    if ans == None:
        print(ip, "port", port, "is open.")
    elif ans != None and ans[TCP].flags == 'RA':
        ans.display()
        print(ip, "port", port, "is closed.")

if __name__ == '__main__':
    ip = '192.168.0.112'
    port = 55
    fin_scan(ip,port)
原文地址:https://www.cnblogs.com/Tempt/p/14267172.html