国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > Python > 正文

巧用python和libnmapd,提取Nmap掃描結(jié)果

2019-11-25 16:36:20
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

每當(dāng)我進(jìn)行內(nèi)網(wǎng)滲透面對(duì)大量主機(jī)和服務(wù)時(shí),我總是習(xí)慣使用自動(dòng)化的方式從 nmap 掃描結(jié)果中提取信息。這樣有利于自動(dòng)化檢測(cè)不同類(lèi)型的服務(wù),例如對(duì) web 服務(wù)進(jìn)行路徑爆破,測(cè)試 SSL/TLS 服務(wù)使用的密鑰或協(xié)議,以及其他有針對(duì)性的測(cè)試。
我在滲透測(cè)試中也會(huì)經(jīng)常使用到 IPthon 或 *nix shell,而這些又都能夠通過(guò) Python 來(lái)訪問(wèn),無(wú)論是直接在腳本中使用、在 REPL 環(huán)境下使用,還是將代碼寫(xiě)入到磁盤(pán)上然后通過(guò) shell 命令訪問(wèn)都是非常好用的。


為了完成這些,libnmap 庫(kù)會(huì)提供很好的幫助。本文將會(huì)講述一系列如何使用一行代碼解析 nmap 掃描結(jié)果,其中會(huì)在 Python 環(huán)境中使用到 libnmap 里的 NmapParser 庫(kù),這個(gè)庫(kù)可以很容易的幫助我們解析 nmap 的掃描結(jié)果。
我希望本文不僅僅是提供給你可以直接復(fù)制粘貼的代碼,還可以了解到 IPython 也是滲透測(cè)試時(shí)一個(gè)非常好用的數(shù)據(jù)處理工具。


配置
解析 nmap 掃描結(jié)果的第一步是你要進(jìn)行一次 nmap 掃描。我不打算在這里關(guān)注過(guò)多的細(xì)節(jié)部分,但是你想要直接使用本文的代碼,你需要將掃描結(jié)構(gòu)保存到一個(gè) xml 文件中(-oX 或者 -oA)并且在開(kāi)放端口上執(zhí)行了服務(wù)偵測(cè)(-sV)和運(yùn)行相關(guān)腳本(-sC)。
本文的命令假設(shè)你在一個(gè) Python REPL 環(huán)境如 IPython 并且安裝 libnmap 模塊(可以使用easy_install 或 pip 安裝)的環(huán)境下執(zhí)行。
開(kāi)始前,你需要設(shè)置下相應(yīng)的環(huán)境,首先導(dǎo)入 NmapParser 模塊并讀入你的 xml 掃描結(jié)果文件(實(shí)例中名為”up_hosts_all_ports_fullscan.xml”位于當(dāng)前工作目錄下)
 

復(fù)制代碼 代碼如下:
from libnmap.parser import NmapParser
nmap_report = NmapParser.parse_fromfile('up_hosts_all_ports_fullscan.xml')

本文的余下部分會(huì)包含一系列使用一行代碼提取各種各樣有用的信息。全部的示例都假設(shè) nmap 掃描結(jié)果保存在一個(gè)如上所示的文件中。下面的會(huì)給出一些基本的示例代碼,如果你想在 IPython 中直接運(yùn)行它們,請(qǐng)先運(yùn)行上面的代碼,這樣它會(huì)直接在控制臺(tái)輸出方便你的查看。我通常會(huì)先做好這一步,這樣我就可以確保輸出的數(shù)據(jù)跟預(yù)期的一樣。
然后,你可以選擇一個(gè)變量名并使用 “=” 將數(shù)據(jù)賦值給這個(gè)變量,這樣你就可以在隨后的代碼中直接調(diào)用,或者將其寫(xiě)入到磁盤(pán)上以便 shell 命令使用。如果有些東西你想使用多次,可以粘貼一些代碼段到 Python 腳本中,或者想加入一些更加復(fù)雜的邏輯但這樣可能會(huì)使 REPL 環(huán)境難以處理,我會(huì)在最后一節(jié)中講述如何快速的執(zhí)行這些操作。

