Detection rules › Panther

Panther rules: netskope

Action Performed by Netskope Personnel

#
Severity
medium
Log types
Netskope.Audit
Tags
Netskope, Supply Chain Compromise
Reference
docs.netskope.com
Source
github.com/panther-labs/panther-analysis

An action was performed by Netskope personnel.

MITRE ATT&CK coverage

TacticTechniques
Initial Access

Detection logic

def rule(event):
    if event.get("is_netskope_personnel") is True:
        return True
    return False


def title(event):
    user = event.get("user", "<USER_NOT_FOUND>")
    audit_log_event = event.get("audit_log_event", "<EVENT_NOT_FOUND>")
    return f"Action [{audit_log_event}] performed by Netskope personnel [{user}]"

Rule specification

AnalysisType: rule
RuleID: "Netskope.NetskopePersonnelActivity"
DisplayName: "Action Performed by Netskope Personnel"
Enabled: true
Filename: netskope_personnel_action.py
LogTypes:
  - Netskope.Audit
Tags:
  - Netskope
  - Supply Chain Compromise
Reports:
  MITRE ATT&CK:
    - TA0001:T1195
Severity: Medium
Description: An action was performed by Netskope personnel.
DedupPeriodMinutes: 60
Threshold: 1
Runbook: Action taken by Netskope Personnel.  Validate that this action was authorized.
Reference: https://docs.netskope.com/en/netskope-help/admin-console/administration/audit-log/#filters-1

Stages and Predicates

Fires on Netskope.Audit events when the condition below holds.

Condition

  • is_netskope_personnel is true

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

Field
audit_log_event
user

Response runbook

Action taken by Netskope Personnel. Validate that this action was authorized.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "_id": "e5ca619b059fccdd0cfd9398",
  "_insertion_epoch_timestamp": 1702308331,
  "audit_log_event": "Login Successful",
  "count": 1,
  "is_netskope_personnel": true,
  "organization_unit": "",
  "severity_level": 2,
  "supporting_data": {
    "data_type": "user",
    "data_values": [
      "11.22.33.44",
      "adminsupport@netskope.com"
    ]
  },
  "timestamp": "2023-12-11 15:25:31.000000000",
  "type": "admin_audit_logs",
  "ur_normalized": "adminsupport@netskope.com",
  "user": "adminsupport@netskope.com"
}

Admin logged out because of successive login failures

#
Severity
medium
Log types
Netskope.Audit
Tags
Netskope, Brute Force
Reference
docs.netskope.com
Source
github.com/panther-labs/panther-analysis

An admin was logged out because of successive login failures.

MITRE ATT&CK coverage

TacticTechniques
Credential Access

Detection logic

def rule(event):
    if event.get("audit_log_event") == "Admin logged out because of successive login failures":
        return True
    return False


def title(event):
    user = event.get("user", "<USER_NOT_FOUND>")
    return f"Admin [{user}] was logged out because of successive login failures"

Rule specification

AnalysisType: rule
RuleID: "Netskope.AdminLoggedOutLoginFailures"
DisplayName: "Admin logged out because of successive login failures"
Enabled: true
Filename: netskope_admin_logged_out.py
LogTypes:
  - Netskope.Audit
Tags:
  - Netskope
  - Brute Force
Reports:
  MITRE ATT&CK:
    - TA0006:T1110
Severity: Medium
Description: An admin was logged out because of successive login failures.
DedupPeriodMinutes: 60
Threshold: 1
Runbook: An admin was logged out because of successive login failures.  This could indicate brute force activity against this account.
Reference: https://docs.netskope.com/en/netskope-help/admin-console/administration/audit-log/

Stages and Predicates

Fires on Netskope.Audit events when the condition below holds.

Condition

  • audit_log_event is Admin logged out because of successive login failures

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
audit_log_eventeq
  • Admin logged out because of successive login failures
field:"audit_log_event" kind:eq value:"Admin logged out because of successive login failures"

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

Field
user

Response runbook

