gvm-tools 25.1.1__tar.gz → 25.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of gvm-tools might be problematic. Click here for more details.
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/PKG-INFO +1 -1
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/gvmtools/__version__.py +1 -1
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/gvmtools/parser.py +1 -2
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/pyproject.toml +1 -1
- gvm_tools-25.2.0/scripts/export-hosts-csv.gmp.py +180 -0
- gvm_tools-25.2.0/scripts/list-hosts.gmp.py +168 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/ssv_csv.py +6 -6
- gvm_tools-25.2.0/scripts/verify-scanners.gmp.py +53 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/LICENSE +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/README.md +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/gvmtools/__init__.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/gvmtools/cli.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/gvmtools/config.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/gvmtools/helper.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/gvmtools/pyshell.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/gvmtools/script.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/.pylintrc +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/README.md +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/application-detection.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/bulk-modify-schedules.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/certbund-report.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/cfg-gen-for-certs.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/check-gmp-gos22.04.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/check-gmp-gos24.10.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/clean-sensor.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/combine-reports.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/create-alerts-from-csv.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/create-consolidated-report.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/create-credentials-from-csv.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/create-cve-report-from-json.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/create-dummy-data.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/create-filters-from-csv.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/create-report-format-from-csv.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/create-schedules-from-csv.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/create-tags-from-csv.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/create-targets-from-csv.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/create-targets-from-host-list.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/create-tasks-from-csv.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/default_report_data.json +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/delete-overrides-by-filter.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/empty-trash.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/export-csv-report.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/export-pdf-report.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/export-xml-report.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/generate-random-reports.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/generate-random-targets.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/list-alerts.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/list-credentials.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/list-feeds.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/list-filters.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/list-groups.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/list-policies.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/list-portlists.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/list-report-formats.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/list-reports.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/list-roles.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/list-scan-configs.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/list-scanners.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/list-schedules.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/list-tags.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/list-targets.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/list-tasks.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/list-tickets.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/list-users.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/monthly-report-gos24.10.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/monthly-report-gos3.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/monthly-report-gos4.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/nvt-scan.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/requirements.txt +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/ruff.toml +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/scan-new-system.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/send-delta-emails.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/send-schedules.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/send-targets.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/send-tasks.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/start-alert-scan.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/start-multiple-alerts-scan.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/start-nvt-scan.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/start-scans-from-csv.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/stop-all-scans.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/stop-scans-from-csv.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/sync-hosts.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/scripts/update-task-target.gmp.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/__init__.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/root_help.3.10.snap +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/root_help.snap +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/scripts/__init__.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/scripts/example_schedules.xml +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/scripts/example_target.xml +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/scripts/example_task.xml +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/scripts/get_alerts.xml +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/scripts/get_scan_configs.xml +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/scripts/invalid_xml.xml +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/scripts/test_combine_reports.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/scripts/test_create_consolidated_report.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/scripts/test_list_tasks.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/scripts/test_send_schedules.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/scripts/test_send_targets.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/scripts/test_send_tasks.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/scripts/test_start_alert_scan.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/socket_help.3.10.snap +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/socket_help.snap +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/ssh_help.3.10.snap +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/ssh_help.snap +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/test.cfg +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/test_auth.cfg +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/test_config.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/test_helper.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/test_parser.py +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/tls_help.3.10.snap +0 -0
- {gvm_tools-25.1.1 → gvm_tools-25.2.0}/tests/tls_help.snap +0 -0
|
@@ -16,8 +16,7 @@
|
|
|
16
16
|
# You should have received a copy of the GNU General Public License
|
|
17
17
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
18
18
|
|
|
19
|
-
"""Command Line Interface Parser
|
|
20
|
-
"""
|
|
19
|
+
"""Command Line Interface Parser"""
|
|
21
20
|
|
|
22
21
|
import argparse
|
|
23
22
|
import logging
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2025 Martin Boller
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
#
|
|
5
|
+
# Loosely based on other greenbone scripts
|
|
6
|
+
#
|
|
7
|
+
# Run with: gvm-script --gmp-username admin-user --gmp-password password socket export-hosts-csv.gmp.py <csv file> days
|
|
8
|
+
# example: gvm-script --gmp-username admin --gmp-password top$ecret socket export-hosts-csv.gmp.py hosts.csv 2
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
import csv
|
|
12
|
+
import sys
|
|
13
|
+
from argparse import ArgumentParser, Namespace, RawTextHelpFormatter
|
|
14
|
+
from datetime import date, datetime, time, timedelta
|
|
15
|
+
|
|
16
|
+
from gvm.protocols.gmp import Gmp
|
|
17
|
+
from gvmtools.helper import error_and_exit
|
|
18
|
+
|
|
19
|
+
HELP_TEXT = (
|
|
20
|
+
"This script generates a csv file with hosts (assets) "
|
|
21
|
+
"from Greenbone Vulnerability Manager.\n\n"
|
|
22
|
+
"csv file will contain:\n"
|
|
23
|
+
"IP Address, Hostname, MAC Address, Operating System, last seen, and severity\n"
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def check_args(args: Namespace) -> None:
|
|
28
|
+
len_args = len(args.script) - 1
|
|
29
|
+
if len_args < 2:
|
|
30
|
+
message = """
|
|
31
|
+
This script requests all hosts <days> prior to today and exports it as a csv file.
|
|
32
|
+
It requires two parameter after the script name:
|
|
33
|
+
1. filename -- name of the csv file of the report
|
|
34
|
+
2. days -- number of days before and until today to pull hosts information from
|
|
35
|
+
|
|
36
|
+
Examples:
|
|
37
|
+
$ gvm-script --gmp-username username --gmp-password password socket export-hosts-csv.gmp.py <csv_file> <days>
|
|
38
|
+
$ gvm-script --gmp-username admin --gmp-password 0f6fa69b-32bb-453a-9aa4-b8c9e56b3d00 socket export-hosts-csv.gmp.py hosts.csv 4
|
|
39
|
+
"""
|
|
40
|
+
print(message)
|
|
41
|
+
sys.exit()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def parse_args(args: Namespace) -> Namespace: # pylint: disable=unused-argument
|
|
45
|
+
"""Parsing args ..."""
|
|
46
|
+
|
|
47
|
+
parser = ArgumentParser(
|
|
48
|
+
prefix_chars="+",
|
|
49
|
+
add_help=False,
|
|
50
|
+
formatter_class=RawTextHelpFormatter,
|
|
51
|
+
description=HELP_TEXT,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
parser.add_argument(
|
|
55
|
+
"+h",
|
|
56
|
+
"++help",
|
|
57
|
+
action="help",
|
|
58
|
+
help="Show this help message and exit.",
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
parser.add_argument(
|
|
62
|
+
"csv_filename",
|
|
63
|
+
type=str,
|
|
64
|
+
help=("CSV File containing credentials"),
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
parser.add_argument(
|
|
68
|
+
"delta_days",
|
|
69
|
+
type=int,
|
|
70
|
+
help=("Number of days in the past to pull hosts information"),
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
script_args, _ = parser.parse_known_args(args)
|
|
74
|
+
return script_args
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def list_hosts(
|
|
78
|
+
gmp: Gmp, from_date: date, to_date: date, csvfilename: str
|
|
79
|
+
) -> None:
|
|
80
|
+
host_filter = (
|
|
81
|
+
f"rows=-1 and modified>{from_date.isoformat()} "
|
|
82
|
+
f"and modified<{to_date.isoformat()}"
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
# Get the XML of hosts
|
|
86
|
+
hosts_xml = gmp.get_hosts(filter_string=host_filter)
|
|
87
|
+
host_info = []
|
|
88
|
+
|
|
89
|
+
for host in hosts_xml.xpath("asset"):
|
|
90
|
+
# ip will always be there
|
|
91
|
+
ip = host.xpath("name/text()")[0]
|
|
92
|
+
host_seendates = host.xpath("modification_time/text()")
|
|
93
|
+
host_lastseen = host_seendates[0]
|
|
94
|
+
|
|
95
|
+
# hostnames and other attributes may not be there
|
|
96
|
+
hostnames = host.xpath(
|
|
97
|
+
'identifiers/identifier/name[text()="hostname"]/../value/text()'
|
|
98
|
+
)
|
|
99
|
+
if len(hostnames) == 0:
|
|
100
|
+
hostname = ""
|
|
101
|
+
pass
|
|
102
|
+
else:
|
|
103
|
+
hostname = hostnames[0]
|
|
104
|
+
|
|
105
|
+
host_macs = host.xpath(
|
|
106
|
+
'identifiers/identifier/name[text()="MAC"]/../value/text()'
|
|
107
|
+
)
|
|
108
|
+
if len(host_macs) == 0:
|
|
109
|
+
host_mac = ""
|
|
110
|
+
pass
|
|
111
|
+
else:
|
|
112
|
+
host_mac = host_macs[0]
|
|
113
|
+
|
|
114
|
+
host_severity = host.xpath("host/severity/value/text()")
|
|
115
|
+
if len(host_severity) == 0:
|
|
116
|
+
host_severity = 0
|
|
117
|
+
pass
|
|
118
|
+
else:
|
|
119
|
+
host_severity = host_severity[0]
|
|
120
|
+
|
|
121
|
+
host_os = host.xpath(
|
|
122
|
+
'host/detail/name[text()="best_os_txt"]/../value/text()'
|
|
123
|
+
)
|
|
124
|
+
if len(host_os) == 0:
|
|
125
|
+
host_os = ""
|
|
126
|
+
pass
|
|
127
|
+
else:
|
|
128
|
+
host_os = host_os[0]
|
|
129
|
+
|
|
130
|
+
host_info.append(
|
|
131
|
+
[hostname, ip, host_mac, host_os, host_lastseen, host_severity]
|
|
132
|
+
)
|
|
133
|
+
# Write the list host_info to csv file
|
|
134
|
+
writecsv(csvfilename, host_info)
|
|
135
|
+
print(
|
|
136
|
+
f"CSV file: {csvfilename}\n"
|
|
137
|
+
f"From: {from_date}\n"
|
|
138
|
+
f"To: {to_date}\n"
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def writecsv(csv_filename, hostinfo: list) -> None:
|
|
143
|
+
field_names = [
|
|
144
|
+
"IP Address",
|
|
145
|
+
"Hostname",
|
|
146
|
+
"MAC Address",
|
|
147
|
+
"Operating System",
|
|
148
|
+
"Last Seen",
|
|
149
|
+
"CVSS",
|
|
150
|
+
]
|
|
151
|
+
try:
|
|
152
|
+
with open(csv_filename, "w") as csvfile:
|
|
153
|
+
writer = csv.writer(csvfile, delimiter=",", quoting=csv.QUOTE_ALL)
|
|
154
|
+
writer.writerow(field_names)
|
|
155
|
+
writer.writerows(hostinfo)
|
|
156
|
+
csvfile.close
|
|
157
|
+
except IOError as e:
|
|
158
|
+
error_and_exit(f"Failed to write csv file: {str(e)} (exit)")
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def main(gmp: Gmp, args: Namespace) -> None:
|
|
162
|
+
# pylint: disable=undefined-variable
|
|
163
|
+
# argv[0] contains the csv file name
|
|
164
|
+
check_args(args)
|
|
165
|
+
if args.script:
|
|
166
|
+
args = args.script[1:]
|
|
167
|
+
parsed_args = parse_args(args=args)
|
|
168
|
+
|
|
169
|
+
delta_days = parsed_args.delta_days
|
|
170
|
+
# simply getting yesterday from midnight to now
|
|
171
|
+
from_date = datetime.combine(datetime.today(), time.min) - timedelta(
|
|
172
|
+
days=delta_days
|
|
173
|
+
)
|
|
174
|
+
to_date = datetime.now()
|
|
175
|
+
# get the hosts
|
|
176
|
+
list_hosts(gmp, from_date, to_date, parsed_args.csv_filename)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
if __name__ == "__gmp__":
|
|
180
|
+
main(gmp, args)
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2025 Martin Boller
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
#
|
|
5
|
+
# Loosely based on other greenbone scripts
|
|
6
|
+
#
|
|
7
|
+
# Run with: gvm-script --gmp-username admin-user --gmp-password password socket list-hosts.gmp.py <days>
|
|
8
|
+
# example: gvm-script --gmp-username admin --gmp-password top$ecret socket list-hosts.gmp.py 2
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
import sys
|
|
12
|
+
from argparse import ArgumentParser, Namespace, RawTextHelpFormatter
|
|
13
|
+
from datetime import date, datetime, time, timedelta
|
|
14
|
+
|
|
15
|
+
from gvm.protocols.gmp import Gmp
|
|
16
|
+
from gvmtools.helper import Table
|
|
17
|
+
|
|
18
|
+
HELP_TEXT = (
|
|
19
|
+
"This script generates a table of hosts (assets) "
|
|
20
|
+
"from Greenbone Vulnerability Manager.\n\n"
|
|
21
|
+
"table will contain:\n"
|
|
22
|
+
"Hostname, IP Address, MAC Address, Operating System, last seen, and severity\n"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def check_args(args: Namespace) -> None:
|
|
27
|
+
len_args = len(args.script) - 1
|
|
28
|
+
if len_args < 1:
|
|
29
|
+
message = """
|
|
30
|
+
This script requests information about all hosts <days> days prior to today (included) and
|
|
31
|
+
displays it as a table. It requires one parameter after the script name:
|
|
32
|
+
1. days -- number of days prior to today to pull hosts information from
|
|
33
|
+
|
|
34
|
+
Examples:
|
|
35
|
+
$ gvm-script --gmp-username username --gmp-password password socket list-hosts.gmp.py <days>
|
|
36
|
+
$ gvm-script --gmp-username admin --gmp-password 0f6fa69b-32bb-453a-9aa4-b8c9e56b3d00 socket list-hosts.gmp.py 4
|
|
37
|
+
"""
|
|
38
|
+
print(message)
|
|
39
|
+
sys.exit()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def parse_args(args: Namespace) -> Namespace: # pylint: disable=unused-argument
|
|
43
|
+
"""Parsing args ..."""
|
|
44
|
+
|
|
45
|
+
parser = ArgumentParser(
|
|
46
|
+
prefix_chars="+",
|
|
47
|
+
add_help=False,
|
|
48
|
+
formatter_class=RawTextHelpFormatter,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
parser.add_argument(
|
|
52
|
+
"+h",
|
|
53
|
+
"++help",
|
|
54
|
+
action="help",
|
|
55
|
+
help="Show this help message and exit.",
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
parser.add_argument(
|
|
59
|
+
"delta_days",
|
|
60
|
+
type=int,
|
|
61
|
+
help=("Number of days in the past to pull hosts information"),
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
script_args, _ = parser.parse_known_args(args)
|
|
65
|
+
return script_args
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def list_hosts(gmp: Gmp, from_date: date, to_date: date) -> None:
|
|
69
|
+
host_filter = (
|
|
70
|
+
f"rows=-1 "
|
|
71
|
+
f"and modified>{from_date.isoformat()} "
|
|
72
|
+
f"and modified<{to_date.isoformat()}"
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# Get the XML of hosts
|
|
76
|
+
hosts_xml = gmp.get_hosts(filter_string=host_filter)
|
|
77
|
+
heading = [
|
|
78
|
+
"#",
|
|
79
|
+
"IP Address",
|
|
80
|
+
"Hostname",
|
|
81
|
+
"MAC Address",
|
|
82
|
+
"Operating System",
|
|
83
|
+
"Last Seen",
|
|
84
|
+
"CVSS",
|
|
85
|
+
]
|
|
86
|
+
rows = []
|
|
87
|
+
numberRows = 0
|
|
88
|
+
|
|
89
|
+
print("Listing hosts.\n" f"From: {from_date}\n" f"To: {to_date}\n")
|
|
90
|
+
|
|
91
|
+
for host in hosts_xml.xpath("asset"):
|
|
92
|
+
# ip will always be there
|
|
93
|
+
ip = host.xpath("name/text()")[0]
|
|
94
|
+
host_seendates = host.xpath("modification_time/text()")
|
|
95
|
+
host_lastseen = host_seendates[0]
|
|
96
|
+
|
|
97
|
+
# hostnames and other attributes may not be there
|
|
98
|
+
hostnames = host.xpath(
|
|
99
|
+
'identifiers/identifier/name[text()="hostname"]/../value/text()'
|
|
100
|
+
)
|
|
101
|
+
if len(hostnames) == 0:
|
|
102
|
+
hostname = ""
|
|
103
|
+
pass
|
|
104
|
+
else:
|
|
105
|
+
hostname = hostnames[0]
|
|
106
|
+
|
|
107
|
+
host_macs = host.xpath(
|
|
108
|
+
'identifiers/identifier/name[text()="MAC"]/../value/text()'
|
|
109
|
+
)
|
|
110
|
+
if len(host_macs) == 0:
|
|
111
|
+
host_mac = ""
|
|
112
|
+
pass
|
|
113
|
+
else:
|
|
114
|
+
host_mac = host_macs[0]
|
|
115
|
+
|
|
116
|
+
host_severity = host.xpath("host/severity/value/text()")
|
|
117
|
+
if len(host_severity) == 0:
|
|
118
|
+
host_severity = "0.0"
|
|
119
|
+
pass
|
|
120
|
+
else:
|
|
121
|
+
host_severity = host_severity[0]
|
|
122
|
+
|
|
123
|
+
host_os = host.xpath(
|
|
124
|
+
'host/detail/name[text()="best_os_txt"]/../value/text()'
|
|
125
|
+
)
|
|
126
|
+
if len(host_os) == 0:
|
|
127
|
+
host_os = ""
|
|
128
|
+
pass
|
|
129
|
+
else:
|
|
130
|
+
host_os = host_os[0]
|
|
131
|
+
# Count number of hosts
|
|
132
|
+
numberRows = numberRows + 1
|
|
133
|
+
# Cast/convert to text to show in list
|
|
134
|
+
rowNumber = str(numberRows)
|
|
135
|
+
rows.append(
|
|
136
|
+
[
|
|
137
|
+
rowNumber,
|
|
138
|
+
ip,
|
|
139
|
+
hostname,
|
|
140
|
+
host_mac,
|
|
141
|
+
host_os,
|
|
142
|
+
host_lastseen,
|
|
143
|
+
host_severity,
|
|
144
|
+
]
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
print(Table(heading=heading, rows=rows))
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def main(gmp: Gmp, args: Namespace) -> None:
|
|
151
|
+
# pylint: disable=undefined-variable
|
|
152
|
+
check_args(args)
|
|
153
|
+
if args.script:
|
|
154
|
+
args = args.script[1:]
|
|
155
|
+
parsed_args = parse_args(args=args)
|
|
156
|
+
delta_days = parsed_args.delta_days
|
|
157
|
+
# simply getting yesterday from midnight to today (now)
|
|
158
|
+
from_date = datetime.combine(datetime.today(), time.min) - timedelta(
|
|
159
|
+
days=delta_days
|
|
160
|
+
)
|
|
161
|
+
to_date = datetime.now()
|
|
162
|
+
# print(from_date, to_date)
|
|
163
|
+
|
|
164
|
+
list_hosts(gmp, from_date, to_date)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
if __name__ == "__gmp__":
|
|
168
|
+
main(gmp, args)
|
|
@@ -286,9 +286,9 @@ class SSVPrinter(CSVPrinter):
|
|
|
286
286
|
"""
|
|
287
287
|
|
|
288
288
|
def __init__(self) -> None:
|
|
289
|
-
CSVPrinter.__init__(self, sep="\
|
|
289
|
+
CSVPrinter.__init__(self, sep="\x1f", quot=None, eol="\n", qnl="\r")
|
|
290
290
|
# not permitted in SSV data
|
|
291
|
-
self._invf = re.compile("[\x00\
|
|
291
|
+
self._invf = re.compile("[\x00\x1f]")
|
|
292
292
|
|
|
293
293
|
|
|
294
294
|
class SSVWriter(CSVWriter):
|
|
@@ -297,10 +297,10 @@ class SSVWriter(CSVWriter):
|
|
|
297
297
|
def __init__(self, file: TextIO) -> None:
|
|
298
298
|
# pylint: disable=C0301
|
|
299
299
|
CSVWriter.__init__(
|
|
300
|
-
self, file, sep="\
|
|
300
|
+
self, file, sep="\x1f", quot=None, eol="\n", qnl="\r"
|
|
301
301
|
)
|
|
302
302
|
# not permitted in SSV data
|
|
303
|
-
self._invf = re.compile("[\x00\
|
|
303
|
+
self._invf = re.compile("[\x00\x1f]")
|
|
304
304
|
|
|
305
305
|
|
|
306
306
|
if SSVPrinter.__doc__ is not None:
|
|
@@ -352,9 +352,9 @@ class SSVReader(object):
|
|
|
352
352
|
if not line:
|
|
353
353
|
return None
|
|
354
354
|
if isinstance(line, str):
|
|
355
|
-
return self._read(line, "\n", "\r", "\
|
|
355
|
+
return self._read(line, "\n", "\r", "\x1f", "\r\n", "\x00")
|
|
356
356
|
if isinstance(line, bytes):
|
|
357
|
-
return self._read(line, b"\n", b"\r", b"\
|
|
357
|
+
return self._read(line, b"\n", b"\r", b"\x1f", b"\r\n", b"\x00")
|
|
358
358
|
raise TypeError()
|
|
359
359
|
|
|
360
360
|
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2025 Martin Boller
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
#
|
|
5
|
+
# Loosely based on other greenbone scripts
|
|
6
|
+
#
|
|
7
|
+
# Run with: gvm-script --gmp-username admin-user --gmp-password password socket verify-scanners.gmp.py
|
|
8
|
+
|
|
9
|
+
from argparse import Namespace
|
|
10
|
+
|
|
11
|
+
from gvm.errors import GvmServerError
|
|
12
|
+
from gvm.protocols.gmp import Gmp
|
|
13
|
+
from gvmtools.helper import Table
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def main(gmp: Gmp, args: Namespace) -> None:
|
|
17
|
+
# pylint: disable=unused-argument
|
|
18
|
+
|
|
19
|
+
heading = ["#", "Name", "Id", "Host", "Version"]
|
|
20
|
+
|
|
21
|
+
rows = []
|
|
22
|
+
numberRows = 0
|
|
23
|
+
|
|
24
|
+
print("Verifying scanners.\n")
|
|
25
|
+
response_xml = gmp.get_scanners(filter_string="rows=-1")
|
|
26
|
+
scanners_xml = response_xml.xpath("scanner")
|
|
27
|
+
|
|
28
|
+
for scanner in scanners_xml:
|
|
29
|
+
# Count number of reports
|
|
30
|
+
numberRows = numberRows + 1
|
|
31
|
+
# Cast/convert to text to show in list
|
|
32
|
+
rowNumber = str(numberRows)
|
|
33
|
+
name = "".join(scanner.xpath("name/text()"))
|
|
34
|
+
scanner_id = scanner.get("id")
|
|
35
|
+
host = "".join(scanner.xpath("host/text()"))
|
|
36
|
+
if host == "":
|
|
37
|
+
host = "local scanner"
|
|
38
|
+
try:
|
|
39
|
+
status_xml = gmp.verify_scanner(str(scanner_id))
|
|
40
|
+
# pretty_print(status_xml)
|
|
41
|
+
for scanner_status in status_xml:
|
|
42
|
+
scanner_version = "".join(scanner_status.xpath("text()"))
|
|
43
|
+
except GvmServerError:
|
|
44
|
+
scanner_version = "*No Response*"
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
rows.append([rowNumber, name, scanner_id, host, scanner_version])
|
|
48
|
+
|
|
49
|
+
print(Table(heading=heading, rows=rows))
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
if __name__ == "__gmp__":
|
|
53
|
+
main(gmp, args)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|