端口信息
開(kāi)放指定端口號(hào)的主機(jī)
顯示所有開(kāi)放指定端口號(hào)的主機(jī)。生成一個(gè)包含主機(jī)地址(string)的列表。下面以 443 端口為例,你可以修改成你自己需要的值。
 

復(fù)制代碼 代碼如下:

 [ a.address for a in nmap_report.hosts if (a.get_open_ports()) and 443 in [b[0] for b in a.get_open_ports()] ]
 

開(kāi)放端口數(shù)量

顯示一系列主機(jī)開(kāi)放端口的數(shù)量。生成一個(gè)包含端口數(shù)量(int)的列表,并進(jìn)行排序。
 

復(fù)制代碼 代碼如下:

 sorted(set([ b[0] for a in nmap_report.hosts for b in a.get_open_ports()]), key=int)
 

主機(jī)開(kāi)放端口對(duì)應(yīng)的服務(wù),按端口號(hào)進(jìn)行分組

顯示所有主機(jī)開(kāi)放的端口號(hào),按端口號(hào)進(jìn)行分組和排序。生成一個(gè)包含多個(gè)列表的列表(即列表的每個(gè)元素也為列表),其中每個(gè)成員列表第一個(gè)元素為端口號(hào)(int),第二個(gè)元素為一個(gè)包含開(kāi)放對(duì)應(yīng)端口主機(jī) IP 地址(string)的列表。

復(fù)制代碼 代碼如下:

 [ [a, [ b.address for b in nmap_report.hosts for c in b.get_open_ports() if a==c[0] ] ] for a in sorted(set([ b[0] for a in nmap_report.hosts for b in a.get_open_ports()]),key=int) ]
SSL/TLS 和 HTTP/HTTPS

使用 SSL 的主機(jī)和端口

顯示所有使用 SSL 的主機(jī)和端口。這是通過(guò)查找是否有服務(wù)使用了 “SSL” 通道或者相關(guān)腳本檢測(cè)的結(jié)果中包含 pem 證書(shū)。生成一個(gè)包含一系列列表的列表,每個(gè)成員列表中包含主機(jī)地址(string)和端口號(hào)(int)。
 

復(fù)制代碼 代碼如下:

 [ [a.address, b.port] for a in nmap_report.hosts for b in a.services if b.tunnel=='ssl' or "'pem'" in str(b.scripts_results) ]

下面的內(nèi)容包含上述相同的信息,但不在是一個(gè)包含列表的列表,而是使用 join 函數(shù)創(chuàng)建了一個(gè)包含 “主機(jī):端口號(hào)”(string) 的列表。
 

復(fù)制代碼 代碼如下:

 [ ':'.join([a.address, str(b.port)]) for a in nmap_report.hosts for b in a.services if b.tunnel=='ssl' or "'pem'" in str(b.scripts_results) ]

包含 web 服務(wù)的主機(jī)和端口

顯示所有的 web 服務(wù)及其對(duì)對(duì)應(yīng)的端口號(hào)和協(xié)議(http 或 https)。這會(huì)生成一個(gè)包含多個(gè)列表的列表,其中每個(gè)成員列表包含協(xié)議(string)、地址(string)和端口號(hào)(int)。但這里會(huì)有些問(wèn)題,nmap 在報(bào)告使用 https 的網(wǎng)站時(shí),有些時(shí)候會(huì)顯示服務(wù)是 “https”,而有時(shí)則會(huì)顯示為使用 “ssl” 通道的 “http”,所以我調(diào)整了下數(shù)據(jù)格式以便統(tǒng)一輸出。
 

