CheckSenderDomainDistance

Get the string distance for the sender from our domain.

python · Common Scripts

Source

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


def levenshtein(s1, s2):
    l1 = len(s1)
    l2 = len(s2)
    matrix = [list(range(l1 + 1))] * (l2 + 1)
    for zz in range(l2 + 1):
        matrix[zz] = list(range(zz, zz + l1 + 1))
    for zz in range(l2):
        for sz in range(l1):
            if s1[sz] == s2[zz]:
                matrix[zz + 1][sz + 1] = min(matrix[zz + 1][sz] + 1, matrix[zz][sz + 1] + 1, matrix[zz][sz])
            else:
                matrix[zz + 1][sz + 1] = min(matrix[zz + 1][sz] + 1, matrix[zz][sz + 1] + 1, matrix[zz][sz] + 1)
    return matrix[l2][l1]


def main():
    res = []
    found = False

    domains = argToList(demisto.get(demisto.args(), "domain"))
    if not domains:
        res.append(
            {
                "Type": entryTypes["error"],
                "ContentsFormat": formats["text"],
                "Contents": "Unable to extract domain from arguments",
            }
        )
    else:
        sender = demisto.get(demisto.args(), "sender")
        if sender:
            parts = sender.split("@")
            if len(parts) == 2:
                if parts[1] not in domains:
                    distances = []
                    for domain in domains:
                        distance = levenshtein(domain, parts[1])
                        distances.append(distance)
                        closeDistance = demisto.get(demisto.args(), "distance")
                        closeDistanceInt = int(closeDistance) if closeDistance else 3
                        if distance > 0 and distance < closeDistanceInt:
                            res.append(
                                {
                                    "Type": entryTypes["note"],
                                    "ContentsFormat": formats["text"],
                                    "Contents": "Domain " + parts[1] + " is suspiciously close to " + domain,
                                }
                            )
                            found = True
                    if len(distances) > 0:
                        # Override the context on each run
                        demisto.setContext("LevenshteinDistance", distances if len(distances) > 1 else distances[0])
            else:
                res.append(
                    {
                        "Type": entryTypes["error"],
                        "ContentsFormat": formats["text"],
                        "Contents": "Unable to extract domain from sender - " + sender,
                    }
                )
        else:
            res.append(
                {"Type": entryTypes["error"], "ContentsFormat": formats["text"], "Contents": "Unable to find sender in email"}
            )
    if found:
        res.append("yes")  # type: ignore
    else:
        res.append("no")  # type: ignore
    demisto.results(res)


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

README

Gets the string distance for the sender from our domain.

Script Data


Name Description
Script Type python
Tags server, phishing, Condition

Inputs


Argument Name Description
domain The domain to be measured against the domain in the sender’s email address. Usually the domain used by the company for email. For example, “acme.com”, when users are assigned jane@acme.com (could be multiple domains with a comma-separator).
sender The sender’s email address.
distance The distance that is considered close.

Outputs


Path Description Type
LevenshteinDistance The proximity of the sender domain to our configured domains. Unknown