利於python指令碼編寫視覺化nmap和masscan的方法
介紹
我編寫了一個快速且帶有斑點的python指令碼,以視覺化nmap和masscan的結果。它通過解析來自掃描的XML日誌並生成所掃描IP範圍的直觀表示來工作。以下螢幕截圖是輸出示例:
由於缺少更好的詞,我將從現在開始將輸出稱為地圖。每個主機由一個彩色正方形表示。覆蓋地圖大部分內容的淺藍色方塊表示主機處於離線狀態(或僅未響應masscan的SYN。)其他彩色方塊表示處於聯機狀態且具有開放埠的主機。正方形的顏色從藍色到紅色。正方形越紅,表示主機上開啟的埠越多。將滑鼠懸停在每個方塊上,將在工具提示中顯示IP地址和開啟的埠。
該工具非常有用,因為它使您可以大致瞭解IP範圍,而不必在日誌檔案中拖網。它使您可以輕鬆檢視掃描中的主機塊。該工具可以從github下載,但是我將在下面描述程式碼的工作方式。
如何使用
首先,我要說這段程式碼沒有經過優化。我已經針對/ 21的日誌運行了程式碼,並花費了大約40秒鐘來生成輸出對映。
第一步是查詢執行掃描的IP地址範圍。由於掃描命令未儲存在日誌檔案中,因此這真是一個痛苦。因此,我們必須根據最低和最高IP結果來計算範圍。我們從掃描中解析XML檔案,並將掃描到的每個IP地址附加到名為ipList的列表中
ipList = [] for event,element in etree.iterparse('output.xml',tag="host"): for child in element: if child.tag == 'address': ipList.append(child.attrib['addr'])
然後,我們遍歷ipList並將每個八位位組分成單獨的列表,分別稱為firstOctetRange,secondOctetRange,thirdOctetRang和forwardOctetRange。
firstOctetRange = [] secondOctetRange = [] thirdOctetRange = [] forthOctetRange = [] bitDelimeter = 0 startingIP = 0 endingIP = 0 for ip in ipList: binaryOctet = '' octets = ip.split('.') firstOctetRange.append(int(octets[0])) secondOctetRange.append(int(octets[1])) thirdOctetRange.append(int(octets[2])) forthOctetRange.append(int(octets[3]))
然後,我們將每個結果的每個八位位組與另一個結果的相同八位位組進行比較,以確定值發生變化的八位位組。例如。如果前兩個八位位組始終相同。我們知道掃描的CIDR表示法將大於/ 16。我使用了變數bitDelimeter來儲存CIDR表示法擷取的八位位元組的值。
if min(firstOctetRange) != max(firstOctetRange): bitDelimeter = 0 elif min(secondOctetRange) != max(secondOctetRange): bitDelimeter = 1 elif min(thirdOctetRange) != max(thirdOctetRange): bitDelimeter = 2 elif min(forthOctetRange) != max(forthOctetRange): bitDelimeter = 3
掃描的IP地址範圍被新增到稱為parsedServers的有序字典中。ip地址是使用一系列4個巢狀的FOR迴圈生成的,每個迴圈在0 – 256範圍內迴圈。此範圍開始的八位位組取決於bitDelimeter。例如。如果掃描了IP地址範圍192.168.10.0/24。位定界符將為3,指示最後一個八位位組是更改其值的八位位組。因此,用於生成要放入parsedServers的IP地址的迴圈將固定前三個八位位元組,並僅對最後一個八位位元組迴圈範圍為0 – 256。如果我們掃描/ 21,則位定界符將為2,因此生成IP地址的迴圈將固定前兩個八位位組。將根據掃描的最小第三八位位元組值和掃描的最大第三八位位元組值的範圍生成第三八位位元組。第四個八位位組的範圍是0 – 256。
if bitDelimeter == 0: for one in range(min(firstOctetRange),max(firstOctetRange) + 1): for two in range(0,256): for three in range(0,256): for four in range(0,256): ip = "%d.%d.%d.%d" % (one,two,three,four) parsedServers[ip] = [] if bitDelimeter == 1: one = min(firstOctetRange) for two in range(min(secondOctetRange),max(secondOctetRange) + 1): for three in range(0,256): for four in range(0,256): ip = "%d.%d.%d.%d" % (one,four) parsedServers[ip] = [] if bitDelimeter == 2: one = min(firstOctetRange) two = min(secondOctetRange) for three in range(min(thirdOctetRange),max(thirdOctetRange) + 1): for four in range(0,256): ip = "%d.%d.%d.%d" % (one,four) parsedServers[ip] = [] if bitDelimeter == 3: one = min(firstOctetRange) two = min(secondOctetRange) three = min(thirdOctetRange) for four in range(min(forthOctetRange),max(forthOctetRange) + 1): ip = "%d.%d.%d.%d" % (one,four) parsedServers[ip] = []
現在,我們有一個parsedServer排序的dict,其中包含我們掃描範圍內的所有IP地址。下一步是將掃描中找到的開啟埠新增到parsedServer字典中。
for event,tag="host"): for child in element: if child.tag == 'address': ipAddress = child.attrib['addr'] if child.tag == 'ports': for subChild in child: port = [subChild.attrib['portid']] parsedServers[ipAddress].append(port)
現在,我們需要生成一個HTML頁面,可用於視覺化結果。這是使用Flask完成的。我們遍歷包含所有資料的pasedServers字典。建立一個infoString,其中包含當前迭代的IP地址和埠。當游標懸停在地圖上的正方形上時,將在工具提示中使用此功能。建立htmlBuffer並將其附加到parsedServers字典的每次迭代中。每次迭代都會新增HTML程式碼,以使用從colourRange列表中提取的顏色新增新的表格資料單元。範圍中總地址的平方根表示何時需要在表中新增新行。這樣可以使結果在頁面上顯示為正方形。
count = 0 htmlBuffer = Markup('') for key,value in parsedServers.items(): infoString = str(key) + '<br>' if value: infoString += 'Ports:' for portValue in value: infoString += str(portValue) + ',' colourRange = ['94A5FF','0024E5','2422C5','4821A6','6D1F87','911E67','B61C48','DA1B29','FF1A0A'] htmlBuffer += Markup('<td class="tooltip",bgcolor="' + colourRange[len(value)] + '"><span class="tooltiptext">' + infoString + '</span></td>')<br> count += 1<br> if count > math.sqrt(len(parsedServers)):<br> htmlBuffer += Markup('</tr><tr>') count = 0
例如。我們正在parsedServers中進行迭代,地址為192.168.10.22,並且打開了3個埠。將使用工具提示中列出的IP地址和埠建立一個表格資料單元。單元格的背景顏色將從包含9個十六進位制顏色程式碼的colourRange列表中提取。列表上的索引越高,顏色越紅色。在此示例中,IP地址有3個開放的埠。因此,第三個索引中的顏色將設定為背景色,從而使資料單元格變為紫色。
最後,我們將模板傳遞給htmlBuffer。然後執行Web伺服器。通過瀏覽至127.0.0.1:5000,可以找到輸出。
@app.route('/') def index(): return render_template('index.html',name=htmlBuffer) if __name__ == '__main__': app.run()
到此這篇關於利於python指令碼編寫視覺化nmap和masscan的文章就介紹到這了,更多相關python編寫視覺化nmap和masscan內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!