復(fù)制代碼 代碼如下:

 [ [(b.service + b.tunnel).replace('sl',''), a.address, b.port] for a in nmap_report.hosts for b in a.services if b.open() and b.service.startswith('http') ]

這里還是相同的信息,只不過(guò)是在原先包含協(xié)議、主機(jī)和端口號(hào)的列表中增加了url(string)。

復(fù)制代碼 代碼如下:

 [ (b.service + b.tunnel).replace('sl','') + '://' + a.address + ':' + str(b.port) + '/' for a in nmap_report.hosts for b in a.services if b.open() and b.service.startswith('http') ]

其他服務(wù)信息
未知服務(wù)

顯示所有 nmap 無(wú)法識(shí)別的服務(wù)。生成一個(gè)包含多個(gè)列表的列表,其中每個(gè)成員列表包含地址(string)、端口號(hào)(int)和 nmap 掃描的端口指紋(string)。生成這些信息,主要是為了方便后續(xù)人工審查那些特定的服務(wù),而不會(huì)參與到任何自動(dòng)化的過(guò)程中。

復(fù)制代碼 代碼如下:

 [ [ a.address, b.port, b.servicefp ] for a in nmap_report.hosts for b in a.services if (b.service =='unknown' or b.servicefp) and b.port in [c[0] for c in a.get_open_ports()] ]

nmap 識(shí)別出的軟件
顯示 nmap 掃描中識(shí)別出的所有軟件。生成按產(chǎn)品字母排序的列表。

復(fù)制代碼 代碼如下:

 sorted(set([ b.banner for a in nmap_report.hosts for b in a.services if 'product' in b.banner]))

軟件對(duì)應(yīng)的主機(jī)和端口號(hào),按產(chǎn)品分組
顯示掃描出軟件對(duì)應(yīng)的主機(jī)和端口,按產(chǎn)品分組。生成一個(gè)包含多個(gè)列表的列表,其中每個(gè)成員列表的第一個(gè)元素為軟件的名稱(chēng)(string),隨后是另一個(gè)列表包含地址(string)和端口號(hào)(int)。

復(fù)制代碼 代碼如下:

 [ [ a, [ [b.address, c.port] for b in nmap_report.hosts for c in b.services if c.banner==a] ] for a in sorted(set([ b.banner for a in nmap_report.hosts for b in a.services if 'product' in b.banner])) ]

同上相同的信息,只是輸出略有不同。同樣還是生成一個(gè)包含多個(gè)列表的列表,成員列表的第一個(gè)元素還是軟件的名稱(chēng)(string),但第二個(gè)是一個(gè)包含 “主機(jī):端口號(hào)” 的列表。

復(fù)制代碼 代碼如下:

 [ [ a, [ ':'.join([b.address, str(c.port)]) for b in nmap_report.hosts for c in b.services if c.banner==a] ] for a in sorted(set([ b.banner for a in nmap_report.hosts for b in a.services if 'product' in b.banner])) ]

搜索指定關(guān)鍵詞相關(guān)的主機(jī)和端口
顯示所有與給定關(guān)鍵詞相關(guān)聯(lián)的主機(jī)和端口,從 nmap 掃描結(jié)果的原始文本中查找包含產(chǎn)品名稱(chēng)、服務(wù)名稱(chēng)等等。下面以 “Oracle” 為例。生成一個(gè)包含多個(gè)列表的列表,其中每個(gè)成員列表包含主機(jī)地址(string)和端口號(hào)(int)。

復(fù)制代碼 代碼如下:

 [ [a.address, b.port] for a in nmap_report.hosts for b in a.services if b.open() and 'Oracle' in str(b.get_dict()) + str(b.scripts_results) ]

 
同上一樣的方法,只是將存儲(chǔ)的信息修改后一律使用小寫(xiě)進(jìn)行搜索(下面示例為小寫(xiě)的 “oracle”),輸出格式還是跟上面一樣。
復(fù)制代碼 代碼如下:

 [ [a.address, b.port] for a in nmap_report.hosts for b in a.services if b.open() and 'oracle' in (str(b.get_dict()) + str(b.scripts_results)).lower() ]

 
