-
1.
Douglas Bienstock and Austin Baker
I AM AD FS AND SO CAN YOU
-
2.
©2019 FireEye©2019 FireEye
Whoami
What is AD FS and how does it work?
How do we find AD FS servers?
How can we attack AD FS?
How can we become (takeover) AD FS?
Tools and Demos
Best practices and mitigations
Goal: Understand AD FS, how we can attack it and why we want to, and how to
keep it safe
Roadmap
-
3.
©2019 FireEye©2019 FireEye
4.5 years of experience at Mandiant
IR and Red Team lead
Speaks fluent cloud
Doug Bienstock - @doughsec
3
-
4.
©2019 FireEye©2019 FireEye
IR and Red Team
5.5 years at Mandiant
Teaches some classes and
stuff
Plays some games and
junk
Austin Baker - @bakedsec
4
-
5.
MSFT AD FS – WTF?
-
6.
©2019 FireEye©2019 FireEye
Single-Sign On (SSO) solution for applications that don’t integrate directly to
Active Directory
In plaintext: use AD creds for services/apps outside AD
Centralizes both authentication, identity management, token issuance
Basically required for any large org now
We must go deeper…
Active Directory Federated Services
6
-
7.
©2019 FireEye©2019 FireEye
Organizations are increasingly moving
to the cloud
AD as a data/security boundary no
longer exists
AD FS is commonly the gateway to
the cloud for organizations
If we can own AD FS we can own the
cloud
As security practitioners we must keep
up with the move to the cloud
OK – but why do we care?
7
-
8.
©2019 FireEye©2019 FireEye
Claims: Statements about a user’s identity
– Description (type) and value
Attribute Store: Where claims are sourced from (e.g. AD)
Claims Rules: Business logic that takes incoming claims, apply conditions, and
produce new outgoing claims based on those conditions. Applied in the claims
pipeline
c:[Type ==
"http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"
, Issuer == "AD AUTHORITY"] => issue(store = "Active Directory", types =
("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"), query =
";mail;{0}", param = c.Value);
Building blocks
8
-
9.
©2019 FireEye©2019 FireEye
1. Start with claims from AD
2. Pipeline adds new claims and
modifies existing claims according
to rules
3. Outputs set of claims that the
relying party has communicated it
needs
– Claims coming out of the pipeline
are transformed into security token
attributes
9
Building Blocks - Claims Pipeline
-
10.
©2019 FireEye©2019 FireEye
Claims output from the claims pipeline are used to generate security tokens in the
form of SAML tokens
Relying parties can be configured with SAML and WS-FED consumers
– WS-FED => SAML 1.1 tokens
– SAML => SAML 2.0 tokens
The tokens follow a standardized (OASIS) format that we rely on to be consistent
Tokens are accepted by relying parties in a standardized format, too
– SAMLResponse POST parameter
Building Blocks - Security Tokens
11
-
11.
©2019 FireEye©2019 FireEye
c:[Type ==
"http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"
, Issuer == "AD AUTHORITY"] => issue(store = "Active Directory", types =
("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"), query =
";mail;{0}", param = c.Value);
<Attribute
Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress">
<AttributeValue>robin@doughcorp.com</AttributeValue>
</Attribute>
Building Blocks – claims to assertions
12
-
12.
©2019 FireEye©2019 FireEye
Identity Provider (IdP): Organization that takes identities as input and outputs
claims about them. Authenticates a user, builds claims for that user (the pipeline),
and packages them into security tokens
ADFS Service: Our IdP, the "account organization"
Building blocks – the IdP
13
-
13.
©2019 FireEye©2019 FireEye
AD FS Proxy (WAP): Proxy server that sits in DMZ to receive requests from
Internet
Relying Party (RP): Unpacks provided claims from security token and makes
authorization decisions based on them. They rely on the provided claims
– e.g. a third-party cloud application
Building blocks – the RP
14
-
14.
©2019 FireEye©2019 FireEye
(1) https://portal.office.com
(2) 302 sts.doughcorp.com
(3)
-
15.
©2019 FireEye©2019 FireEye
(3)
(4)
(5)
(6)
<t:RequestSecurityTokenResponse
xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/tru
st">
<saml:Assertion
xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion”>
<saml:Attribute AttributeName="UPN"
AttributeNamespace="http://schemas.xmlsoap.org/cl
aims">
<saml:AttributeValue>
robin@doughcorp.co</saml:AttributeValue>
</saml:Attribute>
-
16.
©2019 FireEye©2019 FireEye
(1) https://portal.office.com
(2) 302 sts.doughcorp.com
Login.microsoftonline.com
(3)
(4)
(5)
(6)
(7)
-
17.
©2019 FireEye©2019 FireEye
Identity Providers
18
-
18.
©2019 FireEye©2019 FireEye
Federations need identity providers
– Need to know someone is who they claim to be
AD FS is the nexus of identity provision
– And adapters are how third-party vendors can augment that process for their own purposes
Every major vendor with hands in the authentication cookie jar has an AD FS
adapter
– Some even aim to compete for with AD FS for the IdP crown
Identity Providers and Adapters
19
-
19.
Identifying AD FS
-
20.
©2019 FireEye©2019 FireEye
Search DNS for prefixes suggested by Microsoft (most people follow their deploy
guides)
– adfs.doughcorp.com, sts.doughcorp.com, fs.doughcorp.com
– Quick Shodan search found 10,000+
Try logging in to Office 365 using a bogus email address and see if you are
redirected
Search for required URL paths
– /adfs/ls
– /adfs/services/trust/2005/usernamemixed
– more…
Finding AD FS Proxies
21
-
21.
©2019 FireEye©2019 FireEye
Some fun things...
During deployment Microsoft recommends
enabling “IDP-initiated sign-on” in order to
test
– Available at
/adfs/ls/idpinitiatedsignon.aspx
Nice forms-based auth for a password
spray
Lists SAML-enabled service providers that
use AD FS
Finding AD FS Proxies
22
-
22.
©2019 FireEye©2019 FireEye
AD FS also supports NTLM-based authentication for on-premise users
By default those URLs are also exposed to the Internet via the AD FS proxies
Leaks the internal hostname of the AD FS server (not proxy), including the Active
Directory domain name
– Also provides another vector for password sprays
/adfs/services/trust/2005/windowstransport
/adfs/services/trust/13/windowstransport
https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/deployment/best-practices-securing-ad-fs
Finding ADFS Proxies
23
-
23.
Attacking AD FS
-
24.
©2019 FireEye©2019 FireEye
“It’s like the more complex systems we
come across, the more attack surface we
see.”
- Biggie Smalls, maybe
25
-
25.
©2019 FireEye©2019 FireEye
Which pieces are obvious targets:
– Relying Party supporting apps (Duo, RSA, etc.
management)
– IdP policies and exceptions (AD FS
configurations)
– IdP-RP adapters
Relying Party attacks covered in-depth
elsewhere
– See “Two-Factor, Too Furious” from DerbyCon
The IdP side on the other hand…
Target the Weak Links
26
-
26.
©2019 FireEye©2019 FireEye
Auth adapters just implement necessary idP methods
– IsAvailableForUser, Metadata, OnAuthenticationPipelineLoad/Unload, OnError,
TryEndAuthentication
– Registered in GAC – signed with strong name
Vendor adapters construct supporting functions for the above
– Contain all the logic to determine whether a user's claim is signed off on
– Good place to focus attention
Many routes to take
– Register new adapters or adjust existing adapters
Adapt or die
27
-
27.
©2019 FireEye©2019 FireEye
Adapt or die
28
Start by investigating Microsoft.IdentityServer.ServiceHost.exe and our DLL
-
28.
©2019 FireEye©2019 FireEye
Adapt or die
29
Acquire adapter .dll and patch relevant DLL method
-
29.
©2019 FireEye©2019 FireEye
Adapt or die
30
-
30.
©2019 FireEye©2019 FireEye
Adapt or die
31
-
31.
©2019 FireEye©2019 FireEye32
Adapt or die
-
32.
©2019 FireEye©2019 FireEye
Adapt or die
33
Kill/suspend service, replace DLL, restart
Verify success!
Depending on adapter:
– Different methods to patch
– Different logging methods
Same knowledge can be used dynamically
– In-memory patching stealthy, more technically complex
– Doesn't persistent restarts without a persistent "shim"
-
33.
Becoming ADFS
-
34.
©2019 FireEye©2019 FireEye
“The token signing certificate is considered the
bedrock of security in regards to ADFS. If
someone were to get ahold of this certificate,
they could easily impersonate your ADFS
server.”
- Microsoft
35
-
35.
©2019 FireEye©2019 FireEye
Mimikatz is for the birds (in this case)
36
-
36.
©2019 FireEye©2019 FireEye
Relational database intended to be used only by Microsoft products
– MS-SQL “lite”
– Default option for AD FS
Accessible over a named-pipe
– .pipeMICROSOFT##WIDtsqlquery
– Windows 2012+
Can be accessed using SMSS
Windows Internal Database (WID)
37
-
37.
©2019 FireEye©2019 FireEye
Used by AD FS to store service configuration data in default config
Only accessible by the AD FS service account
WID
38
-
38.
©2019 FireEye©2019 FireEye
ADFSConfigurationV3.IdentityServerPolicy.ServiceSetting
Locating the goods
39
-
39.
©2019 FireEye©2019 FireEye
“We present DKM, a distributed key management system with a cryptographically
verified code base. DKM implements a new data protection API. It manages keys
and policies on behalf of groups of users that share data.”
– [https://www.microsoft.com/en-us/research/publication/cryptographically-verified-design-
and-implementation-of-a-distributed-key-manager/]
DKM
40
-
40.
©2019 FireEye©2019 FireEye
DKM
41
-
41.
©2019 FireEye©2019 FireEye
Upon service start, AD FS will load configuration information from the
configuration database (in this case the WID)
As part of that process it calls LoadCertificateCollection()
Which in turn calls DkmDataProtector.Unprotect()...
– Passing in base64 decoded blob from EncryptedPFX XML element
Decrypting the SigningToken
42
-
42.
©2019 FireEye©2019 FireEye
… which in turn calls Dkm.GroupKey._Unprotect() ...
– ...which inherits the method from DKMBase
Decrypting the SigningToken
43
-
43.
©2019 FireEye©2019 FireEye
– DKMBase.Unprotect() is where
the magic happens
Decrypting the SigningToken
44
Decode the EncryptedPFX blob
Get key length based on
encryption algorithm in use
Read the DKM key
KDK using DKM key
Decryption!
-
44.
©2019 FireEye©2019 FireEye
Decrypting the SigningToken
45
-
45.
©2019 FireEye©2019 FireEye
Uses Key Derivation Function from NIST SP 800-108 in Counter Mode
– DKM key is not used itself to decrypt Signing Certificate
– Used as initial input for HMAC-SHA256 Key Derivation (NIST SP 800-108)
Mostly, but not exactly, follows the standard (because standards are hard ;)
– Context is the Nonce decoded from blob
– Label is the OIDs of the encryption algorithms decoded from blob
– Outputs keys to use for AES encryption as well as SHA256 HMAC for verification of
ciphertext
Key Derivation
47
-
46.
©2019 FireEye©2019 FireEye
Decrypts using Windows Crypto
libraries
AES128 in CBC mode
– 16 byte key derived from the DKM
key
– 16 byte IV decoded from the
EncryptedPfx blob
Valid for 1 year!!
Key Decryption
48
-
47.
©2019 FireEye©2019 FireEye49
Putting it all together
1. EncryptedPFX read from the
configuration DB
2. ASN1 types and ciphertext
parsed from the blob
3. DKM key read from AD
4. DKM key used for KDF to obtain
AES key
5. Ciphertext from EncryptedPFX is
decrypted into a PKCS12 object
6. Become an AD FS server – sign
our own security tokens
-
48.
©2019 FireEye©2019 FireEye
AD FS handles "strong authentication"
– MFA
– Certs
– Blood-oath
If we can issue security tokens, then we can
just ignore these requirements
Relying Parties are blind to these requirements
anyway, they just want a valid token
"But I have MFA so I'm good"
50
-
49.
Tool Time
-
50.
©2019 FireEye©2019 FireEye
https://github.com/fireeye/ADFSDump
.NET Assembly to be run on an AD FS server
Must be run on AD FS server as the AD FS service account
Dumps information from the configuration database and AD needed to generate
signed security tokens and become ADFS :)
– Encrypted PFX
– DKM group key
– Relying parties
– Issuance rules
ADFSDump
52
-
51.
©2019 FireEye©2019 FireEye
https://github.com/fireeye/ADFSpoof
Python program to be run offline
– Designed to be run using the data obtained from ADFSDump
Decrypts EncryptedPfx blob given a DKM key
Generates signed SAML tokens for arbitrary users that can be sent to a Relying
Party
– Uses user-generated XML templates
– Each template requires specific parameters – the claims contained in the RP issuance rules
– Launching with Office 365, Dropbox, and extensible SAML 2.0 templates
ADFSpoof
53
-
52.
©2019 FireEye©2019 FireEye54
-
53.
Best Practices and Mitigations
-
54.
©2019 FireEye©2019 FireEye
Secure privileged access
–The AD FS server should be treated as a Tier 0 device (like a domain
controller)
– Access should be restricted to only originate from privileged access workstations
Enabled advanced auditing on AD FS
– Check “success” and “failure” audit options in AD FS Management snap-in
– Enable “Audit Application Generated” events on the AD FS farm via GPO
Best Practices and Mitigations
56
Before everything goes awry
-
55.
©2019 FireEye©2019 FireEye
Make the AD FS Service account a gMSA
– Passwords managed by AD
High Security: Use a Hardware Security Module (HSM)
While we're at it: Extranet Smart Lockout for AD FS 2016
Best Practices and Mitigations
57
Before everything goes awry
-
56.
©2019 FireEye©2019 FireEye
Identity providers now are part of the incident response process
If you have good visibility and confidence attacker targeted AD FS:
– Reset signing key - carefully
– Compare claims rules/exceptions against baselines
– Verify core adapters are intact
If not – determine your risk rating and act appropriately
Vendor debug logs can be useful in AD FS cloning scenarios
– Not so much with modified adapters...
Responding Appropriately
58
-
57.
FIN
Our goal for you at the end of the talk: Understand how AD FS works, how to attack AD FS and why it is an attractive target for attackers, and how we can keep AD FS safe
So before we can dive into attacking AD FS we need to understand it. Welcome to the whirlwind tour of AD FS
At its most basic AD FS can be defined as…
Lets unpack how this actually works
Before we dive in lets answer an important question – why are we even here? I always find it a good idea to discuss motivations for a talk/research
So let's begin our tour
- the currency of AD FS is claims. Claims are statements that tell us about a user's identiy
- they are going to come from an attribute store, in most cases Active Directory
Claims are acted on by rules which follow a speicfic language
- conditions
- statements
These rules are collected into a pipeline
A very simplified view of our pipeline
- don’t really care about the first inputs
- the last set of rules issuance rules, are what we care about
The output of the issuance rules is the final set of claims that makes its way into the security token
In our previous example use case, the bulk of what AD FS does is when it sources claims (statements about an identity), and processes them into a security token. That process is called the claims pipeline
There are three main stages to the pipeline
After the third stage we have claims that are ready to be packaged into a usable security token
The security tokens are what a relying party is going to ultimately consume
Some key terms to be know before we go further
Lets understand how these different terms come into play with an example use case
Some key terms to be know before we go further
Lets understand how these different terms come into play with an example use case
A typical example of the WebSSO authentication flow using AD FS
User navigates to https;//login.microsoftonline.com
They type in their organization email address and O365 issues a 302 redirect to the AD FS URL, sts.doughcorp.com
The AD FS proxy opens a connection to the AD FS server, presenting a web auth form
The user types in their email address and AD password into the web form
The ADFS server talks to the claim’s provider attribute store, AD to authenticate the user
Upon successful auth, the federation service receives claims from the claims provider, and puts them through the claims pipleline The pipeline checks if the user is authorized, transforms the claims and generate a signed security token
The user’s browser receives the security token and sends it to Office 365 where it is verfieid and exchanged for a usable authentication token (a session cookie)
A typical example of the WebSSO authentication flow using AD FS
User navigates to https;//login.microsoftonline.com
They type in their organization email address and O365 issues a 302 redirect to the AD FS URL, sts.doughcorp.com
The AD FS proxy opens a connection to the AD FS server, presenting a web auth form
The user types in their email address and AD password into the web form
The ADFS server talks to the claim’s provider attribute store, AD to authenticate the user
Upon successful auth, the federation service receives claims from the claims provider, and puts them through the claims pipleline The pipeline checks if the user is authorized, transforms the claims and generate a signed security token
AD FS retrieves these attribute values from the store and creates claims based on that information
The user’s browser receives the security token and sends it to Office 365 where it is verfieid and exchanged for a usable authentication token (a session cookie)
A typical example of the WebSSO authentication flow using AD FS
User navigates to https;//login.microsoftonline.com
They type in their organization email address and O365 issues a 302 redirect to the AD FS URL, sts.doughcorp.com
The AD FS proxy opens a connection to the AD FS server, presenting a web auth form
The user types in their email address and AD password into the web form
The ADFS server talks to the claim’s provider attribute store, AD to authenticate the user
Upon successful auth, the federation service receives claims from the claims provider, and puts them through the claims pipleline The pipeline checks if the user is authorized, transforms the claims and generate a signed security token
The user’s browser receives the security token and sends it to Office 365 where it is verfieid and exchanged for a usable authentication token (a session cookie)
We already talked about how AD FS transforms a user authentication event into a security token which is sent to the relying party
Now we are going to go just a little deeper to understand how AD FS itself is architected
Mention: MSSQL DB another option for structured data storage
When you set up AD FS authentication is configured to only allow the service account
Not even a DA will be able to access the database in its base configuration
Exploring this configuration database we can see a table ServiceSetting
It contains a single row, whose data is a large XML doc
Perusing that document we see a tag “SigningToken” with a child element of “EcnryptedPfx”
Well that looks interesting doesn’t it
- If you look at the XML document from ServiceSetting table it also contains a tag called “DKMsetting” which I thought was interesting
A quick google search showed that it is related to encryption, interesting..
In fact, AD FS uses DKM to store an symmetric key that we can use to decrypt that “EncryptedPFX” blob
Opening up AD explorer we can see the container stored as the following
And we can see besides the groups we would eexpect (DA, EA, etc) the AD FS service account also has read/write permissions over this object..
So lets try and piece together how the DKM key is used to decrypte the Encrypted Signing Token by doing a code walk
AD FS is written entirely in .NET, so we can easily inspect the code using tools such as DnSpy
Eventually we can trace to the LoadCertificateCollection() function
First it tries to load the certificates from the cert store, which is where they get placed after the first service start
If that fails however we can see it reads the EncryptedPFx value, decodes it and then passes it to this “Unprotect” method of the _protector clas
_protector is actually of type DKMDataProtector… we are on the right track
We can see that Unprotect is calling another Unprotect method from a _dkm attribute
This is of type Dkm.Groupkey so we are still on the hunt..
- Finally in the DKMBase class we can see where the magic happens
Unprotect method here is doing a lot of tings
It turns out that the EncryptedPFx binary blob is not a simple data type. Rather it is binary data containing ASN1 types
Those ASN1 types contain important information needed to decrypt the signing certificate. Things the IV for the decryption method, the alrogithm types, and a MAC code for verification
We can also see that the DKM key stored in AD is not actually the decryption key. Rather it serves as input for a Key Derivation function that is used to obtain the actual key we need
We can see here an overview of an example EncryptedPFx binary blob and the different encoded ASN1 types.
The decodeprotectedblob() function is unpacking all these structures
Following the ReadKey method we can see how DKM is acutally used to store data
The key derivation is using the standard Microsoft crypto library
From the name we can see it should follow the NIST standard SP 800-108
After tracing the code I found it is a very close follower of the standard, but not quite
Finally we understand how this works
The EncryptedPFX base64 data is read and decoded from the config database