豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit 74074d6

Browse files
committed
Add 11 advanced FreeIPA detection rules (LOOKUP JOIN + new_terms)
Second wave of FreeIPA detection rules using ES|QL LOOKUP JOIN and new_terms rule types for detections that require cross-event correlation or behavioral baselines. LOOKUP JOIN rules (5) use the existing latest_bind transform to enrich directory_access RESULT events with the authenticated identity from the corresponding BIND event. This enables rules that were previously impossible due to BIND and RESULT being separate log events: - Anonymous LDAP enumeration: join to identify anonymous sessions - Credential attribute search by external user: exclude internal FreeIPA operations by bind DN - Mass enumeration by non-service account: filter out SSSD and host principal queries, flag human-initiated enumeration - CVE-2025-7493 krbCanonicalName modification: detect principal spoofing with authenticated identity context - LDAP configuration modification: detect cn=config changes with who made the change new_terms rules (4) use 14-30 day history windows to detect first occurrences of security-relevant activity: - First Kerberos auth from new source IP per principal - First administrative API command for a user - New host enrollment from previously unseen source IP - New constrained delegation (S4U2Proxy) client-service pair 24-hour aggregation rules (2) catch patient attacks that stay below per-interval thresholds: - Slow brute force: 50+ failures per principal over 24 hours - Slow password spray: 50+ failures across 10+ principals over 24 hours
1 parent 78cdc47 commit 74074d6

10 files changed