其他的事情

相同的證書(shū)名稱(chēng)
顯示找到的 SSL 證書(shū)和使用 nmap 腳本解析后得到證書(shū)名稱(chēng)相同的部分。這樣在當(dāng)你從一個(gè) IP 地址開(kāi)始掃描且反向 DNS 失效的時(shí)候,可以幫助確定系統(tǒng)的主機(jī)名。生成一個(gè)包含多個(gè)列表的列表,其中每個(gè)成員列表包含 IP 地址(string)和提取出的主機(jī)名(string)。
 

復(fù)制代碼 代碼如下:

 [ [a.address, c['elements']['subject']['commonName'] ] for a in nmap_report.hosts for b in a.services for c in b.scripts_results if c.has_key('elements') and c['elements'].has_key('subject') ]

處理以上結(jié)果的方法

正向前面所說(shuō),上述的例子,當(dāng)你直接粘貼進(jìn) IPython REPL 時(shí)只是將輸出打印在屏幕上。這的確不錯(cuò),因?yàn)檫@樣你可以隨時(shí)查看到自己感興趣的信息,但你可能還會(huì)想做更多的事情。之所以去生成上述信息,一大好處就在于你可以根據(jù)結(jié)果輕松執(zhí)行一些自動(dòng)化的操作。
如果你已經(jīng)很熟悉 Python,應(yīng)當(dāng)可以很容易完成這些工作,那么你可以跳過(guò)這一節(jié)。但如果你不熟悉,那么本節(jié)會(huì)講述一些很基本的知識(shí),告訴你如何使用上述的代碼段。

保存到磁盤(pán)
如果你想將上述代碼段的輸出結(jié)果保存到磁盤(pán)上的文本文件中,你需要將輸出的列表轉(zhuǎn)換為適當(dāng)?shù)淖址袷?具體取決于你的需求),然后在將這個(gè)字符串寫(xiě)入文件。在 Python 中,你可以使用 join 函數(shù)來(lái)整合這些列表并將其寫(xiě)入文件,這里只是一個(gè)示例。
我們想要從生成的列表中提取出支持 SSL 的主機(jī)和端口,并將它們保存到一個(gè)新的文件中,這樣可以在 bash 中使用循環(huán)來(lái)完成并使用命令行工具來(lái)進(jìn)行測(cè)試。
我通常會(huì)在 IPython 中使用一行代碼來(lái)完成這些,雖然一行代碼會(huì)比較方便,但這里為了方便閱讀和理解,我會(huì)將代碼拆分出來(lái)說(shuō)。
讓我們來(lái)解析之前生成了一個(gè)包含 “主機(jī):端口” 的列表,請(qǐng)注意我們使用了 str 函數(shù)將端口號(hào)從整數(shù)類(lèi)型裝換為了字符類(lèi)型,這樣使得它也能夠使用 join 函數(shù)與其他字符串拼接在一起。
 

復(fù)制代碼 代碼如下:

 [ ':'.join([a.address, str(b.port)]) for a in nmap_report.hosts for b in a.services if b.tunnel=='ssl' or "'pem'" in str(b.scripts_results) ]

讓我們來(lái)給上面這段代碼的結(jié)果分配名為 “ssl_services” 變量,以方便后續(xù)的調(diào)用。
 

復(fù)制代碼 代碼如下:

 ssl_services = [ ':'.join([a.address, str(b.port)]) for a in nmap_report.hosts for b in a.services if b.tunnel=='ssl' or "'pem'" in str(b.scripts_results) ]

