RULE 31 AD LAPS GMSA Sensitive Attribute Read
Query
// =========================================================
// RULE-31 | AD-LAPS-GMSA-SensitiveAttribute-Read
// Description : Detects unauthorized reads of LAPS local
// admin passwords (ms-Mcs-AdmPwd / 4662) and
// Group Managed Service Account passwords
// (msDS-ManagedPassword / 4662). Attackers
// use LAPSToolkit and GMSAPasswordReader to
// harvest these credentials for lateral
// movement without touching LSASS.
// Severity : High
// Tactic : CredentialAccess (T1552.004, T1555)
// Tables : SecurityEvent
// Frequency : PT15M / PT15M
// Suppress : PT4H
// =========================================================
let LookbackPeriod = 15m;
// Privileged accounts with legitimate LAPS/GMSA read access
// (Adjust per environment — accounts like SCCM clients, Intune,
// monitoring tools are expected to read LAPS)
let LegitimateReaders = dynamic([
"sccm-client", "intune", "laps-service",
"azureaddevicesync", "msol_", "adsync"
]);
// Sensitive attribute GUIDs
// ms-Mcs-AdmPwd : {43F8B798-..} — LAPS plaintext password
// ms-Mcs-AdmPwdExpirationTime : LAPS expiry
// msDS-ManagedPassword : GMSA password blob
// msDS-ManagedPasswordId: GMSA key ID
// msDS-ManagedPasswordInterval: GMSA rotation interval
let SensitiveAttrGUIDs = dynamic([
"ms-Mcs-AdmPwd",
"ms-Mcs-AdmPwdExpirationTime",
"msDS-ManagedPassword",
"msDS-ManagedPasswordId",
"msDS-ManagedPasswordInterval"
]);
// EventID 4662: An operation was performed on an object
// ObjectType = attributeSchema access (read of specific attribute)
SecurityEvent
| where TimeGenerated > ago(LookbackPeriod)
| where EventID == 4662
| where AccessMask == "0x10" // Read Property
or AccessMask == "0x100" // Control Access (extended rights)
// Match on LAPS/GMSA specific property GUIDs or names
| where Properties has_any (
"ms-Mcs-AdmPwd",
"msDS-ManagedPassword",
"2d1b333d-222b-14d0-ada8-00aa00c149d8", // ms-Mcs-AdmPwd GUID
"0e10c968-78fb-11d2-90d4-00c04f79dc55", // Extended Rights — Certificate Enrollment
"bf967a86-0de6-11d0-a285-00aa003049e2", // ms-Mcs-AdmPwd property set GUID
"e362ed86-b728-0842-b27d-2dea7a9df218" // msDS-ManagedPassword
)
| extend
Actor = tolower(SubjectUserName),
ActorDomain = SubjectDomainName,
TargetObject = ObjectName,
ActorNorm = tolower(SubjectUserName),
IsLAPSRead = Properties has "ms-Mcs-AdmPwd",
IsGMSARead = Properties has "msDS-ManagedPassword",
AttributeType = case(
Properties has "ms-Mcs-AdmPwd", "LAPS_PlaintextPassword",
Properties has "msDS-ManagedPassword", "GMSA_ManagedPassword",
Properties has "ms-Mcs-AdmPwdExpiration", "LAPS_ExpirationTime",
"SensitiveAttribute"
)
| where not(ActorNorm has_any (LegitimateReaders))
// Exclude machine accounts doing self-read (expected during policy application)
| where not(ActorNorm endswith "$" and TargetObject has ActorNorm)
| summarize
ReadCount = count(),
LAPSReads = countif(IsLAPSRead),
GMSAReads = countif(IsGMSARead),
TargetObjects = make_set(TargetObject, 20),
AttributeTypes = make_set(AttributeType, 5),
DCs = make_set(Computer, 5),
FirstRead = min(TimeGenerated),
LastRead = max(TimeGenerated)
by Actor, ActorDomain
| extend
AccountFull = strcat(ActorDomain, "\\", Actor),
RiskScore = (LAPSReads * 30)
+ (GMSAReads * 30)
+ (array_length(TargetObjects) * 5),
Severity = case(
array_length(TargetObjects) >= 5, "High - Mass_LAPS_GMSA_Harvest",
LAPSReads >= 1 and GMSAReads >= 1, "High - Both_LAPS_And_GMSA_Read",
LAPSReads >= 1, "High - LAPS_Password_Read",
GMSAReads >= 1, "High - GMSA_Password_Read",
"Medium"
)
| where ReadCount >= 1
| project
TimeGenerated = LastRead,
AccountFull,
Actor,
ActorDomain,
Severity,
RiskScore,
LAPSReads,
GMSAReads,
ReadCount,
TargetObjects,
AttributeTypes,
DCs,
FirstRead
| order by RiskScore descExplanation
This query is designed to detect unauthorized access to sensitive password attributes in a network environment. Specifically, it looks for unauthorized reads of Local Administrator Password Solution (LAPS) and Group Managed Service Account (GMSA) passwords, which are critical for maintaining security.
Here's a simplified breakdown of what the query does:
-
Lookback Period: The query examines events from the last 15 minutes.
-
Legitimate Readers: It defines a list of accounts that are allowed to read these sensitive attributes, such as system management tools and services.
-
Sensitive Attributes: It identifies specific attributes related to LAPS and GMSA passwords that are considered sensitive.
-
Event Filtering: The query filters security events (specifically Event ID 4662) that indicate a read operation on these sensitive attributes.
-
Unauthorized Access Detection: It checks if the read operations were performed by accounts not listed as legitimate readers and excludes expected self-reads by machine accounts.
-
Data Aggregation: For each unauthorized actor, it summarizes the number of reads, types of attributes accessed, and the domain controllers involved.
-
Risk Assessment: It calculates a risk score based on the number and type of unauthorized reads and assigns a severity level (High or Medium) based on the nature of the access.
-
Output: The query outputs a list of unauthorized access attempts, sorted by risk score, including details like the actor's account, domain, severity, risk score, and the first and last read times.
In essence, this query helps security teams identify potential threats by flagging unauthorized attempts to access sensitive password information, which could indicate malicious activity aimed at gaining unauthorized access to systems.
Details

David Alonso
Released: March 24, 2026
Tables
Keywords
Operators