Potential SIP REGISTER Brute Force

Identifies repeated SIP REGISTER authentication rejection responses for one or more extensions from a client to a VoIP server within five minutes. The rule distinguishes repeated failures from the single 401 or 407 challenge expected in a normal digest-authentication flow. Attackers brute-force extension credentials to register rogue endpoints for toll fraud, call interception, or registration hijacking.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2026/07/31"
  3integration = ["network_traffic"]
  4maturity = "production"
  5min_stack_comments = "Requires ES|QL JSON_EXTRACT on _source to read SIP fields across current and legacy schemas."
  6min_stack_version = "9.4.0"
  7updated_date = "2026/09/18"
  8
  9[rule]
 10author = ["Elastic"]
 11description = """
 12Identifies repeated SIP REGISTER authentication rejection responses for one or more extensions from a client to a VoIP
 13server within five minutes. The rule distinguishes repeated failures from the single 401 or 407 challenge expected in a
 14normal digest-authentication flow. Attackers brute-force extension credentials to register rogue endpoints for toll
 15fraud, call interception, or registration hijacking.
 16"""
 17false_positives = [
 18    """
 19    Misconfigured phones, expired credentials, or provisioning errors can generate repeated REGISTER failures from a
 20    single device. Validate the client, affected extensions, and registration state before escalating.
 21    """,
 22]
 23from = "now-9m"
 24language = "esql"
 25license = "Elastic License v2"
 26max_signals = 5
 27name = "Potential SIP REGISTER Brute Force"
 28note = """## Triage and analysis
 29
 30### Investigating Potential SIP REGISTER Brute Force
 31
 32SIP REGISTER authenticates endpoints to a PBX or SBC. Attackers iterate extensions and passwords, producing many 401 Unauthorized, 403 Forbidden, or 407 Proxy Authentication Required responses from one external or internal client. A single 401 or 407 challenge is expected during normal digest authentication, so this rule requires either ten failures for one extension or a broader spray affecting at least five repeatedly challenged extensions.
 33
 34### Possible investigation steps
 35
 36- Determine whether `Esql.client_ip` is an expected phone, gateway, proxy, or external attacker address and confirm that `Esql.server_ip` is the intended PBX or SBC.
 37- Review `Esql.sample_extensions`, `Esql.total_failures`, and `Esql.max_failures_per_extension` to distinguish a targeted password attack from a broader extension spray.
 38- Review REGISTER requests corresponding to the rejection responses and confirm whether credentials were supplied after the initial digest challenge.
 39- Check for a successful REGISTER (2xx response) from the same client and extension shortly after the burst. Multiple failures followed by success should be escalated as possible credential compromise.
 40- Inspect CDR/billing records for anomalous outbound calls if a registration succeeded.
 41
 42### False positive analysis
 43
 44- A single misconfigured phone repeatedly attempting REGISTER with a stale password can trigger the targeted-failure branch. Lower severity when only one extension is affected and the client maps to a known device.
 45- NAT gateways and SIP proxies can represent many legitimate phones behind one address. The rule requires repeated challenges per extension to reduce alerts caused by one normal digest challenge from each phone.
 46
 47### Response and remediation
 48
 49- Block or rate-limit the offending `Esql.client_ip` at the SBC and enforce strong SIP credentials.
 50- Rotate compromised extension passwords and audit active registrations for rogue contact bindings.
 51- Enable geo-blocking or IP allowlists for REGISTER if the PBX is internal-only.
 52"""
 53references = ["https://attack.mitre.org/techniques/T1110/"]
 54risk_score = 47
 55rule_id = "1ca59146-7386-4033-a010-1c32717e9321"
 56setup = """## Setup
 57
 58This rule requires the Elastic **network_traffic** integration with the **SIP** protocol module enabled on a sensor that
 59observes VoIP REGISTER signaling to or from the PBX/SBC.
 60
 61The rule requires decoded SIP headers and responses. SIP over TLS (commonly TCP 5061) is not visible unless the sensor
 62receives decrypted traffic or observes plaintext SIP after TLS termination. SRTP encryption does not affect this rule
 63when SIP signaling remains visible.
 64"""
 65severity = "medium"
 66tags = [
 67    "Domain: Network",
 68    "Use Case: Threat Detection",
 69    "Use Case: Network Security Monitoring",
 70    "Tactic: Credential Access",
 71    "Data Source: Network Packet Capture",
 72    "Resources: Investigation Guide",
 73    "Noise: Unknown",
 74    "Performance: Fast",
 75    "Profile: Recommended",
 76    "Threat: Brute Force",
 77    "Rule Type: ES|QL",
 78]
 79timestamp_override = "event.ingested"
 80type = "esql"
 81
 82query = '''
 83from logs-network_traffic.sip-*, packetbeat-* metadata _source
 84| eval
 85    Esql.method = TO_UPPER(COALESCE(
 86        JSON_EXTRACT(_source, "network_traffic.sip.cseq.method"),
 87        JSON_EXTRACT(_source, "sip.cseq.method"),
 88        JSON_EXTRACT(_source, "network_traffic.sip.method"),
 89        JSON_EXTRACT(_source, "sip.method")
 90    )),
 91    Esql.sip_type = TO_LOWER(COALESCE(
 92        JSON_EXTRACT(_source, "network_traffic.sip.type"),
 93        JSON_EXTRACT(_source, "sip.type")
 94    )),
 95    Esql.code = COALESCE(
 96        JSON_EXTRACT(_source, "network_traffic.sip.code"),
 97        JSON_EXTRACT(_source, "sip.code")
 98    ),
 99    Esql.client_ip = COALESCE(client.ip, destination.ip),
100    Esql.server_ip = COALESCE(server.ip, source.ip),
101    Esql.extension = COALESCE(
102        JSON_EXTRACT(_source, "network_traffic.sip.to.uri.username"),
103        JSON_EXTRACT(_source, "sip.to.uri.username")
104    )
105| where
106    Esql.method == "REGISTER" and
107    Esql.sip_type == "response" and
108    Esql.code in ("401", "403", "407") and
109    Esql.client_ip is not null and
110    Esql.server_ip is not null and
111    Esql.extension is not null
112| eval Esql.time_window = DATE_TRUNC(5 minutes, @timestamp)
113| stats
114    Esql.failures_per_extension = COUNT(*)
115  by Esql.time_window, Esql.client_ip, Esql.server_ip, Esql.extension
116| eval Esql.repeated_extension = CASE(Esql.failures_per_extension >= 2, 1, 0)
117| stats
118    Esql.total_failures = SUM(Esql.failures_per_extension),
119    Esql.max_failures_per_extension = MAX(Esql.failures_per_extension),
120    Esql.distinct_extensions = COUNT_DISTINCT(Esql.extension),
121    Esql.repeated_extensions = SUM(Esql.repeated_extension),
122    Esql.sample_extensions = MV_SLICE(VALUES(Esql.extension), 0, 20)
123  by Esql.time_window, Esql.client_ip, Esql.server_ip
124| where
125    Esql.max_failures_per_extension >= 10 or
126    (
127      Esql.total_failures >= 25 and
128      Esql.distinct_extensions >= 5 and
129      Esql.repeated_extensions >= 5
130    )
131| keep Esql.*
132'''
133
134
135[[rule.threat]]
136framework = "MITRE ATT&CK"
137[[rule.threat.technique]]
138id = "T1110"
139name = "Brute Force"
140reference = "https://attack.mitre.org/techniques/T1110/"
141[[rule.threat.technique.subtechnique]]
142id = "T1110.001"
143name = "Password Guessing"
144reference = "https://attack.mitre.org/techniques/T1110/001/"
145
146[[rule.threat.technique.subtechnique]]
147id = "T1110.003"
148name = "Password Spraying"
149reference = "https://attack.mitre.org/techniques/T1110/003/"
150
151
152
153[rule.threat.tactic]
154id = "TA0006"
155name = "Credential Access"
156reference = "https://attack.mitre.org/tactics/TA0006/"
157
158[rule.alert_suppression]
159group_by = ["Esql.client_ip", "Esql.server_ip"]
160missing_fields_strategy = "suppress"
161
162[rule.alert_suppression.duration]
163unit = "h"
164value = 1