現(xiàn)在,讓我們來(lái)使用 join 函數(shù)將列表的每一個(gè)元素拼接起來(lái)并使用 (‘/n') 進(jìn)行換行,然后給它分配一個(gè)名為 “ssl_services_text” 的變量。

復(fù)制代碼 代碼如下:

 ssl_services_text = '/n'.join(ssl_services)

隨后,我們就可以在當(dāng)前工作目錄下創(chuàng)建一個(gè)名為 “ssl_services_file.txt” 的新文建,并將 “ssl_services_text” 變量的內(nèi)容寫(xiě)入其中。
 

復(fù)制代碼 代碼如下:

 open('ssl_services_file.txt','w').write(ssl_services_text)

就這么簡(jiǎn)單,后續(xù)你可以根據(jù)自己的需要來(lái)使用文件內(nèi)容了。

使用其他 Python 代碼
也許你還會(huì)想用其他的 Python 代碼來(lái)完成上述工作?同樣很簡(jiǎn)單,下面就是另一個(gè)示例,這里我們遍歷每一個(gè) nmap 識(shí)別出的 web 服務(wù)及其網(wǎng)頁(yè)的請(qǐng)求結(jié)果。
下面會(huì)生成一個(gè)包含 URLs 的列表,我們分配一個(gè)名為 “urls” 的變量給它。
 

復(fù)制代碼 代碼如下:

 urls = [ (b.service + b.tunnel).replace('sl','') + '://' + a.address + ':' + str(b.port) + '/' for a in nmap_report.hosts for b in a.services if b.open() and b.service.startswith('http') ]

下一步,我們先進(jìn)行一些準(zhǔn)備工作,導(dǎo)入 requests 模塊,然后設(shè)置一個(gè)簡(jiǎn)單的 getAndSave 函數(shù)進(jìn)行 web 請(qǐng)求并將返回結(jié)果保存到磁盤(pán)上,文件名按 url 自動(dòng)生成。你可能會(huì)注意到下面代碼中,在 get 請(qǐng)求中使用了 “verify=False” 選項(xiàng),這會(huì)在發(fā)送請(qǐng)求時(shí)忽略證書(shū)驗(yàn)證的錯(cuò)誤,這個(gè)選項(xiàng)經(jīng)常在測(cè)試內(nèi)部機(jī)器時(shí)使用,因?yàn)閮?nèi)部機(jī)器基本不會(huì)有可信的證書(shū)頒發(fā)機(jī)構(gòu)頒發(fā)的 SSL 證書(shū)。
 

復(fù)制代碼 代碼如下:

 import requests
def getAndSave(url):
r = requests.get(url, verify=False)
open('_'.join(url.split('/')[2:]).replace(':',''),'wb').write(r.text.encode('utf8'))

現(xiàn)在,讓我們?cè)黾右恍┐a來(lái)遍歷每一個(gè) url,請(qǐng)求每個(gè)站點(diǎn)的 robots.txt 文件,并將其保存到本地以供后續(xù)使用。
 

復(fù)制代碼 代碼如下:

 for a in urls:
getAndSave(a + 'robots.txt')

這樣就會(huì)將每一個(gè)站點(diǎn)的 robots.txt 文件爬取到當(dāng)前工作目錄下。這只是一個(gè)很簡(jiǎn)單的例子。

總結(jié)

希望你在閱讀完本文后,可以自己靈活的使用 Python 解析 nmap 掃描結(jié)果。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 洪雅县| 类乌齐县| 钟祥市| 耒阳市| 浪卡子县| 贵港市| 齐齐哈尔市| 林甸县| 安康市| 封丘县| 醴陵市| 宣恩县| 璧山县| 石楼县| 贵定县| 光山县| 徐州市| 故城县| 兴文县| 泉州市| 交口县| 建德市| 新闻| 仙游县| 托克逊县| 祁东县| 贵州省| 林西县| 本溪市| 阳泉市| 玛纳斯县| 斗六市| 射洪县| 黔江区| 洞口县| 阳泉市| 巨野县| 瓦房店市| 乐平市| 晋城| 凤台县|