An admin was logged out because of successive login failures. This could indicate brute force activity against this account.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "_id": "e5ca619b059fccdd0cfd9398",
  "_insertion_epoch_timestamp": 1702308331,
  "audit_log_event": "Admin logged out because of successive login failures",
  "count": 1,
  "is_netskope_personnel": true,
  "organization_unit": "",
  "severity_level": 2,
  "supporting_data": {
    "data_type": "user",
    "data_values": [
      "11.22.33.44",
      "adminsupport@netskope.com"
    ]
  },
  "timestamp": "2023-12-11 15:25:31.000000000",
  "type": "admin_audit_logs",
  "ur_normalized": "adminsupport@netskope.com",
  "user": "adminsupport@netskope.com"
}

An administrator account was created, deleted, or modified.

#
Severity
high
Log types
Netskope.Audit
Tags
Netskope, Account Manipulation
Reference
docs.netskope.com
Source
github.com/panther-labs/panther-analysis

An administrator account was created, deleted, or modified.

MITRE ATT&CK coverage

TacticTechniques
Privilege Escalation

Detection logic

ADMIN_USER_CHANGE_EVENTS = [
    "Created new admin",
    "Added SSO Admin",
    "Edited SSO Admin Record",
    "Created new support admin",
    "Edit admin record",
    "Deleted admin",
    "Enabled admin",
    "Disabled admin",
    "Unlocked admin",
    "Updated admin settings",
    "Deleted Netskope SSO admin",
]


def rule(event):
    if event.get("audit_log_event") in ADMIN_USER_CHANGE_EVENTS:
        return True
    return False


def title(event):
    user = event.get("user", "<USER_NOT_FOUND>")
    audit_log_event = event.get("audit_log_event", "<EVENT_NOT_FOUND>")
    return f"User [{user}] performed [{audit_log_event}]"


def severity(event):
    audit_log_event = event.get("audit_log_event", "no_data").lower()
    if "create" in audit_log_event or "add" in audit_log_event or "delete" in audit_log_event:
        return "CRITICAL"
    return "HIGH"

Rule specification

AnalysisType: rule
RuleID: "Netskope.AdminUserChange"
DisplayName: "An administrator account was created, deleted, or modified."
Enabled: true
Filename: netskope_admin_user_change.py
LogTypes:
  - Netskope.Audit
Tags:
  - Netskope
  - Account Manipulation
Reports:
  MITRE ATT&CK:
    - TA0004:T1098
Severity: High
Reference: https://docs.netskope.com/en/netskope-help/admin-console/administration/managing-administrators/
Description: An administrator account was created, deleted, or modified.
DedupPeriodMinutes: 60
Threshold: 1
Runbook: An administrator account was created, deleted, or modified.  Validate that this activity is expected and authorized.

Stages and Predicates

Fires on Netskope.Audit events when the condition below holds.

Condition

  • audit_log_event is one of Created new admin, Added SSO Admin, Edited SSO Admin Record, Created new support admin, Edit admin record (+6 more values, see Indicators below)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
audit_log_eventin
  • Added SSO Admin
  • Created new admin
  • Created new support admin
  • Deleted Netskope SSO admin
  • Deleted admin
  • Disabled admin
  • Edit admin record
  • Edited SSO Admin Record
  • Enabled admin
  • Unlocked admin
  • Updated admin settings
field:"audit_log_event" kind:in

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

Field
user
audit_log_event

Response runbook

An administrator account was created, deleted, or modified. Validate that this activity is expected and authorized.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "_id": "e5ca619b059fccdd0cfd9398",
  "_insertion_epoch_timestamp": 1702308331,
  "audit_log_event": "Created new admin",
  "count": 1,
  "is_netskope_personnel": true,
  "organization_unit": "",
  "severity_level": 2,
  "supporting_data": {
    "data_type": "user",
    "data_values": [
      "11.22.33.44",
      "adminsupport@netskope.com"
    ]
  },
  "timestamp": "2023-12-11 15:25:31.000000000",
  "type": "admin_audit_logs",
  "ur_normalized": "adminsupport@netskope.com",
  "user": "adminsupport@netskope.com"
}

Netskope Many Objects Deleted

#
Severity
high
Log types
Netskope.Audit
Tags
Netskope, Configuration Required, Data Destruction
Reference
docs.netskope.com
Source
github.com/panther-labs/panther-analysis

A user deleted a large number of objects in a short period of time.

MITRE ATT&CK coverage

TacticTechniques
Impact

Detection logic

def rule(event):
    audit_log_event = event.get("audit_log_event")
    if audit_log_event and "Delete" in audit_log_event:
        return True
    return False


