Skeleton Key
Also calledskeleton key malware
Patches LSASS on a DC so one master password signs in as any account.
- Hooks Into
- Kerberos AS RequestNTLM DC Answer
- Needs
- Code on a DC
- Gives
- Account Access
How the Attack Works
A DC checks each sign-in inside LSASS, by testing the AS request's encrypted timestamp, or an NTLM response, against the keys it holds for the account. Code running on the DC can patch that check in memory so it also accepts one master password for every account, while each real password keeps working. The master password is held as an NT hash, which works only as an RC4 key, so the patched DC steers Kerberos sign-ins to RC4. The patch lasts until the DC restarts.
Read first AS Request and Pre-Authentication, Kerberos Keys and Encryption Types, Credentials on a Running Machine
How It Plays Out
The attack step by step. Each step shows which machines take part, what travels, the keys and tickets each side now holds, what is logged and what a defender can see.
ws-017 Foothold
dc-01 Domain controller
- krbtgt key
Step 1 of 4: LSASS Patched
On dc-01 Domain controller
Code running on dc-01 patches LSASS in memory, so its sign-in checks also accept one master password, held as an NT hash.
Logged
7045 New Service Installed
On dc-01, in the System log
A new service or driver on dc-01, where one carried the code.
4697 A service was installed in the system
On dc-01, in the Security log When enabled
The same install in the Security log.
10 ProcessAccess
On dc-01, in the Microsoft-Windows-Sysmon/Operational log When enabled
A process opening lsass.exe with rights to change its memory.
3033, 3063, 3065 and 3066 A code integrity check determines that a process, usually LSASS.exe, attempts to load a driver that doesn't meet the Microsoft signing level requirements
On dc-01, in the Microsoft-Windows-CodeIntegrity/Operational log When enabled
A module refused a load into LSASS, where LSA protection is on.
What Defenders See
If a service or driver was installed, dc-01 shows event 7045 in its System log or event 4697 in its Security log. Its Microsoft-Windows-Sysmon/Operational log shows LSASS opened as Sysmon event 10, and its Microsoft-Windows-CodeIntegrity/Operational log shows a refused module as event 3033 or 3063.
Step 2 of 4: AS Request
ws-017 Foothold to dc-01 Domain controller
ws-017 asks dc-01 for a TGT as adm-alice, its timestamp sealed with the RC4 key made from the master password.
What Defenders See
Nothing shows in the Security log on dc-01 until it answers. The patched check accepts the master password here.
Hooks into Kerberos AS Request
Step 3 of 4: Genuine TGT
dc-01 Domain controller to ws-017 Foothold
dc-01 returns a real TGT for adm-alice. Nothing in it shows which password proved her.
What Travels in This Step
The TGT
ticketadm-alice's name and real groups
Encrypted with the krbtgt key Only dc-01 can open it.
Keys and Tickets
- ws-017 now holds TGT (new at this step) TGT session key (new at this step)
Logged
4768 A Kerberos authentication ticket (TGT) was requested
On dc-01, in the Security log
RC4 for adm-alice's timestamp, where her sign-ins at dc-02 use AES.
AS Reply: The TGT explains how to read it.
What Defenders See
The Security log on dc-01 shows event 4768 for adm-alice with Pre-Authentication EncryptionType 0x17, though her sign-ins at dc-02 use AES.
Step 4 of 4: NTLM Sign-In
ws-017 Foothold to dc-01 Domain controller
An NTLM sign-in to dc-01 as adm-alice, its response computed from the master password's NT hash, is approved too.
Logged
4776 The computer attempted to validate the credentials for an account
On dc-01, in the Security log
adm-alice validated with Error Code 0x0.
NTLM Authenticate and Validation explains how to read it.4624 An account was successfully logged on
On dc-01, in the Security log
A network logon for adm-alice with the NTLM package.
Reading Logon Events explains how to read it.
What Defenders See
The Security log on dc-01 shows event 4776 for adm-alice with Error Code 0x0, and event 4624 with the NTLM package where Kerberos is normal.
Hooks into NTLM DC Answer
Needs First
What the attacker must already hold for this attack to be possible.
- Code on a Domain ControllerCode running as SYSTEM on a domain controller, to patch its LSASS in memory.
Gives the Attacker
What running it hands the attacker to use next.
- Access as Another AccountSign-in as any account with one master password, beside its real one, until the DC restarts.
What Defenders See
What this attack leaves for a defender to find, and what to read in each. None of it is proof on its own, so treat each as a lead and confirm it against the rest.
| Event and Log | Written On | Look For | Switch It On |
|---|---|---|---|
| 4768 A Kerberos authentication ticket (TGT) was requested (opens in a new tab) Security log | Domain controllers | RC4 in Pre-Authentication EncryptionType for many accounts at once on one DC, while the same accounts use AES at the other DCs.AS Reply: The TGT explains how to read it. | Audit Kerberos Authentication Service |
| 7045 New Service Installed (opens in a new tab) System log | The computer the service was installed on | A new service or kernel driver on a DC, often installed remotely, around the time sign-ins changed. | Always written |
| 4697 A service was installed in the system (opens in a new tab) Security log | The computer the service was installed on | The same service install in the Security log, with its file name and the account that installed it. | Audit Security System Extension |
| 10 ProcessAccess (opens in a new tab) Microsoft-Windows-Sysmon/Operational log | Any Windows computer running Sysmon | A process opening lsass.exe on a DC with rights to change its memory, which few legitimate tools need. | Sysmon, with a configuration that records ProcessAccess to lsass.exe |
| 3033, 3063, 3065 and 3066 A code integrity check determines that a process, usually LSASS.exe, attempts to load a driver that doesn't meet the Microsoft signing level requirements (opens in a new tab) Microsoft-Windows-CodeIntegrity/Operational log | Any Windows computer that runs LSA protection, domain controllers included | A module refused a load into LSASS on a DC, which means something tried to push code into it. | LSA protection on (3033 and 3063 record a refused load) or in audit mode (3065 and 3066) |
What It Looks Like
One event from the worked example, decoded field by field, so you can see what to read in it and what each value means.
4768 A Kerberos authentication ticket (TGT) was requested
In the Security log on dc-01,
A TGT request on dc-01 forced to RC4 for an account that has AES keys.
The account that signed in. With a skeleton key any account works this way, so look at every account on this DC.
As Windows writes it:
Account Nameadm-aliceHer timestamp was sealed with RC4. Check whether other accounts on this DC changed to RC4 at once.
As Windows writes it:
Pre-Authentication EncryptionType0x17ws-017, where the sign-in came from. The address proves nothing, but RC4 on this DC alone points to the patch.
As Windows writes it:
Client Address::ffff:192.0.2.17
Defender for Identity Alerts
Where Defender for Identity runs, its sensors raise these from what they read on the servers they are installed on, domain controllers above all. Each names what it flags, which is a lead to confirm, not proof on its own.
- Suspected skeleton key attack (encryption downgrade) (opens in a new tab)Learns how each DC's Kerberos error replies are normally encrypted, and alerts on a downgrade.
Blind Spots
Where this attack leaves little or nothing to see, so a quiet log is not read as an all-clear.
- The patch lives in LSASS memory, so a restart removes it and the evidence with it. Capture memory before restarting a suspect DC.
- A master-password sign-in looks like the account's own. The patch forces RC4 for every account on that DC, which marks the DC rather than the sign-in, and moving the domain off RC4 makes that mark plain.
Look for It on a Machine
The Registry keys on an endpoint that hold a trace of this, each opening its own page.
Hunt It
The query to run in each tool, and how well each one sees this attack. Pick the tool you use, and the others load their query when you open them.
Needs Defender for Identity sensors on every DC. It learns how each DC encrypts its Kerberos error replies to each account and alerts when that turns weaker. A downgrade is a lead, not proof of a patched LSASS, so capture that DC's memory before any restart.
// Defender for Identity skeleton key alert, with the accounts and DCs it namesAlertEvidence| where Timestamp > ago( 30d)| where Title == "Suspected skeleton key attack ( encryption downgrade)"| summarize FirstSeen = min( Timestamp), Accounts = make_set_if( AccountName, isnotempty( AccountName)), Devices = make_set_if( DeviceName, isnotempty( DeviceName)), Addresses = make_set_if( RemoteIP, isnotempty( RemoteIP)) by AlertId, Title| order by FirstSeen descHow to Prevent It
The controls that break this attack, each with how it helps here and, where the Registry topic has it, where to check it on a machine.
LSA protection (opens in a new tab)
Run LSASS as a protected process on every DC, so other processes cannot open it to change its code.
Check it on a machine: LSA Protection (RunAsPPL)Hardened domain controllers (opens in a new tab)
Limit who can run code on DCs, and explain every new service, driver or unplanned restart on one.
Least-privilege administration (opens in a new tab)
Keep Domain Admins nearly empty, since the patch needs code running on a DC.
Sources
- MITRE ATT&CK T1556.001: Modify Authentication Process: Domain Controller Authentication (opens in a new tab)
- Sophos: Skeleton Key malware analysis (originally Secureworks, 2015) (opens in a new tab)
- Virus Bulletin: the Skeleton Key malware, by Microsoft and Dell SecureWorks researchers (opens in a new tab)
- Microsoft Learn: configure added LSA protection (opens in a new tab)
- [MS-KILE] AS Exchange (KDC) (opens in a new tab)
- Microsoft Learn: Defender for Identity classic alerts, persistence and privilege escalation (opens in a new tab)