-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathopenvas_py_cli.py
More file actions
186 lines (156 loc) · 7.92 KB
/
openvas_py_cli.py
File metadata and controls
186 lines (156 loc) · 7.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#! /usr/bin/python3
# # openvas_py_cli.py
# ###################################################
# # ___ __ __ ___ ___ ___ ___ _ _ #
# # / _ \| \/ | _ \__ _|_ ) | _ \_ _ / __| (_) #
# # | (_) | |\/| | _/\ V // / | _/ || | (__| | | #
# # \___/|_| |_|_| \_//___| |_| \_, |\___|_|_| #
# # |__/ #
# ###################################################
# # OpenVAS Python (3) CLI Manageer #
# # Project started 12/28/2016 #
# ###################################
## Static Variables:
ovpnUser = 'admin' #Your OpenVAS username
ovpnPass = '' #Your OpenVAS password
ovpnIP = '127.0.0.1' #OpenVAS IP (localhost)
ovpnPort = '9390' #OpenVAS port (9390 is default)
ovpnAuth = "omp -u " + ovpnUser + " -w " + ovpnPass + " -h " + ovpnIP + " -p " + ovpnPort
## Testing Variables:
outFilePath = '~/'
## Imports
import subprocess
import base64
from lxml import etree
from io import StringIO, BytesIO
## Functions
def runCommand(command):
cmd = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
cmdOutput = cmd.stdout.readlines()
#cmd.stdin.close()
cmd.wait()
return cmdOutput
def listXML(rootXML):
for i in range(0, len(rootXML)): #step through depth (max depth = len(rootXML))
print(rootXML[i].tag + " " + str(rootXML[i].attrib)) # print XML tag (should already be string) and print XML attribute(s) (attributes are in dictionary form)
def parseXML(cmdResult):
parser = etree.XMLParser()
for line in cmdResult:
parser.feed(((line.decode('utf-8').rstrip("\n\r")).strip()))
return parser.close()
def getReportFormats(): # Get OMP report formats (2.0 only) output is NOT XML
rptFormats = runCommand(ovpnAuth + " -F")
class ReportFormat(object):
def __init__(self, fmtname, fmtcode):
self.fmtname = fmtname
self.fmtcode = fmtcode
rptFormatsDict = {} # declare dict
rptFormatsTable = [] # declare list
for formats in rptFormats:
intrasplit = str(formats.decode('utf-8').rstrip("\n\r")).split(' ') # Create a list of fmt code and fmt name
rptFormatsTable.append(ReportFormat(intrasplit[1], intrasplit[0])) # Create table of ReportFormat classes
rptFormatsDict = dict([ (r.fmtname, r.fmtcode) for r in rptFormatsTable ]) # Create dict of format names and codes
return rptFormatsDict
def getTxtRpt(rptOnID):
rptFormatsDict = getReportFormats() # get OMP report formats
txt_fmtcode = str(rptFormatsDict.get("TXT")) # Save code for text format
commandStr = ovpnAuth + ' -i -X \'<get_reports report_id="' + rptOnID + '" format_id="' + txt_fmtcode + '"/>\''
XMLList_rootXML = parseXML(runCommand(commandStr))
for element in XMLList_rootXML:
if str(element.tag) == "report":
report_base64 = str(element.text)
return base64.b64decode(report_base64)
def getTargets():
cmdResult = runCommand(ovpnAuth + " -i -X '<get_targets/>'")
rootXML = parseXML(cmdResult) # get rootXML from cmdResult
parser = etree.XMLParser(ns_clean=True)
tree = etree.parse(StringIO((etree.tostring(rootXML)).decode('utf-8')), parser)
targetXML = tree.xpath('/get_targets_response/target/name')
target_names = []
for t in targetXML:
target_names.append(t.text)
return target_names
def getConfigs(): # return config formats as a dictionary
vasConfigs = runCommand(ovpnAuth + " -i -X '<get_configs/>'")
cfgsXML = parseXML(vasConfigs) # get root XML from vasConfigs
config_ids = []
for i in range(0, (len(cfgsXML))):
if cfgsXML[i].tag == "config":
config_ids.append(str(cfgsXML[i].attrib.get("id")))
config_names = []
for l in cfgsXML.xpath('/get_configs_response/config/name'):
config_names.append(str(l.text))
class ConfigFormat(object):
def __init__(self, fmtcode, fmtname):
self.fmtcode = fmtcode
self.fmtname = fmtname
cfgFormatsDict = {} # declare dict for Configs
cfgFormatsTable = [] # declare list for Configs
if len(config_ids) == len(config_names): # check to make sure that our list lengths match (need to find a better way to read XML element)
for i in range(0, (len(config_ids))):
cfgFormatsTable.append(ConfigFormat(config_ids[i], config_names[i])) # Create table of ConfigFormat classes
cfgFormatsDict = dict([ (c.fmtcode, c.fmtname) for c in cfgFormatsTable ]) # Create dict of config codes and names
return cfgFormatsDict
def getReports(): # Get OpenVAS reports, return dict
reportsXMLList = runCommand(ovpnAuth + " -i -X '<get_reports/>'")
reports_rootXML = parseXML(reportsXMLList)
parser = etree.XMLParser(ns_clean=True)
tree = etree.parse(StringIO((etree.tostring(reports_rootXML)).decode('utf-8')), parser)
report_ids = [] # declare report IDs list
for i in range(0, (len(reports_rootXML))):
if reports_rootXML[i].tag == "report":
report_ids.append(str(reports_rootXML[i].attrib.get("id")))
report_names = [] # declare report names list (these are not actually OpenVAS report names, these are the task names)
for taskName in tree.xpath('/get_reports_response/report/task/name'):
report_names.append(str(taskName.text))
class VASReports(object):
def __init__(self, rptid, rptname):
self.rptid = rptid
self.rptname = rptname
VASReportsDict = {} # declare dict for Reports
VASReportsTable = [] # declare list for Reports
if len(report_ids) == len(report_names):
for j in range(0, (len(report_ids))):
VASReportsTable.append(VASReports(report_ids[j], report_names[j]))
VASReportsDict = dict([ (r.rptid, r.rptname) for r in VASReportsTable ]) # Create dict of report codes and task names
return VASReportsDict
def reportsMenu(rptsDict):
class rptMenuItem(object):
def __init__(self, menuIndex, rptid, rptname):
self.menuIndex = menuIndex
self.rptid = rptid
self.rptname = rptname
menuCount = 1
menuList = [] # Menu list for rptMenuItem class objects
menuDict = {} # Menu dictionary for looking up report IDs
for k, v in rptsDict.items():
menuList.append(rptMenuItem(menuCount, k, v))
menuCount = menuCount + 1
menuDict = dict([ (m.menuIndex, m.rptid) for m in menuList ]) # Create dict of report codes and task names
for menuItem in menuList:
print("%s\t%s\t%s" % (menuItem.menuIndex, menuItem.rptid, menuItem.rptname))
choice = input("rpt# > ")
rptID = menuDict[int(choice)]
#rptID = menuList[int(choice)].rptid
return rptID
def readReport(rptsDict, rptID):
print("OpenVAS report for %s:" % (reportDict[rptID]))
decodedRpt = getTxtRpt(rptID) # decode report
print(decodedRpt.decode('utf-8'))
## Get OpenVAS targets
target_names = getTargets() # Array of target_names
## Get OpenVAS config
configDict = getConfigs() # Dictionary of config types
full_fast_config_id = list(configDict.keys())[list(configDict.values()).index("Full and fast")] # configID of Full and fast scan config
## Get OpenVAS reports
print("Choose OpenVAS report to read:")
reportDict = getReports() # get dict of report IDs and task names
rptID = reportsMenu(reportDict) # get report ID from user selection from reportDict
readReport(reportDict, rptID) # read the selected report
SaveRptYN = input("Do you want to save the report for %s [y/N]: " % (reportDict[rptID]))
if SaveRptYN[:1].lower() == "y":
#outFilePath = outFilePath + str(rptID) + ".txt" # Uses the report ID as the name of the file
outFilePath = outFilePath + str(reportDict[rptID]) + ".txt" # Uses the target name as the name of the file
outFile = open(outFilePath, 'w') # Open the output file with the 'w' write flag
#outFile = open(outFilePath, 'a') # Open the output file with the 'w' write flag
outFile.write(getTxtRpt(rptID).decode('utf-8')) # Write out the file as utf-8