def title(event):
    user = event.get("user", "<USER_NOT_FOUND>")
    return f"[{user}] deleted many objects in a short time"

Rule specification

AnalysisType: rule
RuleID: "Netskope.ManyDeletes"
DisplayName: "Netskope Many Objects Deleted"
Enabled: true
Filename: netskope_many_deletes.py
LogTypes:
  - Netskope.Audit
Tags:
  - Netskope
  - Configuration Required # configure threshold for your environment
  - Data Destruction
Reports:
  MITRE ATT&CK:
    - TA0040:T1485
Severity: High
Description: A user deleted a large number of objects in a short period of time.
DedupPeriodMinutes: 60
Threshold: 10
Runbook: A user deleted a large number of objects in a short period of time.  Validate that this activity is expected and authorized.
Reference: https://docs.netskope.com/en/netskope-help/admin-console/administration/audit-log/

Stages and Predicates

Fires on Netskope.Audit events when all of the conditions below hold.

Condition

  • audit_log_event is present
  • audit_log_event contains Delete
Alert cadence
alerts after 10 matches within 1h

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

Field
user

Response runbook

A user deleted a large number of objects in a short period of time. Validate that this activity is expected and authorized.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "_id": "1e589befa3da30132362f32a",
  "_insertion_epoch_timestamp": 1702318213,
  "audit_log_event": "Deleted rbi template",
  "count": 1,
  "is_netskope_personnel": false,
  "organization_unit": "",
  "severity_level": 2,
  "timestamp": "2023-12-11 18:10:13.000000000",
  "type": "admin_audit_logs",
  "ur_normalized": "service-account",
  "user": "service-account"
}

Netskope Many Unauthorized API Calls

#
Severity
high
Log types
Netskope.Audit
Tags
Netskope, Configuration Required, Brute Force
Reference
docs.netskope.com
Source
github.com/panther-labs/panther-analysis

Many unauthorized API calls were observed for a user in a short period of time.

MITRE ATT&CK coverage

TacticTechniques
Credential Access

Detection logic

def rule(event):
    data_values = event.deep_walk("supporting_data", "data_values")
    if data_values and data_values[0] == 403:
        return True
    return False


def title(event):
    user = event.get("user", "<USER_NOT_FOUND>")
    return f"Many unauthorized API calls from user [{user}]"

Rule specification

AnalysisType: rule
RuleID: "Netskope.UnauthorizedAPICalls"
DisplayName: "Netskope Many Unauthorized API Calls"
Enabled: true
Filename: netskope_unauthorized_api_calls.py
LogTypes:
  - Netskope.Audit
Tags:
  - Netskope
  - Configuration Required # configure threshold for your environment
  - Brute Force
Reports:
  MITRE ATT&CK:
    - TA0006:T1110
Severity: High
Description: Many unauthorized API calls were observed for a user in a short period of time.
DedupPeriodMinutes: 60
Threshold: 10
Runbook: An account is making many unauthorized API calls.  This could indicate brute force activity, or expired service account credentials.
Reference: https://docs.netskope.com/en/netskope-help/data-security/netskope-private-access/private-access-rest-apis/

Stages and Predicates

Fires on Netskope.Audit events when the condition below holds.

Condition

  • supporting_data.data_values is present

This rule also runs imperative logic the parser cannot express as a filter. The conditions above are the structured part it could extract.

Alert cadence
alerts after 10 matches within 1h

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
supporting_data.data_valuesis_not_null
  • (no value, null check)
field:"supporting_data.data_values" kind:is_not_null

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

Field
user

Response runbook

An account is making many unauthorized API calls. This could indicate brute force activity, or expired service account credentials.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "_id": "1e589befa3da30132362f32a",
  "_insertion_epoch_timestamp": 1702318213,
  "audit_log_event": "Rest API V2 Call",
  "count": 1,
  "is_netskope_personnel": false,
  "organization_unit": "",
  "severity_level": 2,
  "supporting_data": {
    "data_type": "incidents",
    "data_values": [
      403,
      "POST",
      "/api/v2/incidents/uba/getuci",
      "trid=ccb898fgrhvdd0v0lebg"
    ]
  },
  "timestamp": "2023-12-11 18:10:13.000000000",
  "type": "admin_audit_logs",
  "ur_normalized": "service-account",
  "user": "service-account"
}