使用Python3制作TCP端口掃描器
在滲透測(cè)試的初步階段通常我們都需要對(duì)攻擊目標(biāo)進(jìn)行信息搜集,而端口掃描就是信息搜集中至關(guān)重要的一個(gè)步驟。通過端口掃描我們可以了解到目標(biāo)主機(jī)都開放了哪些服務(wù),甚至能根據(jù)服務(wù)猜測(cè)可能存在某些漏洞。 TCP端口掃描一般分為以下幾種類型:
TCP connect掃描:也稱為全連接掃描,這種方式直接連接到目標(biāo)端口,完成了TCP三次握手的過程,這種方式掃描結(jié)果比較準(zhǔn)確,但速度比較慢而且可輕易被目標(biāo)系統(tǒng)檢測(cè)到。
TCP SYN掃描:也稱為半開放掃描,這種方式將發(fā)送一個(gè)SYN包,啟動(dòng)一個(gè)TCP會(huì)話,并等待目標(biāo)響應(yīng)數(shù)據(jù)包。如果收到的是一個(gè)RST包,則表明端口是關(guān)閉的,而如果收到的是一個(gè)SYN/ACK包,則表示相應(yīng)的端口是打開的。
Tcp FIN掃描:這種方式發(fā)送一個(gè)表示拆除一個(gè)活動(dòng)的TCP連接的FIN包,讓對(duì)方關(guān)閉連接。如果收到了一個(gè)RST包,則表明相應(yīng)的端口是關(guān)閉的。
TCP XMAS掃描:這種方式通過發(fā)送PSH、FIN、URG、和TCP標(biāo)志位被設(shè)為1的數(shù)據(jù)包。如果收到了一個(gè)RST包,則表明相應(yīng)的端口是關(guān)閉的。
下面我們將使用Python3 實(shí)現(xiàn)TCP全連接端口掃描器,下面進(jìn)入編程環(huán)節(jié)。
編碼實(shí)戰(zhàn)
全連接掃描
方式的核心就是針對(duì)不同端口進(jìn)行TCP連接,根據(jù)是否連接成功來判斷端口是否打開,現(xiàn)在我們來實(shí)現(xiàn)一個(gè)最簡(jiǎn)單的端口掃描器:
#!/usr/bin/python3 # -*- coding: utf-8 -*- from socket import * def portScanner(host,port): try: s = socket(AF_INET,SOCK_STREAM) s.connect((host,port)) print('[+] %d open' % port) s.close() except: print('[-] %d close' % port) def main(): setdefaulttimeout(1) for p in range(1,1024): portScanner('192.168.0.100',p) if __name__ == '__main__': main()
這段代碼的核心就是portScanner
函數(shù),從其中的內(nèi)容可以看出,只是進(jìn)行了簡(jiǎn)單的TCP連接,如果連接成功則判斷為端口打開,否則視為關(guān)閉。 我們來看一下運(yùn)行結(jié)果:
這樣的掃描看起來效率太低了,實(shí)際也確實(shí)很慢,因?yàn)槲覀冊(cè)O(shè)置了默認(rèn)的超時(shí)時(shí)間為1秒,這要是掃描10000個(gè)端口,豈不是要等到花都謝了? 最簡(jiǎn)單的辦法就是用多線程
來提高效率,雖然python的多線程有點(diǎn)太弱了,不過至少可以利用我們等待的時(shí)間去干點(diǎn)別的。另外之前掃描的端口比較多, 顯示的信息我們看起來不方便,這次我們只顯示我們關(guān)心的打開的端口
,并將打開端口的數(shù)量在掃描結(jié)束的時(shí)候顯示出來。
#!/usr/bin/python3 # -*- coding: utf-8 -*- from socket import * import threading lock = threading.Lock() openNum = 0 threads = [] def portScanner(host,port): global openNum try: s = socket(AF_INET,SOCK_STREAM) s.connect((host,port)) lock.acquire() openNum+=1 print('[+] %d open' % port) lock.release() s.close() except: pass def main(): setdefaulttimeout(1) for p in range(1,1024): t = threading.Thread(target=portScanner,args=('192.168.0.100',p)) threads.append(t) t.start() for t in threads: t.join() print('[*] The scan is complete!') print('[*] A total of %d open port ' % (openNum)) if __name__ == '__main__': main()
運(yùn)行看一下效果,如下圖:
這下看起來是不是方便多了?至此效率上的問題解決了,現(xiàn)在我們還需要為掃描器增加一個(gè) 參數(shù)解析的功能,這樣才能看起來像個(gè)樣子,總不能每次都改代碼來修改掃描目標(biāo)和端口吧!
參數(shù)解析我們將用python3自帶的標(biāo)準(zhǔn)模塊argparse
,這樣我們就省去了自己解析字符串的麻煩! 下面來看代碼:
#!/usr/bin/python3 # -*- coding: utf-8 -*- from socket import * import threading import argparse lock = threading.Lock() openNum = 0 threads = [] def portScanner(host,port): global openNum try: s = socket(AF_INET,SOCK_STREAM) s.connect((host,port)) lock.acquire() openNum+=1 print('[+] %d open' % port) lock.release() s.close() except: pass def main(): p = argparse.ArgumentParser(description='Port scanner!.') p.add_argument('-H', dest='hosts', type=str) args = p.parse_args() hostList = args.hosts.split(',') setdefaulttimeout(1) for host in hostList: print('Scanning the host:%s......' % (host)) for p in range(1,1024): t = threading.Thread(target=portScanner,args=(host,p)) threads.append(t) t.start() for t in threads: t.join() print('[*] The host:%s scan is complete!' % (host)) print('[*] A total of %d open port ' % (openNum)) if __name__ == '__main__': main()
看一下運(yùn)行效果,如下圖:
至此我們的端口掃描器就基本完成了,雖然功能比較簡(jiǎn)單,旨在表達(dá)端口掃描器的基本實(shí)現(xiàn)思路! 至于更詳細(xì)的功能可以基于這個(gè)基本結(jié)構(gòu)來逐步完善!
小結(jié)
本節(jié)主要講解了Python3實(shí)現(xiàn)一個(gè)簡(jiǎn)單的端口掃描器的過程,本次實(shí)驗(yàn)采用了Tcp全連接的方式,不斷嘗試連接主機(jī)的端口來判斷端口的開放情況,雖然存在一些缺點(diǎn), 不過這種方式最適合初學(xué)者學(xué)習(xí),至于更復(fù)雜的方式以后學(xué)習(xí)起來也不會(huì)很難。想舉一反三的朋友可以根據(jù)協(xié)議和端口的對(duì)照關(guān)系來完成掃描時(shí)同時(shí)輸出協(xié)議, 這樣看起來會(huì)更好一些,至于更詳細(xì)的功能就留給大家做練習(xí)了!
相關(guān)文章
關(guān)于安裝halcon包pycharm提示不全的問題
很多小伙伴給小編反映在pycham上面安裝halcon對(duì)應(yīng)的安裝包之后,導(dǎo)入出現(xiàn)問題,發(fā)現(xiàn)輸入ha.read 沒有自動(dòng)提示 ,只有幾個(gè)變量和方法,怎么解決這個(gè)問題呢,下面小編給大家?guī)砹税惭bhalcon包pycharm提示不全的問題,一起看看吧2021-06-06在python的類中動(dòng)態(tài)添加屬性與生成對(duì)象
這篇文章給大家介紹了如何在python的類中動(dòng)態(tài)添加屬性和生成對(duì)象,文中通過幾個(gè)方面來進(jìn)行介紹,對(duì)這感興趣的朋友們可以學(xué)習(xí)學(xué)習(xí)。2016-09-09Python?ArcPy實(shí)現(xiàn)批量計(jì)算多時(shí)相遙感影像的各項(xiàng)元平均值
這篇文章主要為大家詳細(xì)介紹了如何基于Python中ArcPy模塊,實(shí)現(xiàn)對(duì)大量長(zhǎng)時(shí)間序列柵格遙感影像文件的每一個(gè)像元進(jìn)行多時(shí)序平均值的求取,感興趣的可以了解一下2023-04-04Python實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)與算法之隊(duì)列詳解
這篇文章主要介紹了Python實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)與算法之隊(duì)列,詳細(xì)分析了隊(duì)列的定義、功能與Python實(shí)現(xiàn)隊(duì)列的相關(guān)技巧,以及具體的用法,需要的朋友可以參考下2015-04-04Django實(shí)現(xiàn)簡(jiǎn)單登錄的示例代碼
本文主要介紹了Django實(shí)現(xiàn)簡(jiǎn)單登錄的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11Python數(shù)據(jù)分析之?Pandas?Dataframe應(yīng)用自定義
這篇文章主要介紹了Python數(shù)據(jù)分析之?Pandas?Dataframe應(yīng)用自定義,文章基于python的相關(guān)資料展開?Pandas?Dataframe應(yīng)用自定義的詳細(xì)內(nèi)容,需要的小伙伴可以參考一下2022-05-05python使用 HTMLTestRunner.py生成測(cè)試報(bào)告
這篇文章主要介紹了python使用 HTMLTestRunner.py生成測(cè)試報(bào)告 ,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10