#!/usr/bin/env python
"""
Model the CVSS Exploitability and Exploit Code Maturity metrics as SSVC decision points.
"""

#  Copyright (c) 2023-2025 Carnegie Mellon University.
#  NO WARRANTY. THIS CARNEGIE MELLON UNIVERSITY AND SOFTWARE
#  ENGINEERING INSTITUTE MATERIAL IS FURNISHED ON AN "AS-IS" BASIS.
#  CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND,
#  EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT
#  NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR
#  MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE
#  OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE
#  ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM
#  PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
#  Licensed under a MIT (SEI)-style license, please see LICENSE or contact
#  permission@sei.cmu.edu for full terms.
#  [DISTRIBUTION STATEMENT A] This material has been approved for
#  public release and unlimited distribution. Please see Copyright notice
#  for non-US Government use and distribution.
#  This Software includes and/or makes use of Third-Party Software each
#  subject to its own license.
#  DM24-0278

from ssvc.decision_points.base import DecisionPointValue
from ssvc.decision_points.cvss._not_defined import (
    NOT_DEFINED_ND,
    NOT_DEFINED_X,
)
from ssvc.decision_points.cvss.base import CvssDecisionPoint
from ssvc.decision_points.cvss.helpers import no_x
from ssvc.decision_points.helpers import print_versions_and_diffs

_HIGH_2 = DecisionPointValue(
    name="High",
    key="H",
    definition="Functional autonomous code exists, or no exploit is required (manual trigger) and details are widely "
    "available. Exploit code works in every situation, or is actively being delivered via an autonomous "
    "agent (such as a worm or virus). Network-connected systems are likely to encounter scanning or "
    "exploitation attempts. Exploit development has reached the level of reliable, widely-available, "
    "easy-to-use automated tools.",
)

_FUNCTIONAL_2 = DecisionPointValue(
    name="Functional",
    key="F",
    definition="Functional exploit code is available. The code works in most situations where the vulnerability "
    "exists.",
)

_PROOF_OF_CONCEPT_2 = DecisionPointValue(
    name="Proof-of-Concept",
    key="POC",
    definition="Proof-of-concept exploit code is available, or an attack demonstration is not practical for most "
    "systems. The code or technique is not functional in all situations and may require substantial "
    "modification by a skilled attacker.",
)

_UNPROVEN_2 = DecisionPointValue(
    name="Unproven",
    key="U",
    definition="No exploit code is available, or an exploit is theoretical.",
)

_HIGH = DecisionPointValue(
    name="High",
    key="H",
    definition="Either the vulnerability is exploitable by functional mobile autonomous code or no exploit is "
    "required (manual trigger) and the details for the manual technique are widely available. The code "
    "works in every situation where the vulnerability is exploitable and/or is actively being delivered "
    "via a mobile autonomous agent (a worm or virus).",
)

_FUNCTIONAL = DecisionPointValue(
    name="Functional",
    key="F",
    definition="Functional exploit code is available. The code works in most situations where the vulnerability is "
    "exploitable.",
)

_PROOF_OF_CONCEPT = DecisionPointValue(
    name="Proof of Concept",
    key="P",
    definition="Proof of concept exploit code or an attack demonstration that is not practically applicable to "
    "deployed systems is available. The code or technique is not functional in all situations and may "
    "require substantial hand tuning by a skilled attacker for use against deployed systems.",
)

_UNPROVEN = DecisionPointValue(
    name="Unproven",
    key="U",
    definition="No exploit code is yet available or an exploit method is entirely theoretical.",
)

EXPLOITABILITY_1 = CvssDecisionPoint(
    name="Exploitability",
    definition="This metric measures the current state of exploit technique or code availability and suggests a "
    "likelihood of exploitation.",
    key="E",
    version="1.0.0",
    values=(
        _UNPROVEN,
        _PROOF_OF_CONCEPT,
        _FUNCTIONAL,
        _HIGH,
    ),
)
"""
Defines Unproven, Proof of Concept, Functional, and High values for CVSS Exploitability.
"""

EXPLOITABILITY_1_1 = CvssDecisionPoint(
    name="Exploitability",
    definition="This metric measures the current state of exploit technique or code availability and suggests a "
    "likelihood of exploitation.",
    key="E",
    version="1.1.0",
    values=(
        _UNPROVEN,
        _PROOF_OF_CONCEPT,
        _FUNCTIONAL,
        _HIGH,
        NOT_DEFINED_ND,
    ),
)
"""
Introduced Not Defined value.
"""


EXPLOIT_CODE_MATURITY_1_2 = CvssDecisionPoint(
    name="Exploit Code Maturity",
    definition="measures the likelihood of the vulnerability being attacked, and is typically based on the current "
    "state of exploit techniques, exploit code availability, or active, 'in-the-wild' exploitation",
    key="E",
    version="1.2.0",
    values=(
        _UNPROVEN_2,
        _PROOF_OF_CONCEPT_2,
        _FUNCTIONAL_2,
        _HIGH_2,
        NOT_DEFINED_X,
    ),
)
"""
Name changed to Exploit Code Maturity. Updated descriptions of values.
"""


_ATTACKED = DecisionPointValue(
    name="Attacked",
    key="A",
    definition="Based on available threat intelligence either of the following must apply: Attacks targeting "
    "this vulnerability (attempted or successful) have been reported Solutions to simplify attempts "
    "to exploit the vulnerability are publicly or privately available (such as exploit toolkits)",
)

_PROOF_OF_CONCEPT_3 = DecisionPointValue(
    name="Proof-of-Concept",
    key="P",
    definition="Based on available threat intelligence each of the following must apply: Proof-of-concept exploit "
    "code is publicly available No knowledge of reported attempts to exploit this vulnerability No "
    "knowledge of publicly available solutions used to simplify attempts to exploit the vulnerability "
    "(i.e., the “Attacked” value does not apply)",
)

_UNREPORTED = DecisionPointValue(
    name="Unreported",
    key="U",
    definition="Based on available threat intelligence each of the following must apply: No knowledge of publicly "
    "available proof-of-concept exploit code No knowledge of reported attempts to exploit this "
    "vulnerability No knowledge of publicly available solutions used to simplify attempts to exploit "
    "the vulnerability (i.e., neither the “POC” nor “Attacked” values apply)",
)

EXPLOIT_MATURITY_2 = CvssDecisionPoint(
    name="Exploit Maturity",
    key="E",
    definition="This metric measures the likelihood of the vulnerability being attacked, and is based on the current "
    "state of exploit techniques, exploit code availability, or active, “in-the-wild” exploitation.",
    version="2.0.0",
    values=(
        _UNREPORTED,
        _PROOF_OF_CONCEPT_3,
        _ATTACKED,
        NOT_DEFINED_X,
    ),
)

EXPLOIT_MATURITY_2_NoX = no_x(EXPLOIT_MATURITY_2)

VERSIONS = (
    EXPLOITABILITY_1,
    EXPLOITABILITY_1_1,
    EXPLOIT_CODE_MATURITY_1_2,
    EXPLOIT_MATURITY_2,
)
LATEST = VERSIONS[-1]


def main():
    print_versions_and_diffs(VERSIONS)


if __name__ == "__main__":
    main()
