tcp端口掃描(python多線程)


1 使用單線程掃描單台主機

首先實現的是對單台主機中0-1024端口的掃描,發現差不多每秒掃描一個端口,很慢。

import socket

def tcp_scanner(host,port):
    client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    try:
        client.connect((host, port))
        print('connected to host %s,port %d successfully' %(host,port))
        return True
    except:
        # print('connected to host %s,port %d failed'  %(host,port))
        return False

if __name__ == '__main__':
    host = "192.168.10.10"
    for port in range(1024):
        tcp_scanner(host,port)

  

2 使用多線程掃描單台主機

import threading,socket

def tcp_scanner(host,port):
    client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    try:
        client.connect((host, port))
        print('connected to host %s,port %d successfully' %(host,port))
        client.close()
        return True
    except:
        # print('connected to host %s,port %d failed'  %(host,port))
        return False

if __name__ == '__main__':
    host = "192.168.10.10"
    for port in range(1,1024):
        th = threading.Thread(target=tcp_scanner,args=(host,port))
        th.start()

  

在運行以上代碼時,出現報錯:RuntimeError: can't start new thread,原因是超過了線程啟動數的上限。

解決辦法是修改最大文件描述符打開數。

 

3 使用多線程掃描多台主機

import threading,socket,subprocess

def tcp_scanner(host,port):
    client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    try:
        client.connect((host, port))
        print('connected to host %s,port %d successfully' %(host,port))
        client.close()
        return True
    except:
        # print('connected to host %s,port %d failed'  %(host,port))
        return False

def main():

    for i in range(2,255):

        # host = "10.224.32.%d" %i
        host = "192.168.136.%d" %i
        cmd = 'fping %s 1>/dev/null 2>&1;echo $?' %host
        p = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True)
        ret = int(p.stdout.read())
        if ret == 0:
            for port in range(1,4000):
                th = threading.Thread(target=tcp_scanner,args=(host,port))
                th.start()
        else:
            print('status of %s:False' %host)

if __name__ == '__main__':
    main()

  

上面的問題又出現了,可以用的文件描述符不夠,即使改到655350。畢竟是全盤掃描。

解決辦法是加信號threading.Semaphore,限制線程數

'''
create  2018/9/24
version 1.0
auth    jabbok
info    scan all the tcp port of the listed hosts by multithreading,to know is it listened
'''

import threading,socket,subprocess,time

screenLock = threading.Semaphore(value=1)

def tcp_scanner(host,port):

    socket.setdefaulttimeout(1)
    client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

    try:
        client.connect((host, port))
        print('connected to host %s,port %d successfully' %(host,port))
        client.close()
        screenLock.acquire()
        return True

    except:
        screenLock.acquire()
        return False

    finally:
        screenLock.release()
        client.close()

def main():

    for i in range(2,255):
        # host = "10.224.32.%d" %i
        host = "192.168.136.%d" %i
        cmd = 'fping %s 1>/dev/null 2>&1;echo $?' %host
        p = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True)
        ret = int(p.stdout.read())

        if ret == 0:
            for port in range(1,4000):
                th = threading.Thread(target=tcp_scanner,args=(host,port))
                th.start()

        else:
            print('status of %s:False' %host)

if __name__ == '__main__':
    main()

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM