python3 端口掃描的編寫(xiě)

前言

之前學(xué)習(xí)python2的時(shí)候?qū)懥硕丝趻呙璧囊恍┠_本有鹿,寫(xiě)的不怎么樣。抽空又重新捋了一遍,使用python3從簡(jiǎn)單的單線程單個(gè)IP到編寫(xiě)多線程枫振、隊(duì)列加線程。也算是以端口掃描為目標(biāo)又重新學(xué)了一遍python3萤彩。

端口掃描

V0.1
python3寫(xiě)的單線程掃描自定義端口粪滤。也是最簡(jiǎn)單的探測(cè)端口開(kāi)放狀態(tài)的腳本。
注解:
1.s.settimeout(0.1) 設(shè)置了超時(shí)時(shí)間乒疏;
2.用最簡(jiǎn)單的connect_ex方法進(jìn)行socket連接额衙,成功返回0,失敗返回error怕吴;
3.使用sys模塊來(lái)接收參數(shù)窍侧;

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import socket
import sys

def scan(host,port):  
    s = socket.socket()
    s.settimeout(0.1)
    # 設(shè)置超時(shí)時(shí)間
    if s.connect_ex((host, port)) == 0:  
        # 與connect一樣,成功返回0.失敗返回error
        print(port,'open')
    s.close()
if __name__ == '__main__':
    if(len(sys.argv) == 2):
        print('User: please port_scan.py IP')
        host = sys.argv[1]
        port = [22,23,25,135,137,445,3306,1541,3389,1080,9200]
        for p in port:
            scan(host,p)
    else:
        print('User: please port_scan.py IP')

V0.2
python3寫(xiě)的單線程掃描端口段转绷。適用于探測(cè)一些web資產(chǎn)伟件,比如8000-10000之間的端口。
注解:
相比較V0.1腳本出現(xiàn)了一下變動(dòng):
1.使用內(nèi)置的map函數(shù)议经,對(duì)每一個(gè)元素調(diào)用function函數(shù)斧账。即每一個(gè)port調(diào)用scan函數(shù)谴返;
2.返回的結(jié)果在python2位list類(lèi)型,python3手動(dòng)添加list咧织;

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import socket
import sys

def scan(port):  
    s = socket.socket()
    s.settimeout(0.1)
    if s.connect_ex((sys.argv[1], port)) == 0:
        print(port,'open')
    s.close()
if __name__ == '__main__':
    if(len(sys.argv) == 4):
        print('User: please port_scan.py IP start_port end_port')
        start_port = int(sys.argv[2])
        end_port = int(sys.argv[3])
        list(map(scan,range(start_port,end_port)))
        # python2 可以直接map返回list嗓袱,python3 需要手動(dòng)list
    else:
        print('User: please port_scan.py IP start_port end_port')

V0.2.1
python3寫(xiě)的單線程掃描端口段。
注解:
1.相比較V0.2腳本习绢,引入了optparse 模塊用于處理命令行參數(shù)渠抹;

#!/usr/bin/env python3
#-*- coding:utf-8 -*-

import socket
import sys
import optparse
# optparse 模塊用于處理命令行參數(shù)

def scan(host,port):  
    s = socket.socket()
    s.settimeout(0.1)
    if s.connect_ex((host, port)) == 0:
        print(port,'open')
    s.close()
if __name__ == '__main__':
    parser = optparse.OptionParser("port_scan.py -H host -s start_port -e end_port")
    parser.add_option("-H",action="store",type="string",dest="host",default="127.0.0.1",help="ip")
    parser.add_option("-s",action="store",type="int",dest="start_port",default=0,help="start_port")
    parser.add_option("-e",action="store",type="int",dest="end_port",default=512,help="end_port")
    (options,args) = parser.parse_args()
    #print(options)
    host = options.host
    start_port = options.start_port
    end_port   = options.end_port
    for p in range(start_port,end_port):
            scan(host,p)

V1.0
python3寫(xiě)的多線程掃描自定義端口。
適用于更快更高效的快速掃描一些端口闪萄。
注解:
1.首先使用了threading模塊多線程梧却,將port進(jìn)行循環(huán)添加線程中,有多少了port就有多少線程數(shù)败去。在port_list列表的端口掃描夠了放航;
2.沒(méi)有加Lock鎖;

# !/usr/bin/env python3
# -*- coding: utf-8 -*-
import threading
import socket
import sys


def scan(host,port):
    s = socket.socket()
    s.settimeout(0.1)
    if s.connect_ex((host, port)) == 0:
        print(port,'open')
    s.close()

def thread():
    thread_list = []
    port_list = [21,22,23,25,80,135,137,139,445,1433,1521,3306,3389,8080,9015]
    for port in port_list:
        t = threading.Thread(target = scan,args = (host,port))
        thread_list.append(t)
    for t in thread_list:
        t.start() #啟動(dòng)線程
    for t in thread_list:
        t.join() #等待到線程終止

if __name__ == '__main__':
    if(len(sys.argv) == 2):
        print('User: please port_scan_thread.py IP')
        host = sys.argv[1]
        thread()
    else:
        print('User: please port_scan_thread.py IP')

V1.0.1
python3 寫(xiě)的多線程自定義端口掃描圆裕。這次使用繼承threading類(lèi)的方式來(lái)編寫(xiě)广鳍。
注解:
1.在對(duì)run方法進(jìn)行重寫(xiě)的時(shí)候,python2 使用的apply()函數(shù)葫辐,python3使用星號(hào)標(biāo)記搜锰。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import threading
import sys
import socket

class Mythread(threading.Thread):
    def __init__(self,fun,args):
        # 初始化
        threading.Thread.__init__(self)
        self.fun = fun
        self.args = args
    def run(self):
        # 重寫(xiě)run方法
        self.fun(*self.args)
        # python2 apply(self.fun,self.args) 
        
def scan(host,port):
    s = socket.socket()
    s.settimeout(0.1)
    if s.connect_ex((host, port)) == 0:
        ip_port = str(host)+':'+str(port)+'\t'+'open'
        print(ip_port)
        save_result('ip_scan_port_result.txt',ip_port)
    s.close()


def save_result(filename,ip_port):
    with open(filename,'a+') as f:
        f.write(str(ip_port)+'\n')


def thread(host):
    port_list = [21,22,23,25,80,135,137,139,445,1433,1521,3306,3389,8080,9015]
    thread_list = []
    for port in port_list:
        t = Mythread(scan,(host,port))
        thread_list.append(t)
    for t in thread_list:
        t.start()
    for t in thread_list:
        t.join()

if __name__=='__main__':
    if(len(sys.argv) == 2):
        print('User: please port_scan_thread.py IP')
        host = sys.argv[1]
        thread(host)
    else:
        print('User: please port_scan_thread.py IP')

V1.1
python3寫(xiě)的多線程掃描指定端口范圍。
適用于更快更高效的快速掃描端口耿战,但是端口范圍不易過(guò)大。
注解:
1.使用threading模塊焊傅,將port進(jìn)行循環(huán)添加線程中剂陡,有多少了port就有多少線程數(shù)。端口范圍不易過(guò)大狐胎,否則意味著線程過(guò)高鸭栖。雖然加了Lock鎖,當(dāng)線程過(guò)高的時(shí)候握巢,程序依然會(huì)崩潰;
2.注意加鎖的位置,在connect_ex之后芥映;
3.也加了時(shí)間方便比較單線程崇败;

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import threading
import socket
import sys
import time

lock = threading.Lock()
# 創(chuàng)建鎖
def scan(host,port):
        s = socket.socket()
        s.settimeout(0.1)
        if s.connect_ex((host, port)) == 0:
                if lock.acquire(): #鎖定
                        print(port,'open')
                        lock.release() #釋放鎖
        s.close()

def thread(port_list):
    thread_list = []
    for port in port_list:
        t = threading.Thread(target = scan,args = (host,port))
        thread_list.append(t)
    for t in thread_list:
        t.start()
    for t in thread_list:
        t.join()

if __name__ == '__main__':
    if(len(sys.argv) == 4):
        print('User: please port_scan_thread.py IP start_port end_port')
        host = sys.argv[1]
        start_port = int(sys.argv[2])
        end_port = int(sys.argv[3])
        port_list = list(range(start_port,end_port))
        t1 = time.time()
        thread(port_list)
        print('intime:',time.time()-t1)
    else:
        print('User: please port_scan_thread.py IP start_port end_port')

V1.2
python3 寫(xiě)的多線程掃描端口段。
注解
1.相比較V1.1歌焦,添加了隊(duì)列解決線程過(guò)高導(dǎo)致程序崩潰的問(wèn)題飞几;
2.利用隊(duì)列先入先出;
3.設(shè)置線程數(shù)為50独撇;

#!/usr/bin/env python3
#-*- coding:utf-8 -*-
import threading
import socket
import sys
import time
import queue


def scan(host,port):
        s = socket.socket()
        s.settimeout(0.1)
        if s.connect_ex((host, port)) == 0:
            print(port,'open')
        s.close()

def worker(host):
    while not q.empty():
        port = q.get() # 取出隊(duì)列
        try:
            scan(host,port)
        finally:
            q.task_done()
def thread(host):
    thread_list = []
    for t in range(50):
        t = threading.Thread(target = worker,args = (host,))
        thread_list.append(t)
    for x in thread_list:
        x.start()
    for x in thread_list:
        x.join()

if __name__ == '__main__':
    if(len(sys.argv) == 4):
        print('User: please port_scan_thread.py IP start_port end_port')
        host = sys.argv[1]
        start_port = int(sys.argv[2])
        end_port = int(sys.argv[3])
        t1 = time.time()
        q = queue.Queue() # 創(chuàng)建隊(duì)列的對(duì)象
        for port in range(start_port,end_port):
            q.put(port) #put()方法將值port放入隊(duì)列
        thread(host)
        q.join()
        print("end time:",time.time()-t1)
    else:
        print('User: please port_scan_thread.py IP start_port end_port')

V1.2.1
python3 寫(xiě)的多線程掃描端口段屑墨。
注解
1.只是把thread線程設(shè)置為自定義參數(shù)躁锁。當(dāng)然不建議自定義的線程過(guò)高;

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import threading
import socket
import sys
import time
import queue


def scan(host,port):
        s = socket.socket()
        s.settimeout(0.1)
        if s.connect_ex((host, port)) == 0:
            print(port,'open')
        s.close()

def worker(host):
    while not q.empty():
        port = q.get() # 取出隊(duì)列
        try:
            scan(host,port)
        finally:
            q.task_done()
def thread(host,threads):
    thread_list = []
    for t in range(threads):
        t = threading.Thread(target = worker,args = (host,))
        thread_list.append(t)
    for x in thread_list:
        x.start()
    for x in thread_list:
        x.join()

if __name__ == '__main__':
    if(len(sys.argv) == 5):
        print('User: please port_scan_thread.py IP start_port end_port threads')
        host = sys.argv[1]
        start_port = int(sys.argv[2])
        end_port = int(sys.argv[3])
        threads = int(sys.argv[4])
        t1 = time.time()
        q = queue.Queue() # 創(chuàng)建隊(duì)列的對(duì)象
        for port in range(start_port,end_port):
            q.put(port) #put()方法將值port放入隊(duì)列
        thread(host,threads)
        q.join()
        print("end time:",time.time()-t1)
    else:
        print('User: please port_scan_thread.py IP start_port end_port threads')

V1.3
python3 寫(xiě)的多線程掃描多個(gè)端口卵史。
注解
1.增加了輸出端口战转,保存在ip_scan_port_result.txt 文件中

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import threading
import socket
import sys
import time
import queue


def scan(host,port):
        s = socket.socket()
        s.settimeout(0.1)
        if s.connect_ex((host, port)) == 0:
            ip_port = str(host)+':'+str(port)+'\t'+'open'
            print(ip_port)
            save_result('ip_scan_port_result.txt',ip_port)
        s.close()

def save_result(filename,ip_port):
    with open(filename,'a+') as f:
        f.write(str(ip_port)+'\n')


