Easy Parsing of ADFS Security Audit Events

I recently saw an internet meme going around that showed a sticker shaped like a cloud and in the cloud were the words “The Cloud is just someone else’s computer.”.  This is accurate on so many levels. Any company’s cloud solution is simply a series of data centers, geographically managed on the internet so that you find the one network-wise closest to you.

The idea that the cloud is someone else’s computer is exactly why many companies use federation sign on services. A federated sign on configuration in your cloud service simply redirects the user from the cloud sign in page back to the on premise federated sign in servers. 

The configuration, setup and maintenance of federated single sign on to the cloud requires a significant amount of work.

Why would you want to do that?

The answer is simple-control. Requiring that the cloud redirect the user to your premise for sign in to cloud services provides a company a great deal of control on who gets access to the cloud services, where they are allowed to gain that control from, what additional authentication may be required and many more control aspects. This measure of control is quite a discussion point when you are using “someone else’s computer”.

It also gives a great deal of on-premise auditing which can be done if you are using Active Directory Federation Services (AD FS). ADFS can be configured to do service auditing of the user logon in order to reveal a level of detail any national intelligence service would envy. You will learn the version of device a user is connecting from, the application they are using, the IP address of the originating client, the user name and more.

The ”how to” for ADFS auditing Configuring ADFS Servers for Troubleshooting can be found in this TechNet link under the “Configuring ADFS Servers to Record Auditing of ADFS Events to the Security Log” heading.

These audit data points are most commonly used in setting ADFS Client Access Policies. In fact, in the past few years a nice collection of blog and other content has sprung up around configuring those client access policies and claims processing rules.  Client access policies can take those same values which appear in the Security event log as auditing details and make decisions about whether to issue a token to a client, to transform a value received from the client into another value issued in the token, or to challenge the user for additional authentication proof up-essentially a challenge for the user to provide multi factor authentication.

Greater information on scenarios where ADFS client access policies could be used and the values which can be seen in them can be found on TechNet at this link: https://technet.microsoft.com/en-us/library/dn592182.aspx .

The only catch is that the auditing provides approximately 78 events per user logon to ADFS in Server 2012 R2 and earlier versions. Word on the street is that Server 2016’s ADFS verbose auditing will be less, er, verbose and give fewer events but in the meantime 78 is what we get.

How do you make sense of so many events so you can tune your client access or policies or tie together your security forensics?

I’ve written a PowerShell script to make it easier to parse through an ADFS servers Security event log for these events.

He script was written for and tested on Server 2012 R2 ADFS. It is likely to work on prior versions of ADFS but since it hasn’t been tested on them it’s not certain.

You can download the PowerShell script here:

ADFS Security Audit Events Parser (ADFSSecAuditParse.ps1)

https://gallery.technet.microsoft.com/scriptcenter/ADFS-Security-Audit-Events-81c207cf/

More details about the script:

  • The script is intended to run against a “live” Security event log on the ADFS server. It is not written to run against saved logs-though that is possible it is very slow and resource intensive.
  • If you have an ADFS farm the script would need to be ran against each server in the farm (not WAP) in order to collect all of the data you need reliably. Unless you can trick your load balancer with a HOST entry for testing.
  • The script has three switches: SearchCriteria, PastDays and PastHours.
  • SearchCriteria should be a string variable of what you want to search the Security event log for. For example, if I want to see if a user with the universal principal name (UPN) of joebob@contoso.com has logged on and all of the details regarding that logon I would pass in “joebob@contoso.com” or that same string in a variable.
  • Only one SearchCriteria string can be specified at a time.
  • PastDays specifies how many days in the past from current time to search the log. The default is 1.
  • PastHours specifies how many hours to search the log back from current time. Less than an hour can be specified if you’d like-just use decimal. For example, a half hour would be .5.
  • The script searches for instanceIDs which match the SearchCriteria and then searches for all of the matches to that instanceID.
  • The script will find all instanceIDs (token requests) which take place during the specified time and get the event details.
  • The script will find any Security event which contains the instanceID in the event details. For ADFS token requests this is typically events 500, 501 and 299.
  • Each result set based on isntanceID is displayed in the PowerShell console and also piped out to a text file.
  • Each output text file is named %SearchCriteria%-ADFSSecAudit_%Counter%.txt. The counter value is in lieu of the instanceID since instanceIDs are too large for practical file names.

Example text output:

Security Audit Events which match joeuser@contoso.com and instance 3a152fbb-6cda-495a-ac9d-98ce2b98631c in Security event log.

Event ID : 501

Provider : AD FS Auditing

Machine Name : adfsserver1.contoso.com

User ID : S-1-5-21-<snip>

Time Created : 2/4/2016 8:38:18 PM

Value

-----

19d6868b-c074-4afd-990e-d237b4aabb1b

https://schemas.microsoft.com/2012/01/requestcontext/claims/client-request-id

00000000-0000-0000-6300-0080000000d3

https://schemas.microsoft.com/2012/01/requestcontext/claims/relyingpartytrustid

https://login.microsoftonline.com/login.srf

https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip

192.168.1.23

https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip

192.168.1.23

https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-ip

10.0.0.9

Event ID : 501

Provider : AD FS Auditing

Machine Name : adfsserver1.contoso.com

User ID : S-1-5-21-<snip>

Time Created : 2/4/2016 8:38:18 PM

Value

-----

19d6868b-c074-4afd-990e-d237b4aabb1b

https://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid

S-1-1-0

https://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid

S-1-5-32-545

https://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid

S-1-5-2

https://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid

S-1-5-11

https://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid

S-1-5-15

https://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid

S-1-18-2

https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-user-agent

Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko

https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path

/adfs/ls/

https://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork

false

https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy

contosowap1

Event ID : 501

Provider : AD FS Auditing

Machine Name : adfsserver1.contoso.com

User ID : S-1-5-21-<snip>

Time Created : 2/4/2016 8:38:18 PM

Value

-----

19d6868b-c074-4afd-990e-d237b4aabb1b

https://schemas.xmlsoap.org/ws/2005/05/identity/claims/implicitupn

joeuser@tspring.com

https://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod

urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport

https://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationinstant

2016-02-04T20:38:18.701Z

https://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn

joeuser@contoso.com

https://schemas.microsoft.com/ws/2008/06/identity/claims/primarygroupsid

S-1-5-21-<snip>-513

https://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid

S-1-5-21-<snip>-1107

https://schemas.xmlsoap.org/ws/2005/05/identity/claims/name

CONTOSO\joeuser

https://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname

CONTOSO\joeuser

https://schemas.microsoft.com/claims/authnmethodsreferences

urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport

https://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid

S-1-5-21-<snip>-513

I sincerely hope using this PowerShell script helps you in day to day activities, setting things up in a new client access policy, or your forensic peek under the covers.