+1157
-0
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
[metadata]
2+
creation_date = "2026/03/28"
3+
integration = ["freeipa"]
4+
maturity = "development"
5+
min_stack_comments = "ES|QL LOOKUP JOIN requires 8.19+ for GA support with lookup-mode indices."
6+
min_stack_version = "8.19.0"
7+
updated_date = "2026/03/28"
8+
9+
[rule]
10+
author = ["Elastic"]
11+
description = """
12+
Detects LDAP searches for credential attributes (userPassword, krbPrincipalKey, ipaNTHash, krbMKey) by non-internal
13+
users. These attributes contain password hashes, Kerberos keys, and NT hashes that can be cracked offline. Uses
14+
LOOKUP JOIN with the latest_bind transform to identify the authenticated identity and exclude internal FreeIPA
15+
operations such as Directory Manager and Kerberos subsystem searches.
16+
"""
17+
false_positives = [
18+
"""
19+
FreeIPA internal processes (ipa-kdb, certmonger) may search for credential attributes during normal operations.
20+
These use bind DNs under cn=kerberos or cn=Directory Manager and are excluded. Custom LDAP scripts performing
21+
password auditing may trigger this rule — add their bind DNs to the exclusion list.
22+
""",
23+
]
24+
from = "now-9m"
25+
interval = "5m"
26+
language = "esql"
27+
license = "Elastic License v2"
28+
name = "FreeIPA LDAP Credential Attribute Search by External User"
29+
note = """## Triage and analysis
30+
31+
### Investigating FreeIPA LDAP Credential Attribute Search by External User
32+
33+
FreeIPA stores credential material in LDAP attributes that are normally ACL-protected. Searches explicitly requesting these attributes indicate an attempt to extract password hashes or Kerberos keys for offline cracking. Internal FreeIPA processes access these attributes routinely, but any external user or non-standard bind DN doing so is highly suspicious.
34+
35+
### Possible investigation steps
36+
37+
- Identify the authenticated user from `freeipa.directory.bind_dn` — this is the account performing the search.
38+
- Check `freeipa.directory.filter` to understand exactly which credential attributes were requested.
39+
- Review `source.ip` to determine where the search originated.
40+
- Check if the bind DN has been compromised by reviewing recent authentication events for that principal.
41+
- Look for follow-up activity indicating offline cracking succeeded — new authentications for the targeted accounts from unusual sources.
42+
43+
### Response and remediation
44+
45+
- Immediately reset the password for the bind DN performing the search.
46+
- Rotate Kerberos keys for any principals whose krbPrincipalKey was exposed.
47+
- Review LDAP ACIs to ensure credential attributes are not readable by non-admin users.
48+
- Block the source IP if external or unauthorized.
49+
- Consider enabling audit logging for sensitive attribute access in 389 DS.
50+
"""
51+
references = [
52+
"https://attack.mitre.org/techniques/T1552/001/",
53+
"https://specterops.io/blog/2019/12/04/attacking-freeipa-part-ii-enumeration/",
54+
]
55+
risk_score = 99
56+
rule_id = "fb49e9de-f62b-41ad-9a37-40fed994c491"
57+
setup = """## Setup
58+
59+
This rule requires the FreeIPA integration to be installed and configured to collect logs from FreeIPA servers.
60+
61+
### FreeIPA Integration Setup
62+
1. Install the FreeIPA integration in Kibana Fleet.
63+
2. Add the integration to an Elastic Agent policy deployed on your FreeIPA server(s).
64+
3. Ensure the relevant log paths are accessible:
65+
- 389DS access: `/var/log/dirsrv/slapd-*/access` (directory_access data stream)
66+
67+
This rule requires the `latest_bind` transform to be running. Verify the transform is running: `GET _transform/logs-freeipa-latest-bind/_stats`. The destination index must use `index.mode: lookup`. See the integration README for setup instructions.
68+
"""
69+
severity = "critical"
70+
tags = [
71+
"Domain: Identity",
72+
"Data Source: FreeIPA",
73+
"Data Source: FreeIPA Directory Server",
74+
"Use Case: Threat Detection",
75+
"Tactic: Credential Access",
76+
"Resources: Investigation Guide",
77+
]
78+
timestamp_override = "event.ingested"
79+
type = "esql"
80+
81+
query = '''
82+
from logs-freeipa.directory_access-*
83+
| where freeipa.directory.operation == "SRCH"
84+
and freeipa.directory.scope == "sub"
85+
and freeipa.directory.filter == "(userPassword=*)"
86+
| LOOKUP JOIN freeipa-lookup-bind ON freeipa.directory.connection_id
87+
| KEEP @timestamp, freeipa.*, source.ip, user.*, observer.*, host.name, event.action, event.outcome, event.kind, event.category, event.type, event.module
88+
| where not freeipa.directory.bind_dn in ("cn=Directory Manager", "cn=directory manager")
89+
and not freeipa.directory.bind_dn like "*cn=kerberos,*"
90+
'''
91+
92+
93+
[[rule.threat]]
94+
framework = "MITRE ATT&CK"
95+
[[rule.threat.technique]]
96+
id = "T1552"
97+
name = "Unsecured Credentials"
98+
reference = "https://attack.mitre.org/techniques/T1552/"
99+
[[rule.threat.technique.subtechnique]]
100+
id = "T1552.001"
101+
name = "Credentials In Files"
102+
reference = "https://attack.mitre.org/techniques/T1552/001/"
103+
104+
105+
[rule.threat.tactic]
106+
id = "TA0006"
107+
name = "Credential Access"
108+
reference = "https://attack.mitre.org/tactics/TA0006/"
109+
110+
[rule.investigation_fields]
111+
field_names = [
112+
"@timestamp",
113+
"source.ip",
114+
"freeipa.directory.bind_dn",
115+
"freeipa.directory.connection_id",
116+
"freeipa.directory.filter",
117+
"freeipa.directory.base_dn",
118+
"freeipa.directory.scope",
119+
]
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
[metadata]
2+
creation_date = "2026/03/28"
3+
integration = ["freeipa"]
4+
maturity = "development"
5+
updated_date = "2026/03/28"
6+
7+
[rule]
8+
author = ["Elastic"]
9+
description = """
10+
Detects the first time a constrained delegation (S4U2Proxy) is used to impersonate a particular client for a
11+
particular service. New delegation relationships that haven't been seen in the past 14 days may indicate abuse of
12+
delegation privileges. Constrained delegation allows a service to request tickets on behalf of a user, and
13+
unauthorized new delegation pairs can enable lateral movement and privilege escalation.
14+
"""
15+
false_positives = [
16+
"""
17+
Legitimate constrained delegation occurs in environments using web applications with Kerberos SSO (e.g., HTTP
18+
services delegating to LDAP or CIFS). New delegation pairs may appear when new services are deployed or when
19+
users access delegated services for the first time. Review the service principal's delegation configuration.
20+
""",
21+
]
22+
from = "now-9m"
23+
index = ["logs-freeipa.kdc-*"]
24+
language = "kuery"
25+
license = "Elastic License v2"
26+
name = "FreeIPA New Constrained Delegation (S4U2Proxy) for Client"
27+
note = """## Triage and analysis
28+
29+
### Investigating FreeIPA New Constrained Delegation (S4U2Proxy) for Client
30+
31+
Constrained delegation (S4U2Proxy) allows a service principal to request Kerberos tickets on behalf of a user for specific target services. This is configured via msDS-AllowedToDelegateTo or its FreeIPA equivalent. If an attacker gains control of a service principal with delegation privileges, they can impersonate any user to the allowed target services. A new client-service delegation pair that hasn't been seen before may indicate abuse.
32+
33+
### Possible investigation steps
34+
35+
- Identify the impersonated client from `freeipa.kdc.s4u_client` and the target service from `freeipa.kdc.service_principal`.
36+
- Verify the service principal's delegation configuration matches the observed delegation pair.
37+
- Check if the s4u_client is a high-value target (admin, service account with elevated privileges).
38+
- Review who modified the service principal's delegation settings recently via IPA API events.
39+
- Correlate with other activity from the service principal's host to determine if it has been compromised.
40+
41+
### Response and remediation
42+
43+
- If unauthorized, remove the delegation privilege from the service principal using `ipa service-mod`.
44+
- Revoke active tickets for both the service principal and the impersonated client.
45+
- Investigate the service principal's host for signs of compromise.
46+
- Review all constrained delegation configurations in the domain with `ipa service-find --with-delegation`.
47+
"""
48+
references = [
49+
"https://attack.mitre.org/techniques/T1550/003/",
50+
"https://www.thehacker.recipes/ad/movement/kerberos/delegations/constrained",
51+
]
52+
risk_score = 73
53+
rule_id = "27304633-f55a-42dc-92bb-05aba996bfe7"
54+
setup = """## Setup
55+
56+
This rule requires the FreeIPA integration to be installed and configured to collect logs from FreeIPA servers.
57+
58+
### FreeIPA Integration Setup
59+
1. Install the FreeIPA integration in Kibana Fleet.
60+
2. Add the integration to an Elastic Agent policy deployed on your FreeIPA server(s).
61+
3. Ensure the relevant log paths are accessible:
62+
- KDC: `/var/log/krb5kdc.log` (kdc data stream)
63+
"""
64+
severity = "high"
65+
tags = [
66+
"Domain: Identity",
67+
"Data Source: FreeIPA",
68+
"Data Source: FreeIPA KDC",
69+
"Use Case: Threat Detection",
70+
"Tactic: Credential Access",
71+
"Resources: Investigation Guide",
72+
]
73+
timestamp_override = "event.ingested"
74+
type = "new_terms"
75+
76+
query = '''
77+
event.dataset: "freeipa.kdc" and freeipa.kdc.s4u_client: *
78+
'''
79+
80+
81+
[[rule.threat]]
82+
framework = "MITRE ATT&CK"
83+
[[rule.threat.technique]]
84+
id = "T1550"
85+
name = "Use Alternate Authentication Material"
86+
reference = "https://attack.mitre.org/techniques/T1550/"
87+
[[rule.threat.technique.subtechnique]]
88+
id = "T1550.003"
89+
name = "Pass the Ticket"
90+
reference = "https://attack.mitre.org/techniques/T1550/003/"
91+
92+
93+
[rule.threat.tactic]
94+
id = "TA0006"
95+
name = "Credential Access"
96+
reference = "https://attack.mitre.org/tactics/TA0006/"
97+
98+
[rule.investigation_fields]
99+
field_names = [
100+
"@timestamp",
101+
"source.ip",
102+
"freeipa.kdc.s4u_client",
103+
"freeipa.kdc.service_principal",
104+
"freeipa.kdc.client_principal",
105+
"freeipa.kdc.request_type",
106+
"event.outcome",
107+
]
108+
109+
[rule.new_terms]
110+
field = "new_terms_fields"
111+
value = ["freeipa.kdc.s4u_client", "freeipa.kdc.service_principal"]
112+
113+
[[rule.new_terms.history_window_start]]
114+
field = "history_window_start"
115+
value = "now-14d"
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
[metadata]
2+
creation_date = "2026/03/28"
3+
integration = ["freeipa"]
4+
maturity = "development"
5+
updated_date = "2026/03/28"
6+
7+
[rule]
8+
author = ["Elastic"]
9+
description = """
10+
Detects a high number of Kerberos authentication failures for a single principal from a single source IP over a
11+
24-hour period. This catches patient brute force attacks that stay below the per-interval threshold of the standard
12+
brute force rule by spreading attempts across hours. The 24-hour bucket aggregation reveals slow-and-low credential
13+
guessing that would otherwise evade shorter detection windows.
14+
"""
15+
false_positives = [
16+
"""
17+
A misconfigured service with an expired or incorrect keytab may generate sustained low-rate authentication
18+
failures over 24 hours. Identify and fix the misconfigured service or exclude its source IP and principal.
19+
""",
20+
]
21+
from = "now-25h"
22+
interval = "1h"
23+
language = "kuery"
24+
license = "Elastic License v2"
25+
name = "FreeIPA Slow Kerberos Brute Force Over 24 Hours"
26+
note = """## Triage and analysis
27+
28+
### Investigating FreeIPA Slow Kerberos Brute Force Over 24 Hours
29+
30+
Sophisticated attackers spread brute force attempts over long periods to avoid detection by short-window threshold rules. By aggregating failures into 24-hour buckets, this rule catches patient attacks that generate fewer than 25 failures per 5-minute window but accumulate significantly over a day. This is a common technique to stay below account lockout thresholds.
31+
32+
### Possible investigation steps
33+
34+
- Identify the targeted principal from `freeipa.kdc.client_principal` and determine its value (admin, service account, regular user).
35+
- Check `source.ip` and `source.geo` for the origin. External sources are high risk.
36+
- Review the distribution of failures over the 24-hour period — evenly spread failures suggest automated tooling, while clustered failures suggest manual attempts.
37+
- Check if any successful authentication occurred for the same principal from the same source, indicating the brute force may have succeeded.
38+
- Compare with the standard brute force rule to confirm this was below the short-window threshold.
39+
40+
### Response and remediation
41+
42+
- Block the source IP at the network perimeter.
43+
- Reset the targeted principal's password if there is any chance of compromise.
44+
- Review and lower account lockout thresholds if the current policy allows too many attempts.
45+
- Enable FreeIPA OTP/2FA for the targeted account if it is high-value.
46+
- Monitor for follow-up activity from the source IP.
47+
"""
48+
references = [
49+
"https://attack.mitre.org/techniques/T1110/001/",
50+
"https://specterops.io/blog/2019/11/25/attacking-freeipa-part-i-authentication/",
51+
]
52+
risk_score = 73
53+
rule_id = "449a8017-a606-4c89-a678-c4369c218a02"
54+
setup = """## Setup
55+
56+
This rule requires the FreeIPA integration to be installed and configured to collect logs from FreeIPA servers.
57+
58+
### FreeIPA Integration Setup
59+
1. Install the FreeIPA integration in Kibana Fleet.
60+
2. Add the integration to an Elastic Agent policy deployed on your FreeIPA server(s).
61+
3. Ensure the relevant log paths are accessible:
62+
- KDC: `/var/log/krb5kdc.log` (kdc data stream)
63+
"""
64+
severity = "high"
65+
tags = [
66+
"Domain: Identity",
67+
"Data Source: FreeIPA",
68+
"Data Source: FreeIPA KDC",
69+
"Use Case: Threat Detection",
70+
"Use Case: Identity and Access Audit",
71+
"Tactic: Credential Access",
72+
"Resources: Investigation Guide",
73+
]
74+
timestamp_override = "event.ingested"
75+
index = ["logs-freeipa.kdc-*"]
76+
type = "threshold"
77+
78+
query = '''
79+
event.dataset: "freeipa.kdc" and event.outcome: "failure"
80+
'''
81+
82+
83+
84+
[rule.threshold]
85+
field = ["freeipa.kdc.client_principal", "source.ip"]
86+
value = 50
87+
88+
[[rule.threat]]
89+
framework = "MITRE ATT&CK"
90+
[[rule.threat.technique]]
91+
id = "T1110"
92+
name = "Brute Force"
93+
reference = "https://attack.mitre.org/techniques/T1110/"
94+
[[rule.threat.technique.subtechnique]]
95+
id = "T1110.001"
96+
name = "Password Guessing"
97+
reference = "https://attack.mitre.org/techniques/T1110/001/"
98+
99+
100+
[rule.threat.tactic]
101+
id = "TA0006"
102+
name = "Credential Access"
103+
reference = "https://attack.mitre.org/tactics/TA0006/"
104+
105+
[rule.investigation_fields]
106+
field_names = [
107+
"@timestamp",
108+
"source.ip",
109+
"source.geo.country_name",
110+
"freeipa.kdc.client_principal",
111+
"freeipa.kdc.error_code",
112+
"event.outcome",
113+
"Esql.failure_count",
114+
"day_bucket",
115+
]

0 commit comments

Comments
 (0)