wapiti/wapitiCore/report/jsonreportgenerator.py

154 lines
5.8 KiB
Python

#!/usr/bin/env python3
# JSON Report Generator Module for Wapiti Project
# Wapiti Project (https://wapiti-scanner.github.io)
#
# Copyright (C) 2014-2022 Nicolas SURRIBAS
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import json
from wapitiCore.report.reportgenerator import ReportGenerator
class JSONReportGenerator(ReportGenerator):
"""This class allow generating reports in JSON format.
The root dictionary contains 5 dictionaries :
- classifications : contains the description and references of a vulnerability type.
- vulnerabilities : each key is matching a vulnerability class. Value is a list of found vulnerabilities.
- anomalies : same as vulnerabilities but used only for error messages and timeouts (items of less importance).
- additionals : some additional information about the target.
- infos : several information about the scan.
"""
def __init__(self):
super().__init__()
# Use only one dict for vulnerability, anomaly and additional types
self._flaw_types = {}
self._vulns = {}
self._anomalies = {}
self._additionals = {}
def generate_report(self, output_path):
"""
Generate a JSON report of the vulnerabilities, anomalies and additionnals which have
been previously logged with the log* methods.
"""
report_dict = {
"classifications": self._flaw_types,
"vulnerabilities": self._vulns,
"anomalies": self._anomalies,
"additionals": self._additionals,
"infos": self._infos
}
with open(output_path, "w", encoding='utf-8') as json_report_file:
json.dump(report_dict, json_report_file, indent=2)
# Vulnerabilities
def add_vulnerability_type(self, name, description="", solution="", references=None, wstg=None):
"""Add information on a type of vulnerability"""
if name not in self._flaw_types:
self._flaw_types[name] = {
"desc": description,
"sol": solution,
"ref": references,
"wstg": wstg
}
if name not in self._vulns:
self._vulns[name] = []
def add_vulnerability(self, module: str, category=None, level=0, request=None, parameter="", info="", wstg=None):
"""
Store the information about a found vulnerability.
"""
vuln_dict = {
"method": request.method,
"path": request.file_path,
"info": info,
"level": level,
"parameter": parameter,
"referer": request.referer,
"module": module,
"http_request": request.http_repr(left_margin=""),
"curl_command": request.curl_repr,
"wstg": wstg,
}
if category not in self._vulns:
self._vulns[category] = []
self._vulns[category].append(vuln_dict)
# Anomalies
def add_anomaly_type(self, name, description="", solution="", references=None, wstg=None):
"""Register a type of anomaly"""
if name not in self._flaw_types:
self._flaw_types[name] = {
"desc": description,
"sol": solution,
"ref": references,
"wstg": wstg,
}
if name not in self._anomalies:
self._anomalies[name] = []
def add_anomaly(self, module: str, category=None, level=0, request=None, parameter="", info="", wstg=None):
"""Store the information about an anomaly met during the attack."""
anom_dict = {
"method": request.method,
"path": request.file_path,
"info": info,
"level": level,
"parameter": parameter,
"referer": request.referer,
"module": module,
"http_request": request.http_repr(left_margin=""),
"curl_command": request.curl_repr,
"wstg": wstg
}
if category not in self._anomalies:
self._anomalies[category] = []
self._anomalies[category].append(anom_dict)
def add_additional_type(self, name, description="", solution="", references=None, wstg=None):
"""Register a type of additional"""
if name not in self._flaw_types:
self._flaw_types[name] = {
"desc": description,
"sol": solution,
"ref": references,
"wstg": wstg
}
if name not in self._additionals:
self._additionals[name] = []
def add_additional(self, module: str, category=None, level=0, request=None, parameter="", info="", wstg=None):
"""Store the information about an additional."""
addition_dict = {
"method": request.method,
"path": request.file_path,
"info": info,
"level": level,
"parameter": parameter,
"referer": request.referer,
"module": module,
"http_request": request.http_repr(left_margin=""),
"curl_command": request.curl_repr,
"wstg": wstg
}
if category not in self._additionals:
self._additionals[category] = []
self._additionals[category].append(addition_dict)