Get the final verdict from the DBotScore of the context.
Provided that it has all of the latest source verdict, this script gives you the right final verdict.
import demistomock as demisto # noqa: F401
from CommonServerPython import * # noqa: F401
from typing import Any
FINAL_VERDICT_VENDOR = "XSOAR"
def reliability_level(reliability: str | None) -> int:
if reliability is None:
return -1
return {
DBotScoreReliability.A_PLUS: 6,
DBotScoreReliability.A: 5,
DBotScoreReliability.B: 4,
DBotScoreReliability.C: 3,
DBotScoreReliability.D: 2,
DBotScoreReliability.E: 1,
DBotScoreReliability.F: 0,
}.get(reliability, -1)
def is_source_reliable(final: dict[str, Any] | None, source: dict[str, Any]) -> bool:
if source.get("Vendor") == "Manual":
return True
source_reliability = reliability_level(source.get("Reliability"))
if source_reliability < 0:
return False
if final is None:
return True
final_reliability = reliability_level(final.get("Reliability"))
if source_reliability > final_reliability:
return True
elif source_reliability == final_reliability:
source_score = source.get("Score") or 0
final_score = final.get("Score") or 0
if source_score > final_score:
return True
return False
def get_final_verdict(sources: list[dict[str, Any]], indicator_value: str) -> dict[str, Any] | None:
"""Get the DBotScore of the final verdict of an indicator from list of source DBotScores
Vendor = Manual:
- The most reliable DBotScore
If DBotScore by Manual is not found:
- The most reliable DBotScore is decided by 'Reliability'
If some different DBotScores having the same Reliability are found:
- The DBotScores having the highest risk are applied for the final verdict.
(Malicious > Suspicious > Benign > Unknown)
If there are some different DBotScores filtered by the highest risk:
- The DBotScore found at first is applied for the final verdict.
:param sources: The list of source DBotScore
:param indicator_value: The indicator value
:return: The DBotScore of the final verdict.
"""
final = None
for source in sources:
source_indicator = source.get("Indicator")
if source_indicator == indicator_value and is_source_reliable(final, source):
final = assign_params(
Indicator=source_indicator,
Type=source.get("Type"),
Score=source.get("Score") or 0,
Reliability=source.get("Reliability"),
Vendor=FINAL_VERDICT_VENDOR,
)
return final
def main():
try:
args = demisto.args()
indicator_value = args.get("indicator_value")
final_dbot_store = None
if source_dbot_scores := demisto.dt(demisto.context(), "DBotScore(val.Indicator && val.Score)"):
source_dbot_scores = source_dbot_scores if isinstance(source_dbot_scores, list) else [source_dbot_scores]
final_dbot_store = get_final_verdict(source_dbot_scores, indicator_value)
if final_dbot_store:
return_results(
CommandResults(
outputs_prefix="FinalDBotScore",
outputs_key_field="Indicator",
outputs=final_dbot_store,
readable_output=tblToMd("Final Verdict", final_dbot_store),
raw_response=final_dbot_store,
)
)
else:
return_results(f"No DBotScore found for {indicator_value}")
except Exception as err:
return_error(f"Failed to execute GetIndicatorDBotScoreFromContext script. Error: {str(err)}")
if __name__ in ("__builtin__", "builtins", "__main__"):
main()
README
Get the final verdict of a indcator from the given DBotScores in the context by their reliability.
Provided that it has all of the latest source verdict, this script gives you the right final verdict.
Note that the result is calculated by the context data and not given from the database.