Triage and analysis

Investigating Potential SIP REGISTER Brute Force

SIP REGISTER authenticates endpoints to a PBX or SBC. Attackers iterate extensions and passwords, producing many 401 Unauthorized, 403 Forbidden, or 407 Proxy Authentication Required responses from one external or internal client. A single 401 or 407 challenge is expected during normal digest authentication, so this rule requires either ten failures for one extension or a broader spray affecting at least five repeatedly challenged extensions.

Possible investigation steps

  • Determine whether Esql.client_ip is an expected phone, gateway, proxy, or external attacker address and confirm that Esql.server_ip is the intended PBX or SBC.
  • Review Esql.sample_extensions, Esql.total_failures, and Esql.max_failures_per_extension to distinguish a targeted password attack from a broader extension spray.
  • Review REGISTER requests corresponding to the rejection responses and confirm whether credentials were supplied after the initial digest challenge.
  • Check for a successful REGISTER (2xx response) from the same client and extension shortly after the burst. Multiple failures followed by success should be escalated as possible credential compromise.
  • Inspect CDR/billing records for anomalous outbound calls if a registration succeeded.

False positive analysis

  • A single misconfigured phone repeatedly attempting REGISTER with a stale password can trigger the targeted-failure branch. Lower severity when only one extension is affected and the client maps to a known device.
  • NAT gateways and SIP proxies can represent many legitimate phones behind one address. The rule requires repeated challenges per extension to reduce alerts caused by one normal digest challenge from each phone.

Response and remediation

  • Block or rate-limit the offending Esql.client_ip at the SBC and enforce strong SIP credentials.
  • Rotate compromised extension passwords and audit active registrations for rogue contact bindings.
  • Enable geo-blocking or IP allowlists for REGISTER if the PBX is internal-only.

References

Related rules

to-top