大綱
主要紀錄一下這兩點的開發過程,而這個案子雖然還用到了爬蟲抓取中文翻譯的資料,並且使用了 pandas 來實現 xlsx 的轉換,但因為沒什麼特別的地方,都是很基礎的語法功能而已,這邊就不紀錄了。
- 讀取 .nessus 檔案(解析 XML 的過程)
- Command Line 功能(python argparse module 的使用)
讀取 .nessus 檔案
使用第三方函示庫 nessus_file_reader
,來讀取 .nessus 檔案。使用到的程式碼如下
import nessus_file_reader as nfr
root = nfr.file.nessus_scan_file_root_element(filename) # 讀入檔案
for case_index, report_host in enumerate(nfr.scan.report_hosts(root)):
report_items_per_host = nfr.host.report_items(report_host)
for index, report_item in enumerate(report_items_per_host):
__risk_factor = nfr.plugin.report_item_value(report_item, 'risk_factor')
__plugin_id = nfr.plugin.report_item_value(report_item, 'pluginID')
這個套件的解析過程會把 .nessus 當作 XML 來分析,先找出這份 XML 的 root 之後,尋找所有的 ReportHost
,這是每一組 ip 的報告結果,接者再從這些報告結果中找出 ReportItem
一筆一筆分析
了解 nessus_file_reader
是如何解析 XML,就換我用 ElementTree
寫一個。
import xml.etree.ElementTree as ET
filename = ""
def main():
tree = ET.parse(filename)
root = tree.getroot() # 找出 XML 檔案的 root
hosts = root.find("Report").findall("ReportHost") # 找出所有的 ReportHost
report_item_name = "risk_factor"
for report_host in hosts:
reports = report_host.findall("ReportItem") # 從每個 ReportHost 找出所有的 ReportItem
for report_item in reports:
report_item_content_value = report_item.get(report_item_name)
if report_item_content_value is None:
report_item_content = report_item.find(report_item_name)
if report_item_content is not None:
report_item_content_value = report_item_content.text
需要注意的是,在找 report_item_name
的 tag,可能會遇到多層的巢狀結構,所以如果用 get()
的返回值為 None
,也就是 tag 的 attribute 沒有 report_item_name
,此時就需要用 find()
往內尋找
自訂義 Command Line
這是我第一次挑戰寫 CLI 的工具,直接使用內建的 argparse
來建立指令,一開始需要先宣告 parser
parser = argparse.ArgumentParser(description='CLI描述')
設置預設觸發 function
parser.set_defaults(handle=simple_transform)
參數功能
設置如下,其中 store_true
代表只要出現這個參數就設為 True,這樣就不用特地給將 True Value 打出來
parser.add_argument('-sl', '--show_all_level', action='store_true',
help='是否輸出 Critical level 之外等級的漏洞')
parser.add_argument('-info', '--info', action='store_true',
help='是否輸出 infomation')
parser.add_argument('-o', '--output', type=str, default=os.getcwd(),
help='輸出的位置')
群組功能
這個功能可以用來設置一定要輸入該群組中其中一個指令
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-f', '--file', type=str,
help='要轉換的 .nessus 檔案')
group.add_argument('-l', '--list', type=str,
help='轉換多個 .nessus 檔案')
子命令功能
如果要增加子命令,使用以下方法即可,subparsers
的用法就跟 parser
一樣
subparsers = parser.add_subparsers(metavar='子命令')
資料來源
comments powered by Disqus