DarkmonLevenshtein

Computes the minimum Levenshtein edit distance between a domain's root label and a list of brand names. Used by Darkmon - Brand-Targeted NRD Watch to flag typosquatting candidates.

python · Darkmon

Source

import demistomock as demisto  # noqa: F401
from CommonServerPython import *  # noqa: F401


def levenshtein(a: str, b: str) -> int:
    """Plain Wagner-Fischer; small inputs (domain names), no need for optimization."""
    if a == b:
        return 0
    if not a:
        return len(b)
    if not b:
        return len(a)
    prev = list(range(len(b) + 1))
    for i, ca in enumerate(a, 1):
        curr = [i] + [0] * len(b)
        for j, cb in enumerate(b, 1):
            curr[j] = min(
                prev[j] + 1,  # deletion
                curr[j - 1] + 1,  # insertion
                prev[j - 1] + (0 if ca == cb else 1),  # substitution
            )
        prev = curr
    return prev[-1]


def main():
    args = demisto.args()
    domain = (args.get("domain") or "").strip().lower()
    brands = argToList(args.get("brands"))
    if not domain or not brands:
        return_error("Both 'domain' and 'brands' are required.")
        return

    domain_root = domain.split(".")[0]
    best_brand = None
    best_distance = 10**9
    for b in brands:
        b_clean = b.strip().lower()
        if not b_clean:
            continue
        d = levenshtein(domain_root, b_clean)
        if d < best_distance:
            best_distance, best_brand = d, b_clean

    return_results(
        {
            "Type": entryTypes["note"],
            "ContentsFormat": formats["json"],
            "Contents": {
                "domain": domain,
                "brand": best_brand,
                "distance": best_distance,
            },
            "EntryContext": {
                "Darkmon.Levenshtein": {
                    "domain": domain,
                    "brand": best_brand,
                    "distance": best_distance,
                }
            },
        }
    )


if __name__ in ("__main__", "__builtin__", "builtins"):
    main()

README

Computes the minimum Levenshtein edit distance between a domain’s root label
and a list of brand names. Used by Darkmon - Brand-Targeted NRD Watch to
flag typosquatting candidates.

Script Data


Name Description
Script Type python3
Tags darkmon, transformer
Cortex XSOAR Version 6.5.0

Used In


This script is used in the following playbooks and scripts.

  • DarkmonScoreNRDs

Inputs


Argument Name Description
domain The domain to compare (only the root label is used).
brands Comma-separated brand names to compare against.

Outputs


Path Description Type
Darkmon.Levenshtein.domain The input domain (lowercased). String
Darkmon.Levenshtein.brand The brand with the smallest distance to the domain root. String
Darkmon.Levenshtein.distance The minimum Levenshtein distance found. Number