Acknowledgements: Thanks to Aaron Margosis and Sean Metcalf for providing feedback that sharpened both the accuracy and the argument of this research. And thanks to Susannah Matt for her help reviewing, formatting, and publishing this post.
It started with a lab domain controller, the kind of thing I've stood up a dozen times until the clicks are automatic. I opened Add Roles and Features out of habit. Most of the list I recognized. One I didn't: Active Directory Rights Management Services (AD RMS). I'd never deployed it, and never attacked it. The name suggested document protection of some kind. I installed it, poked at it for an afternoon, and asked the two questions that matter most to me: how would you attack this, and how would you defend it?
Answering that took six weeks and produced a compiled tool, four independent key-extraction paths, a 255-year non-rotatable private key sitting in a file on my desktop, and a plaintext copy of a document I had encrypted, opened entirely offline, with no server contact and no user rights. This first part covers the groundwork; the payoff comes in Part 2.
Part 1 is the map: what AD RMS is, why it is still everywhere, how the trust model actually works, and how you find a cluster and read the templates that map what it protects, all from an ordinary domain account.
Part 2 is the attack: extracting the root key through service-group membership and decrypting the protected documents offline. It also covers the part that makes this matter: the SLC certificate is valid for 255 years, from 2002 to 2258, and there is no way to rotate the key behind it. Once that private key is out, it decrypts protected content indefinitely, past the certificate window entirely. If you only care about the payoff, skip to Part 2. If you want to understand what is getting attacked, and be able to find it on an engagement, start here.
What Is AD RMS?
AD RMS is Microsoft's enterprise digital-rights management system. Microsoft's own documentation describes it as a server role that pairs encryption, certificates, and authentication to build information-protection solutions, and the property it keeps coming back to is persistence: the protection travels with the file no matter where it goes or how it's transported. That's the pitch that made it attractive circa 2008: Encrypt documents at rest and in transit, enforce granular permissions (view but don't print, edit but don't forward), keep control even after a file reaches the wrong inbox. When you right-click a document in Office and see "Confidential, View Only," that's RMS. When an Outlook message has a gold padlock and you can't forward it, that's RMS. When a SharePoint library says "IRM Protected" and files download already encrypted, RMS.
Microsoft's own threat model for the product tells you where the design's attention went. The documentation enumerates what RMS deliberately does not stop: a recipient photographing their screen, retyping content by hand, or malware capturing the decrypted content once an authorized user has opened it. Every item on that list is about the enforcement boundary, stopping an authorized viewer from doing something with content they're already allowed to see. Nothing on the list contemplates the server's own signing key walking out the door. The design took that for granted, on the assumption that the servers holding the key and the accounts with access to it would be guarded like the privileged assets they are. Part 2 is what happens when that assumption doesn't hold.
Why AD RMS is still everywhere
The current migration guide states plainly that AD RMS is no longer in active development and recommends moving to Azure Information Protection (AIP). That recommendation is about capability, not support. The same guide's header reads "Applies to: Windows Server 2025" because the role ships and is fully supported in the current server OS. If you do not need what AIP adds, staying on AD RMS is a legitimate choice, not a problem. Migrations are also expensive, painful, and risky, especially when the thing you are migrating from still works and still protects documents that need protecting.
Microsoft, AD RMS documentation: The upgrade guide is still titled "Upgrading AD RMS to Windows Server 2016," yet its "Applies to" header lists Windows Server 2025, 2022, 2019, and 2016. The role ships and is supported on the current OS; the guidance just never got retitled.
Figure 1: Microsoft Learn, "Upgrading AD RMS to Windows Server 2016." The "Applies to" header lists Windows Server 2025, so the guidance still applies to the current OS. Only the title is out of date, not the content.
One more detail from that same migration guide, because the second half of this series turns on it: Microsoft calls the AD RMS configuration database the most important database in the deployment, because it stores the Server Licensor Certificate, the rights-policy templates, and users' keys. It tells administrators to back that database up and keep the backups reachable so the deployment can be restored to another server. That is correct, responsible guidance. The security consequence is not that Microsoft documents it; it is that this one database, and every backup of it, concentrates the crown jewels and has to be guarded just as strongly. Part 2 goes after exactly that database.
Microsoft, AD RMS migration guide: The configuration database is described as "the most important" one in the deployment because it stores the Server Licensor Certificate and the rights-policy templates. The same guide tells administrators to back that database up and keep the backups available so the deployment can be restored to another server.
The lab
Everything that follows runs against a purpose-built AD RMS deployment in a Sopranos-themed lab. Though you do not need to have seen one of television's greatest shows to follow along 🙂, every name is defined by its AD role. It is one New Jersey forest, newjersey.sopranos.local
, with AD RMS built the way Microsoft actually recommends, across member servers. The RMS service runs on VESUVIO
. The configuration database, which holds the SLC key, lives on a separate SQL server, BARONE
. The domain controller is BADABING
. That split, the RMS service on VESUVIO
and the SLC key in the database on BARONE
, is what matters in Part 2. For now it just means the crown jewel, the SLC key, sits in the configuration database, one step removed from the RMS service.
A handful of accounts carry the series, each defined by what it can reach:
labadmin
: Domain and enterprise admin, and the only member of AD RMS Enterprise Administrators. Runs the console. In production these would be separate accounts; the lab collapses them.svc_bing
: the RMS domain service account. Runs the cluster's app pool and sits in the AD RMS Service Group.tony.soprano
: A domain user and a member of the AD RMS Service Group. That membership alone makes him an effective administrator of the RMS service, able to reach the administrative surface a plain domain user cannot. That group is the boundary this series is about.silvio.dante
: A domain user granted read access to specific protected content through a template. He can open documents that grant permits, and nothing else; he has no administrative access to the cluster.paulie.gualtieri
: A plain domain user with no admin rights, no service group membership, and no content grants. Like any domain user he can still discover the cluster and read its templates, but the admin surface returns 401.
Installing AD RMS creates a set of local groups on the cluster server on its own: AD RMS Enterprise Administrators, AD RMS Service Group, AD RMS Template Administrators, and AD RMS Auditors. These are local groups on the RMS server, not domain groups, and provisioning drops the service account into the Service Group automatically. Membership is what the cluster checks before it answers its administrative surface, the endpoints that expose the configuration and the administrative surface. It grants nothing in the domain; its reach is scoped entirely to the RMS cluster, which happens to be where the crown jewels sit.
Because it is a local group, anyone with administrator rights on the RMS server can add themselves to it. The point runs the other way: holding this group takes no domain-wide privilege at all, so whoever compromises the member server or the service account reaches it without ever becoming Domain Admin. Provisioning creates the group and drops the service account in. From then on it looks like plumbing, a service-account artifact, yet its membership reaches the administrative surface and the key behind it. That gap between how the group looks and what it can reach is the crux of this lab.
Figure 2: The lab. AD RMS runs on member servers, the service on VESUVIO
and the configuration database on BARONE
(SQL). The figure maps who can reach what: AD RMS Service Group members reach the admin surface. An ordinary domain user is limited to discovery and shut out of the rest.
Figure 3: The AD RMS console once the role is installed. Trust Policies (Trusted User Domains, Trusted Publishing Domains), Rights Policy Templates, Exclusion Policies, Security Policies (Super Users, Cluster Key Password, Decommissioning), and Reports. Every node here maps to something the series covers later.
The cluster has a shape worth previewing before the recon section walks it in detail. AD RMS speaks SOAP over HTTP or HTTPS; this lab is configured for HTTP, though the transport makes no difference to the attack. An authenticated client makes the same calls over either. Its endpoints are divided by privilege. The client pipeline, which covers certification, licensing, and the template-distribution calls that the RMS client makes on its own, answers any authenticated domain user. The administrative surface is gated to the AD RMS Service Group. The rights-policy templates sit on the open side, readable by any domain account, since the client needs them to apply protection.
Figure 4: The AD RMS surface. The service runs on VESUVIO
and the configuration database on BARONE
. The SOAP endpoints are split by privilege: the client pipeline answers any domain user, while the administrative surface is gated to the AD RMS Service Group. Each of the three rights-policy templates grants one group.
How protection actually works
Understanding the attack requires understanding the trust structure. At the top sits the Microsoft DRM Production Root, chaining down through a CA and a Server Enrollment CA to the Microsoft DRM Server Self Enrollment Service, which signs your Server Licensor Certificate (SLC), the deployment root. That layering is by design, not a flaw. Every certificate system needs a root key at the top that signs the keys beneath, and here the real root is Microsoft's, above every deployment. The SLC is only the deployment's own root one layer down, and unlike Microsoft's root, that key is one an administrator can extract. Every protected document's content key, a symmetric AES key, is encrypted to the SLC public key. The server decrypts it with the SLC private key on demand. Whoever holds the SLC private key holds the master key to every document that deployment ever protected.
Microsoft DRM Production Root
└─ Microsoft DRM Production CA
└─ Microsoft DRM Production Server Enrollment CA
└─ Microsoft DRM Server Self Enrollment Service
└─ Server Licensor Certificate (SLC) ← the cluster root
Figure 5: Certificate and license relationships in AD RMS. Redrawn from Enrique Saggese, Microsoft (2012)
When a user protects a Word document, the RMS client generates a random AES content key, encrypts the document body with it, then sends an unsigned rights label, XrML, to the server specifying who gets what rights and the content key encrypted with the SLC public key. The server signs the rights label with the SLC private key and returns a publishing license (PL). The encrypted content, the IV, and the signed PL all get embedded together in an OLE Compound File (D0 CF 11 E0
magic bytes) and that file goes wherever files go. Opening it reverses the process: the client sends the PL back to the server, the server decrypts the content key using the SLC private key, checks the rights policy, re-encrypts the content key to the user's identity certificate, and issues a use license. Rights enforcement (no print, no copy) happens in the client.
This is the key architectural point the series rests on. A protected document's confidentiality, the actual encryption of its body, is real cryptography rooted in the SLC. Whoever holds that key can open the document itself, not just bypass what it permits. The "no print / no forward" rights are the separate and weaker layer: policy a cooperating client chooses to honor, not a cryptographic boundary. This series is about the strong boundary, the SLC, and Part 2 is where that boundary breaks.
There is a second layer worth previewing, because it trips up every from-scratch decryptor. The content key in the license is not applied to the document body directly. It is wrapped in a sealed-key structure that unwraps to reveal the actual package key, which is what encrypts the body. So the real chain is:
SLC private key unseals the content key (RSA-OAEP)
The content key unwraps the package key (a nested sealed-key)
The package key decrypts the body (AES)
One root key, two unwraps, then the plaintext. Part 2 will document every byte of that; for now, just hold the shape. It is layered, and every layer is reachable from the SLC key alone.
Figure 6: The sealed-key unwrap as nested keys. The SLC's RSA key opens the content key, which wraps the package key, which encrypts the document. Two keys, two layers of protection, with the inner package-key layer and byte offsets recovered by reverse engineering.
All of this happens over SOAP on HTTP or HTTPS with NTLM or Kerberos at the HTTP layer. The following endpoints are published in AD for any domain user to discover, which is how clients find the cluster in the first place:
/_wmcs/certification/
/_wmcs/licensing/
/_wmcs/admin/
/_wmcs/decommission/
The discovery query and an endpoint-reachability probe are shown below.
Recon: How do I know I'm dealing with RMS?
Before you spend time on the key (that's Part 2), you need to know whether RMS is even being used. The good news: you can answer that question before you have any credentials at all.
The Service Connection Point (SCP) for any RMS server in AD is the first check. Any domain user can run the LDAP query below, no special tools required. One filter, one result, cluster URL in the output.
Figure 7: SCP discovery. The LDAP filter (keywords=MSRMRootCluster
) locates the cluster URL from the Configuration partition. Any domain user, no special rights needed.
That SCP is the entire AD footprint. AD RMS adds no groups to the directory, no objects beyond that one connection point, and no schema at all, no classes and no attributes, none of what Exchange or AD CS leave behind. Microsoft states it plainly, "the Active Directory Schema Extension is not required to install or use AD RMS." The authorization boundary is not in AD either. It lives on the RMS server. The AD RMS Service Group and AD RMS Enterprise Administrators, the groups that actually gate the key, are local groups in the server's own SAM. Microsoft's own prerequisites confirm it, noting the Service Group "is created as a domain group on the domain controller and not as a local group," so on any normal member-server deployment it stays local and never shows up in a directory query.
A compromised workstation gives up the cluster with no directory query at all. The RMS client records the cluster's location in the registry at HKLM\SOFTWARE\Microsoft\MSIPC\ServiceLocation
, where EnterpriseCertification
and EnterprisePublishing
values name the certification and licensing URLs outright.
If you can reach the cluster URL, hitting /_wmcs/certification/server.asmx
returns the SLC certificate chain (the public cert) to any authenticated domain user. That's expected, since the chain is public; for recon it confirms the cluster is live and hands you its identity.
Figure 8: Endpoint reachability probe as paulie.gualtieri
(domain user). All four SOAP endpoints answer. The admin endpoints return 401, drawing the privilege boundary the server enforces.
Finding the protected content itself is the higher-value move. Modern Office files like .docx
, .xlsx
, and .pptx
are normally ZIP archives. They start with PK (50 4B 03 04)
. An RMS-protected Office file is an OLE Compound File. It starts with D0 CF 11 E0
. That's the whole test: iIf a .docx
on a file share has an OLE header, it's protected.
Figure 9: A normal .docx
is a ZIP, starting 50-4B-03-04 (PK)
. An RMS-protected .docx
is wrapped in an OLE compound file, starting D0-CF-11-E0-A1-B1-1A-E1, with Primary (the publishing license) and EncryptedPackage
streams inside. You sweep a share or mailbox for the D0-CF magic to pick out protected files.
That only tells you a file is protected. The same wrapper that makes it stand out also carries its publishing license in the clear, as the Primary stream is signed, not encrypted. So a protected file gives up far more than its name and size to anyone who can read the bytes, with no key, no rights, and no server contact. Parsing that license attributes the file: the server that sealed it and its licensing URL, the owner and their SID, the content ID, the applied policy, and the timestamp. Everything comes out except the content itself, whose key stays sealed to the SLC. Note where the licensing URL points: That is the exact server Part 2 goes after, handed to you by the file it protected.
Figure 10: The applied policy is its own tell: a named template points you at a classification and the group that holds it, while "Restricted Access" marks a file someone locked down by hand. Everything comes out except the content itself, whose key stays sealed to the SLC.
Beyond Office files: .pfile
, .ptxt,
.ppdf
, and .rpmsg
extensions are all RMS-native formats. Any .rpmsg
attachment in Exchange is a rights-protected message. The Content-Type: application/x-microsoft-rms-protection
header in email marks IRM mail at the transport layer.
Rights-policy templates are the richest recon on the box. Their names, descriptions, and grants map how the organization classifies its protected content and which group each classification is granted to, all before you touch a file. And you do not need to be anyone special to read them. The RMS client fetches templates so it can apply them, so the cluster serves them to any authenticated user through the licensing pipeline. AcquireTemplateInformation
, on /licensing/TemplateDistribution.asmx
, is the call the client itself makes, and a plain domain user with no group membership gets a 200 from it. There is a second, administrative route to the same templates, GetAll
on /admin/TemplateMgr.asmx
, but that one is gated behind AD RMS Service Group membership and hands an ordinary user a 401. Managing templates is an admin action. Reading them is not, so the classification scheme and its grants are visible to any domain user, no Service Group required.
Both routes mean speaking the RMS SOAP protocol by hand, which is where SharpRMS comes in. SharpRMS is a custom C# post-exploitation tool that speaks the AD RMS SOAP protocol directly, the same web-service calls the RMS client makes under the hood. It authenticates with the operator's existing domain credentials and exercises the certification, licensing, and administrative endpoints to enumerate a cluster, pull its rights-policy templates, and extract key material. Reading the template list never needed privilege. What comes next does: the cluster key.
Here is the enumeration pulled over the wire against our lab, where the cluster has three templates:
Figure 11: SharpRMS admin /operation:templates as tony.soprano
, a member of the AD RMS Service Group.
The cluster returns all three rights-policy templates in full. Internal (Confidential) is granted to Earners, Legal (Attorney-Client Privileged) to Legal, and Executive (Board Confidential) to Capos. Each grant's WellKnownRights
is a bitfield of the rights the client is trusted to enforce. 1 (0x1) is View, 1537 (0x601) is View plus Edit plus Save, and 4096 (0x1000) is the owner's full control. Creating a template is an admin action. Reading the list is not. A plain domain user like Paulie pulls the same names and descriptions straight from the licensing endpoint without Service Group membership. The admin surface is shown here only because its output is fuller.
Read that as an attacker. Template names, descriptions, and grants are free recon, though what they reveal varies. In this lab they map to an internal, an attorney-client, and an executive category, each granted to a specific group, which points you straight at the shares and mailboxes worth hitting first. In other environments a description may just state a behavior, like "do not forward", and a template may be granted to everyone. Read them as hints about how an organization organizes its protection, not as a guaranteed org chart.
Two fields worth noting. The Author field names the account that created each template, and a plain domain user can read it. In the lab that is labadmin
; in a real deployment it is whoever administers RMS, an admin account name handed to a low-privilege attacker for free. And WellKnownRights
is a policy value, not a cryptographic one. It does not change the content key. A template set to view-only and a template set to full control both seal their content to the same SLC, and the offline decrypt (which we'll cover in Part 2) ignores the rights, the expiration, and the revocation alike. Every field in a template is a control the client is trusted to honor. None of them dictates encryption.
Figure 12: The same three templates in the AD RMS console (Rights Policy Templates). Creating them is privileged; enumerating them, as above, is not.
The logging database is equally useful for attackers and defenders, though reaching it is not a domain-user move. DRMS_Logging_*
lives on the SQL server, BARONE
, and reading it takes SQL access to that database, the same footing as the configuration database itself, not an ordinary authenticated account. With that access, the ServiceRequest
table tracks every license request: user, host, timestamp, request type. ErrorInformation
stores detailed error context including SIDs. ServiceRequestView
assembles these into a readable format that shows who uses RMS, how frequently, from which machines, and for what. To an attacker who has compromised the database server, this identifies the users who open the most protected content, the machines with cached credentials worth targeting, and the accounts worth impersonating. To a defender doing IR, it is a good place to spot anomalies in who is requesting licenses: unfamiliar accounts, unusual hosts, or spikes in volume.
Workstation artifacts round out the picture. Every machine that has ever opened an RMS-protected document caches credentials in %LOCALAPPDATA%\Microsoft\DRM\
(the user's Rights Account Certificate, their RMS identity certificate and private key) and %LOCALAPPDATA%\Microsoft\MSIPC\
(the MSIPC client cache, which includes cached use licenses). These are protected by user-scope DPAPI, which means they are only as strong as the user's own context. If you can run code as that user, you are that user. The RMS identity decrypts transparently under their profile, no key extraction required. The RMS identity decrypts transparently under their profile, no key extraction required. The offline variant is to lift the DPAPI-protected identity and rebuild it elsewhere, though that takes more than a file copy: the master key that unlocks it is sealed with the user's password, so you need that password or the domain DPAPI backup key too.
Registry keys under HKCU\Software\Microsoft\Office\*\Common\DRM
also holds state. This is an entirely separate attack path from the server-side extraction work Part 2 covers; whether or not anyone uses it, the path is there.
Why Domain Admin isn't enough
For most engagements, the report ends at Domain Admin. The client's actual sensitive data (the M&A terms, board minutes, legal holds, ITAR designs) is still encrypted. Domain Admin lets you read NTFS permissions and copy files off a share. It does not open RMS-protected content, because the content is AES-encrypted inside OLE containers and the decryption key is held by RMS. That's the entire point of the system; the security boundary is the document, not the network perimeter.
An important distinction: This is total compromise of the cluster's protected content, not domain compromise. The SLC key yields no AD credentials and no privileges outside the RMS trust domain. It is not a DCSync equivalent. The honest reporting line is:
Domain Admin alone did not open this organization's RMS-protected data. Extracting the Server Licensor Certificate private key, which required AD RMS Service Group membership and not Domain Admin, defeated the RMS protection layer offline. The SLC cannot be rotated without orphaning every document already sealed under it, so a fresh key protects only new documents while everything protected to date stays exposed, even after the domain is otherwise remediated.
What each tier can see
Before touching the key, establish what each privilege tier can already see. The gap between them is what the whole attack hinges on.
Any domain user
Run enum
as paulie.gualtieri
(plain domain users):
.\SharpRMS.exe enum
SharpRMS enum automates all of this in one call: SCP discovery, cert chain retrieval, endpoint probe, and GAC enumeration. The full output as Paulie, a plain Domain Users member with no special RMS rights:
Figure 13: SharpRMS enum
as paulie.gualtieri
(domain user). The full SLC certificate chain, validity window, and GAC enrollment keys are public. Every admin endpoint returns 401. The server draws the privilege boundary itself.
Service-group member
The same admin surface that 401'd Paulie answers user tony.soprano
. The tool lists the full catalog first: 31 read operations, eight parameterized writes, and three cross-cluster trust operations. Two reads decide the rest of the attack:
Figure 14: SharpRMS admin /operation:clusterinfo
, run as tony.soprano
.
Locating the server needs no privilege, any domain user resolves it from the SCP, and Paulie already surfaced VESUVIO
in the previous figure. Tony's Service Group membership is what makes the administrative SOAP call answer: CryptoMode 2, IsDecommissioned: false
, IsADFederationSvcInstalled: false
. Passing his password on the command line is shorthand for the figure; a real operator would act under Tony's token rather than expose his plaintext credentials in Paulie's session.
Figure 15: SharpRMS admin /operation:keyprotection as tony.soprano
.
A separate admin method, GetServicePrivateKeyProtectionInformation
, returns two facts that set up the attack. Here the SLC private key is software-based (IsServicePrivateKeySoftwareBased: true
), so it is extractable, and the config database that holds it lives on BARONE
(DatabaseConnectionString
). AD RMS can instead protect that key in a hardware module, where this software extraction would not apply; software protection is the deployed configuration, and the common default.
The boundary that matters isn't Domain Admin or Enterprise Admin, it is AD RMS Service Group membership, which is exactly where it should sit. The gap is in monitoring: Domain Admin and the other high-privilege groups are watched by default, while the RMS Service Group is a role-specific group that standard privileged-group monitoring does not include unless someone adds it, so it is easy to leave unwatched. Paulie can map the deployment; Tony can confirm the key is grabbable and where. In Part 2, everything runs through Tony.
Coming in Part 2
If Part 1 was the map, Part 2 is the key. It covers the one property that sets AD RMS apart from the AD secrets you already guard: Those you rotate as a matter of course, while the SLC private key has no rotation mechanism and no expiry, and the certificate that carries it runs 255 years. It shows why Domain Admin does not open this data, and what does. The specifics of the extraction and the offline decrypt are Part 2's to tell.
Stated plainly, the boundary that protects an organization's most sensitive documents is not the domain. It is a single organization-wide key that an AD RMS Service Group member can reach, and unlike the AD secrets you rotate to recover from a breach, this key has no rotation or re-protection path. Extract it once and the protected content stays readable, for any user, long after the domain is cleaned up.
A note on scope and prior work
This series covers on-premises AD RMS. It does not apply to Azure Information Protection or Microsoft Purview, whose tenant key is cloud-held, out of reach of the on-premises compromise this series describes. The exception is deployments that deliberately keep the protection key on-premises, which inherit the same exposure. Part 2 covers that boundary in detail.
Prior work worth naming: DisARMS (Grothe, Mainka, Rösler & Schwenk, WOOT '16, MSRC Case 33210) covered client-side protection removal via the MSIPC SDK, a different surface from the server-side key extraction this series focuses on. Microsoft treated rights enforcement as policy rather than a security boundary. For the rights themselves, that holds. View-only and no-print are controls the client chooses to honor, not cryptography. The real boundary is the SLC private key, and reaching it is what this series is about.
