一、引言
前段时间在做一个网络安全管理系统,涉及到漏洞扫描相关的内容,在网上搜了一圈,找到了一个开源的漏洞扫描系统openvas,目前是改名为greenbone,是著名的漏洞扫描分析软件Nessus的开源版,漏洞库还是比较全的,官网地址:Vulnerability Management | Open Source und DSGVO-konform - Greenbone。
网络安全管理系统我是用python写的,当时想着把openvas接到我这个系统中来,自定义IP然后传到openvas去做扫描,返回扫描结果和报告,但目前网上关于python对接openvas的资料太少了,只能自己去官网查文档和API来写接口,于是花了一段时间去看文档以及部署openvas,最后终于搞定了!
二、参考资料链接
1)如何使用OpenVas做一个漏洞扫描系统。 - 哔哩哔哩 | 作者是用于对接JAVA的,还是比较有参考意义
2)1 Einführung - Greenbone Enterprise Appliance – GOS 22.04.21 | 官方操作手册
3)https://greenbone.github.io/docs/latest/22.4/container/workflows.html | 社区文档,需要注意的是,如果用容器部署,需要修改docker-compose文件开放socket才能使用API(注意,2024/6/1官方停用了docker.io镜像使用,要么使用源码部署,要么用其他非官方镜像)
4)python-gvm | API文档
5)https://blog.csdn.net/2401_84139924/article/details/137551640 | 部署文档参考,操作系统用centos、ubuntu也行
三、API详解
部署过程就不过多叙述了,有多种安装方式,包括源码安装、容器安装等等,注意的是如果使用官方的免费版虚拟机文件启动,是用不了API的,也就是【Greenbone Enterprise TRIAL VMware/VirtualBox】
3.1 使用GMP
# 导入必要的类
from gvm.connections import UnixSocketConnection
from gvm.protocols.gmp import Gmp
from gvm.transforms import EtreeCheckCommandTransform
from gvm.errors import GvmError
# 设定socket和账号密码
path = '/tmp/gvm/gvmd/gvmd.sock'
connection = UnixSocketConnection(path=path)
transform = EtreeCheckCommandTransform()
username = 'admin'
password = 'admin'
# 连接GMP获取版本并打印
with Gmp(connection=connection) as gmp:
# get the response message returned as a utf-8 encoded string
response = gmp.get_version()
# print the response message
print(response)
# 执行以上命令,成功的话会返回
<get_version_response status="200" status_text="OK"><version>9.0</version></get_version_response>
3.2 获取扫描任务
import sys
from gvm.connections import UnixSocketConnection
from gvm.errors import GvmError
from gvm.protocols.gmp import Gmp
from gvm.transforms import EtreeCheckCommandTransform
path = '/run/gvmd/gvmd.sock'
connection = UnixSocketConnection(path=path)
transform = EtreeCheckCommandTransform()
username = 'foo'
password = 'bar'
try:
tasks = []
with Gmp(connection=connection, transform=transform) as gmp:
gmp.authenticate(username, password)
tasks = gmp.get_tasks(filter_string='name~weekly')
for task in tasks.xpath('task'):
print(task.find('name').text)
except GvmError as e:
print('An error occurred', e, file=sys.stderr)
注意上面的gmp.get_tasks()就是获取tasks的API,具体有哪些API可参考GMP v22.5 - python-gvm
每个API的使用都差不多,输入参数,返回内容,然后再对内容进行分割处理
3.3 创建一个target目标
with Gmp(connection=connection) as gmp:
# login GSM
gmp.authenticate(username,password)
hostip = []
hostip.append(ipaddr)
# get target
response_target = gmp.get_targets(filter_string="rows=-1")
tarip = []
ipre = re.compile(r"<hosts>([a-zA-Z0-9.]+)</hosts>")
ipfind = ipre.findall(str(response_target))
# task name
taskname = "Immediate scan of IP " + hostip[0]
# first create scan ipaddr
if hostip[0] in ipfind:
print('This IP is already create scan target, please input other ipaddr or input other type.')
else:
# create target name
tarname = "Target for immediate scan of IP " + hostip[0]
print('target_name:' + tarname)
# get port_list id
response_port_re = gmp.get_port_lists()
portid = get_id('port_list',taskname,response_port_re)
# create target
gmp.create_target(name=tarname,hosts=hostip,port_list_id=portid,asset_hosts_filter=None, comment=None, exclude_hosts=None, ssh_credential_id=None, ssh_credential_port=None, smb_credential_id=None, esxi_credential_id=None, snmp_credential_id=None, alive_test=None, allow_simultaneous_ips=None, reverse_lookup_only=None, reverse_lookup_unify=None, port_range=None)
值得注意的点是,如果你有非常多的target,获取列表的时候一定要加【filter_string="rows=-1"】,不然默认只返回10条数据
3.4 启动一个任务
def start_task(taskid):
try:
with Gmp(connection=connection) as gmp:
# login GSM
gmp.authenticate(username,password)
# start task
gmp.start_task(taskid)
# check status
# status re
response_task = gmp.get_task(taskid)
taskstatusre = re.compile(r"<status>([a-zA-Z]+)</status>")
taskstatus = taskstatusre.findall(str(response_task))
print('task_status:'+ taskstatus[0])
print("task id started.")
except Exception as e:
print('An error occurred: ', e)
3.5 获取报告,包括txt和pdf格式
def get_report(taskname):
try:
with Gmp(connection=connection) as gmp:
# login GSM
gmp.authenticate(username,password)
#get report id
response_report_re = gmp.get_reports(filter_string="rows=-1")
reportid = get_id('report',taskname,response_report_re)
# get report txt type
response_report_txt = gmp.get_report(report_id=reportid,report_format_id=txt_report_formatid,filter_string="apply_overrides=0 levels=hml rows=100 min_qod=70 first=1 sort-reverse=severity")
reportre_txt = re.compile(r"</report_format>([a-zA-Z0-9].+)</report>")
report_data_txt = reportre_txt.findall(str(response_report_txt))
print("txt report base64:" + str(report_data_txt[0]))
# get report pdf type
response_report_pdf = gmp.get_report(report_id=reportid,report_format_id=pdf_report_formatid,filter_string="apply_overrides=0 levels=hml rows=100 min_qod=70 first=1 sort-reverse=severity")
reportre_pdf = re.compile(r"</report_format>([a-zA-Z0-9].+)</report>")
report_data_pdf = reportre_pdf.findall(str(response_report_pdf))
print("pdf report base64:" + str(report_data_pdf[0]))
except Exception as e:
print('An error occurred: ', e)
完整代码已上传:https://download.csdn.net/download/liucx9710/89444950
觉得有用的朋友可以给文章点个赞哦,使用过程中有问题的也可以评论大家一起探讨!
顺便打个小广告,成套的网络安全管理系统,有需要朋友的WX搜:LCX-YY,备注CSDN