def worker(host):
    while not q.empty():
        port = q.get() # 取出隊(duì)列
        try:
            scan(host,port)
        finally:
            q.task_done()
def thread(host,threads):
    thread_list = []
    for t in range(threads):
        t = threading.Thread(target = worker,args = (host,))
        thread_list.append(t)
    for x in thread_list:
        x.start()
    for x in thread_list:
        x.join()

if __name__ == '__main__':
    if(len(sys.argv) == 5):
        print('User: please port_scan_thread.py IP start_port end_port threads')
        host = sys.argv[1]
        start_port = int(sys.argv[2])
        end_port = int(sys.argv[3])
        threads = int(sys.argv[4])
        t1 = time.time()
        q = queue.Queue() # 創(chuàng)建隊(duì)列的對(duì)象
        for port in range(start_port,end_port):
            q.put(port) #put()方法將值port放入隊(duì)列
        thread(host,threads)
        q.join()
        print("end time:",time.time()-t1)
    else:
        print('User: please port_scan_thread.py IP start_port end_port threads')

V1.4
python3寫(xiě)的多線程全端口掃描。
注解
1.默認(rèn)也是50個(gè)線程以躯;
2.把start_port匣吊、end_port寫(xiě)死就行;

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import threading
import socket
import sys
import time
import queue


def scan(host,port):
        s = socket.socket()
        s.settimeout(0.1)
        if s.connect_ex((host, port)) == 0:
            print(port,'open')
        s.close()

def worker(host):
    while not q.empty():
        port = q.get() # 取出隊(duì)列
        try:
            scan(host,port)
        finally:
            q.task_done() 
def thread(host):
    thread_list = []
    for t in range(50):
        t = threading.Thread(target = worker,args = (host,))
        thread_list.append(t)
    for x in thread_list:
        x.start()
    for x in thread_list:
        x.join()

if __name__ == '__main__':
    if(len(sys.argv) == 2):
        print('User: please port_scan_thread.py IP')
        host = sys.argv[1]
        t1 = time.time()
        q = queue.Queue() # 創(chuàng)建隊(duì)列的對(duì)象
        for port in range(1,65535):
            q.put(port) #put()方法將值port放入隊(duì)列
        thread(host)
        q.join()
        print("end time:",time.time()-t1)
    else:
        print('User: please port_scan_thread.py IP')

參考資料

https://github.com/windard/Port_Scan
https://blog.csdn.net/handsomekang/article/details/39826729

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載寸潦,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者色鸳。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市见转,隨后出現(xiàn)的幾起案子命雀,更是在濱河造成了極大的恐慌,老刑警劉巖斩箫,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吏砂,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡乘客,警方通過(guò)查閱死者的電腦和手機(jī)狐血,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)易核,“玉大人匈织,你說(shuō)我怎么就攤上這事∧抵保” “怎么了缀匕?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)碰逸。 經(jīng)常有香客問(wèn)我乡小,道長(zhǎng),這世上最難降的妖魔是什么饵史? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任满钟,我火速辦了婚禮,結(jié)果婚禮上胳喷,老公的妹妹穿的比我還像新娘湃番。我一直安慰自己,他們只是感情好厌蔽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布牵辣。 她就那樣靜靜地躺著,像睡著了一般奴饮。 火紅的嫁衣襯著肌膚如雪纬向。 梳的紋絲不亂的頭發(fā)上择浊,一...
    開(kāi)封第一講書(shū)人閱讀 51,443評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音逾条,去河邊找鬼琢岩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛师脂,可吹牛的內(nèi)容都是我干的担孔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼吃警,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼糕篇!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起酌心,我...
    開(kāi)封第一講書(shū)人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤拌消,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后安券,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體墩崩,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年侯勉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鹦筹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡址貌,死狀恐怖铐拐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情芳誓,我是刑警寧澤余舶,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站锹淌,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏赠制。R本人自食惡果不足惜赂摆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望钟些。 院中可真熱鬧烟号,春花似錦、人聲如沸政恍。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)篙耗。三九已至迫筑,卻和暖如春宪赶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背脯燃。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工搂妻, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人辕棚。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓欲主,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親逝嚎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子扁瓢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354