Axonius Too Many Failed Logins


Description

Detects too many failed Axonius login attempts, which may indicate a brute-force attack

Query · python

def rule(event):
    action = event.deep_get("event", "action", default="")
    status = event.deep_get("event", "params", "status", default="")
    username = event.deep_get("event", "user", default="")
    return status != "successful" and action == "AuditAction.LoginFrom" and bool(username)


def dedup(event):
    return event.deep_get("event", "user", default="<UNKNOWN_USER>")


def title(event):
    username = event.deep_get("event", "user", default="")
    return f"[Axonius] Too many failed Login from {username}"


def alert_context(event):
    username = event.deep_get("event", "user", default="")
    ip_address = event.deep_get("event", "params", "ip", default="")
    action = event.deep_get("event", "action", default="")
    status = event.deep_get("event", "params", "status", default="")

    context = {
        "username": username,
        "ip_address": ip_address,
        "action": action,
        "status": status,
    }
    return context

Analyst notes

Review the actions taken, check credentials/service user used and escalate.

Raw source Axonius Too Many Failed Logins · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
AnalysisType: rule
Filename: axonius_too_many_failed_logins.py
RuleID: Axonius.TooManyFailedLogins
DisplayName: Axonius Too Many Failed Logins
Enabled: true
LogTypes:
  - Axonius.Activity
Tags:
  - Axonius
Severity: Medium
Threshold: 5
DedupPeriodMinutes: 5
Description: Detects too many failed Axonius login attempts, which may indicate a brute-force attack
Runbook: Review the actions taken, check credentials/service user used and escalate.
Tests:
  - Name: Successful Login
    ExpectedResult: False
    Log:
      {
        "event": {
          "action": "AuditAction.LoginFrom",
          "category": "AuditCategory.UserSession",
          "params": {
            "ip": "1.2.3.4",
            "status": "successful"
          },
          "type": "user",
          "user": "denethor@lotr.com"
        },
        "source": "axonius",
        "time": 1752690986.344609
      }
  - Name: Failed Login - Counts Toward Threshold
    ExpectedResult: True
    Log:
      {
        "event": {
          "action": "AuditAction.LoginFrom",
          "category": "AuditCategory.UserSession",
          "params": {
            "ip": "1.2.3.4",
            "status": "failure"
          },
          "type": "user",
          "user": "denethor@lotr.com"
        },
        "source": "axonius",
        "time": 1752690986.344609
      }
  - Name: Failed Login Without Username - No Match
    ExpectedResult: False
    Log:
      {
        "event": {
          "action": "AuditAction.LoginFrom",
          "category": "AuditCategory.UserSession",
          "params": {
            "ip": "172.7.1.1",
            "status": "failure"
          },
          "type": "user",
          "user": ""
        },
        "source": "axonius",
        "time": 1752690986.344609
      }

# ------ paired body: axonius_too_many_failed_logins.py ------

def rule(event):
    action = event.deep_get("event", "action", default="")
    status = event.deep_get("event", "params", "status", default="")
    username = event.deep_get("event", "user", default="")
    return status != "successful" and action == "AuditAction.LoginFrom" and bool(username)


def dedup(event):
    return event.deep_get("event", "user", default="<UNKNOWN_USER>")


def title(event):
    username = event.deep_get("event", "user", default="")
    return f"[Axonius] Too many failed Login from {username}"


def alert_context(event):
    username = event.deep_get("event", "user", default="")
    ip_address = event.deep_get("event", "params", "ip", default="")
    action = event.deep_get("event", "action", default="")
    status = event.deep_get("event", "params", "status", default="")

    context = {
        "username": username,
        "ip_address": ip_address,
        "action": action,
        "status": status,
    }
    return context

Detection rules belong to the projects that publish them and remain under their own licenses. This site indexes and links to them; it claims no rights in them.