Workplace join as seen by Fiddler

Workplace join (WPJ) was first introduced in Windows 8.1 but was then back ported to Windows 7. Workplace join uses the device registration service (DRS) on AD FS or Azure AD to get a certificate to authenticate the device.

Fiddler is a useful tool to examine HTTP traffic. And here is how we can use it to see what happens at the device side during a workplace join.

Basics for configuring Fiddler are

  1. Install Fiddler from here
  2. Enable HTTP decryption as per  this article
  3. Follow this article to avoid issues with extended protection if using DRS on AD FS via Windows Integrated Auth while using Fiddler on your corporate network. Else, this can be skipped.
  4. Use the this doc allow the modern settings app in Windows 8.1 and above to be traced via Fiddler.

 

The remainder of the article will examine data collected for a Windows 8.1 PC while it was doing a workplace join.

The trace below was collected while doing WPJ via a Web Application Proxy (WAP).

Lets start with the discovery request.

image

JSON tab in Fiddler is useful to view the response.

Here the response from “https://EnterpriseRegistration.maweeras2.lab/EnrollmentServer/contract?api-version=1.0” shows the OAuth endpoints we should use to get authorization codes and then access tokens. The DRS endpoint that will issue the cert is also shown here.

If you check the client side, Workplace Join/Admin event log (accessed via Applications and Services\Microsoft\Windows) you will note event 100 with this text.

Workplace Join discovery succeeded. Activity Id: NULL

Click on details to see the full event along with discovered info.

<Event xmlns=”http://schemas.microsoft.com/win/2004/08/events/event”>
<System>
<Provider Name=”Microsoft-Windows-Workplace Join” Guid=”{76AB12D5-C986-4E60-9D7C-2A092B284CDD}” />
<EventID>100</EventID>
<Version>0</Version>
<Level>4</Level>
<Task>0</Task>
<Opcode>0</Opcode>
<Keywords>0x8000000000000000</Keywords>
<TimeCreated SystemTime=”2015-12-05T13:05:02.090168300Z” />
<EventRecordID>29</EventRecordID>
<Correlation />
<Execution ProcessID=”2264″ ThreadID=”4484″ />
<Channel>Microsoft-Windows-Workplace Join/Admin</Channel>
<Computer>PC1.maweeras2.lab</Computer>
<Security UserID=”S-1-5-21-194226691-3252264409-2149212596-1109″ />
</System>
<EventData>
<Data Name=”ActivityId”>NULL</Data>
<Data Name=”JWT”>{“DeviceRegistrationService”:{“RegistrationEndpoint”:”https:\/\/sts.maweeras2.lab\/EnrollmentServer\/DeviceEnrollmentWebService.svc”,”RegistrationResourceId”:”urn:ms-drs:sts.maweeras2.lab”,”ServiceVersion”:”1.0″},”AuthenticationService”:{“OAuth2”:{“AuthCodeEndpoint”:”https:\/\/sts.maweeras2.lab\/adfs\/oauth2\/authorize”,”TokenEndpoint”:”https:\/\/sts.maweeras2.lab\/adfs\/oauth2\/token”}},”IdentityProviderService”:{“PassiveAuthEndpoint”:”https:\/\/sts.maweeras2.lab\/adfs\/ls”}}</Data>
</EventData>
</Event>

In the next frame below we see the attempts to use OAuth2 and get an authorization token. Here is the raw request header.

GET https://sts.maweeras2.lab/adfs/oauth2/authorize?response_type=code&client_id=dd762716-544d-4aeb-a526-687b73838a22&resource=urn:ms-drs:sts.maweeras2.lab&redirect_uri=ms-app%3A%2F%2Fwindows.immersivecontrolpanel&login_hint=mw%40maweeras2.lab HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Accept-Language: en-GB
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64; Trident/7.0; MSAuthHost/1.0/In-Domain; rv:11.0) like Gecko
UA-CPU: AMD64
Accept-Encoding: gzip, deflate
Host: sts.maweeras2.lab
Connection: Keep-Alive

The highlighted guid is the unique OAuth2 Client ID known to AD FS that identifies this request issuer as device registration client (for workplace join) running on the Windows 8.1 PC (invoked from the modern settings app). All Windows PC’s will use this hard coded guid.

image

I am using the webview tab in the bottom pane to show the forms based auth (FBA) page rendered while accessing the WAP. As the global authentication policy on my AD FS farm has configured only FBA for extranet I am presented with this FBA page.

I have not configured any requirement to do MFA when requesting tokens for the DRS endpoint externally via WAP as this is a lab. In production environments some MFA use is recommended.

We now see the response to the credentials been posted.

image

Note the credentials seen in the clear within the Fiddler POST request.

We get a 302 redirect which is the same request as earlier but with an added ssocookie parameter in the query string.  We also have a cookie to represent the credentials posted.

image

The cookie is validated and MSISAuth cookie is set indicating authentication was successful. We have an authorization code returned in a 302 redirect. The client side modern settings app as the OAuth2 client will use this authorization code to now get an access token.

image

 

We have a bearer token now. We see its valid for an hour.

Lets decode the value in “access_token” via http://authnauthz.com or http://jwt.io

Header section has…

{

“typ”: “JWT”,

“alg”: “RS256”,

“x5t”: “NT7XQomMBJvC5hovEkWcpY7WhVA”

}

Data section has …

{

“aud”: “urn:ms-drs:sts.maweeras2.lab”,

“iss”: “http://sts.maweeras2.lab/adfs/services/trust“,

“iat”: 1449320718,

“exp”: 1449324318,

http://schemas.xmlsoap.org/ws/2005/05/identity/claims/implicitupn“: “mw@maweeras2.lab”,

“pwdexptime”: “2016-01-16T13:04:45.812Z”,

“authmethod”: “urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport”,

“auth_time”: “2015-12-05T13:05:18.610Z”,

“upn”: “mw@maweeras2.lab”,

“primarysid”: “S-1-5-21-194226691-3252264409-2149212596-1109”,

“unique_name”: “MAWEERAS2\\mw”,

“winaccountname”: “MAWEERAS2\\mw”,

“amr”: “urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport”,

“clientuseragent”: “Mozilla/5.0 (Windows NT 6.3; Win64; x64; Trident/7.0; MSAuthHost/1.0/In-Domain; rv:11.0) like Gecko”,

“endpointpath”: “/adfs/oauth2/authorize”,

“insidecorpnetwork”: “false”,

“proxy”: “wap1”,

“clientreqid”: “00000000-0000-0000-0f00-0080000000cc”,

“forwardedclientip”: “10.1.1.4”,

“clientip”: “10.1.1.3”,

http://schemas.microsoft.com/authorization/claims/PermitDeviceRegistration“: “true”,

“ver”: “1.0”,

“appid”: “dd762716-544d-4aeb-a526-687b73838a22”

}

forwarded-client-ip represents the IP address seen by WAP when it received the request. It forwards this to AD FS. As my PC directly accessed WAP (without going via firewalls or NAT devices) the WAP saw my real client PC IP address.

client-ip is actually the WAP server’s IP address.

This access token will now be used to obtain a certificate from DRS. Note that request in the next frame.

image

Here we see the SOAP header in the request containing the Base64 encoded JWT token (access token) we received earlier. If you scroll down in the request you will see a PKCS10 request representing a request for a certificate.

AD FS process this request and sends a RSTR containing the signed cert and other info. Its received as a Base64 encoded binary blob. The XML tab is useful to see the relevant fields.

If curious you can read up more about the payload and its contents here.

The client side Workplace Join Admin event log will now have event 201 with text similar to below.

Workplace Join operation succeeded. Activity Id: 5d711a21-6f82-4178-8314-9b08da34490c
Registration Service URI: https://sts.maweeras2.lab/EnrollmentServer/DeviceEnrollmentWebService.svc

Click details to see full event like so.

<Event xmlns=”http://schemas.microsoft.com/win/2004/08/events/event”&gt;
<System>
<Provider Name=”Microsoft-Windows-Workplace Join” Guid=”{76AB12D5-C986-4E60-9D7C-2A092B284CDD}” />
<EventID>201</EventID>
<Version>0</Version>
<Level>4</Level>
<Task>0</Task>
<Opcode>0</Opcode>
<Keywords>0x8000000000000000</Keywords>
<TimeCreated SystemTime=”2015-12-05T13:05:26.605287300Z” />
<EventRecordID>30</EventRecordID>
<Correlation />
<Execution ProcessID=”2264″ ThreadID=”4484″ />
<Channel>Microsoft-Windows-Workplace Join/Admin</Channel>
<Computer>PC1.maweeras2.lab</Computer>
<Security UserID=”S-1-5-21-194226691-3252264409-2149212596-1109″ />
</System>
<EventData>
<Data Name=”ActivityId”>5d711a21-6f82-4178-8314-9b08da34490c</Data>
<Data Name=”SoapResponse”>&lt;s:Envelope xmlns:s=”http://www.w3.org/2003/05/soap-envelope&#8221; xmlns:a=”http://www.w3.org/2005/08/addressing”&gt;&lt;s:Header&gt;&lt;a:Action s:mustUnderstand=”1″&gt;http://schemas.microsoft.com/windows/pki/2009/01/enrollment/RSTRC/wstep&lt;/a:Action&gt;&lt;ActivityId CorrelationId=”34171a3c-603c-4fd8-b6fe-ebb35c21cf63″ xmlns=”http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics”&gt;5d711a21-6f82-4178-8314-9b08da34490c&lt;/ActivityId&gt;&lt;a:RelatesTo&gt;urn:uuid:0d5a1441-5891-453b-becf-a2e5f6ea3749&lt;/a:RelatesTo&gt;&lt;/s:Header&gt;&lt;s:Body&gt;&lt;RequestSecurityTokenResponseCollection xmlns=”http://docs.oasis-open.org/ws-sx/ws-trust/200512″&gt;&lt;RequestSecurityTokenResponse&gt;&lt;TokenType&gt;http://schemas.microsoft.com/5.0.0.0/ConfigurationManager/Enrollment/DeviceEnrollmentToken&lt;/TokenType&gt;&lt;RequestedSecurityToken&gt;&lt;BinarySecurityToken ValueType=”http://schemas.microsoft.com/5.0.0.0/ConfigurationManager/Enrollment/DeviceEnrollmentProvisionDoc&#8221; EncodingType=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#base64binary&#8221; xmlns=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”&gt;PHdhcC1wcm92aXNpb25pbmdkb2MgdmVyc2lvbj0iMS4xIj4NCiAgPGNoYXJhY3RlcmlzdGljIHR5&amp;#xD;
cGU9IkNlcnRpZmljYXRlU3RvcmUiPg0KICAgIDxjaGFyYWN0ZXJpc3RpYyB0eXBlPSJNeSI+DQog&amp;#xD;
ICAgICA8Y2hhcmFjdGVyaXN0aWMgdHlwZT0iVXNlciI+DQogICAgICAgIDxjaGFyYWN0ZXJpc3Rp&amp;#xD;
YyB0eXBlPSI1QjJFNURBNzE3MEI2REEwRTYwMTNEOTgyQ0IyODdDQjFEREVEQ0Y2Ij4NCiAgICAg&amp;#xD;
ICAgICA8cGFybSBuYW1lPSJFbmNvZGVkQ2VydGlmaWNhdGUiIHZhbHVlPSJNSUlFRXpDQ0F2dWdB&amp;#xD;
d0lCQWdJUUJZbCtCc1QyeGI5TEZvRmdBU2ZaRWpBTkJna3Foa2lHOXcwQkFRc0ZBREI2TVhnd0VR&amp;#xD;
WUtDWkltaVpQeUxHUUJHUllEYkdGaU1CY0dDZ21TSm9tVDhpeGtBUmtXQ1cxaGQyVmxjbUZ6TWpB&amp;#xD;
ZEJnTlZCQU1URmsxVExVOXlaMkZ1YVhwaGRHbHZiaTFCWTJObGMzTXdLd1lEVlFRTEV5UmlNelZq&amp;#xD;
TnpsaE1pMDFZek0zTFRSbU1HWXRZV1l4TkMwd09HVXdZVGRoTlRSbU4yRXdIaGNOTVRVeE1qQTFN&amp;#xD;
VE13TURJMFdoY05NalV4TWpBeU1UTXdOVEkwV2pBdk1TMHdLd1lEVlFRREV5UXlaVGhrWWpFeE1p&amp;#xD;
MWlaR1JsTFRRM09UUXRZbVl3TUMxallXUmlabVU0TkRRek5ERXdnZ0VpTUEwR0NTcUdTSWIzRFFF&amp;#xD;
QkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDYlY0Zzg1Vkx2RUo3WVd5b0hzWW9aOFJpWVBaRjdBSE9K&amp;#xD;
aHJmMWRBV0xQbnJuekRqVGZsQlkvR3dmY3ZGbU9BdUhFUFZpZEEvZEdiSnNTQVl0dlJvc0w1aUl1&amp;#xD;
Q25qVlZmS0ZZU0RXdlZDbVFjMHdjWWVmemV2dHdCUDFmaURlM2UwUUdYclVrYWRlZVI4Z3Exb1Rj&amp;#xD;
WU01RGhzbnFZUnZSbW1jQWlKVkhOV1d5OUVjU2xCeGtmVk10MW9kdzM3clF2YlllT3crRWxvYUFi&amp;#xD;
NzZqWW1UYllGYVFUQmN0VTNVdVBqOEM0S0c3am11TjcwdW5tcFk3Ti81enljblROVlhjTUxHUWVs&amp;#xD;
dFMxS0J5a0JYQndLUFU4OStJMlZCVHM5akV1SnB2VmlnOW5SVFlxdjA3bjRBUFJzbGw3Mmd6MWY0&amp;#xD;
b1ZpSEhhd3diZUhuaTZlRXZrcThvSW5BZ01CQUFHQkVRRHh2Mk5ZRytMZVFxbXI0REY2Qm5ZUmdo&amp;#xD;
RUFFckdOTHQ2OWxFZS9BTXJiL29SRFFhT0J1VENCdGpBTUJnTlZIUk1CQWY4RUFqQUFNQ0lHQ3lx&amp;#xD;
R1NJYjNGQUVGZ2h3REJCTUVnUkRUa0tXQjE0bG1TSmpZc0pQKzVJWmNNQ0lHQ3lxR1NJYjNGQUVG&amp;#xD;
Z2h3Q0JCTUVnUkFTc1kwdTNyMlVSNzhBeXR2K2hFTkJNQ0lHQ3lxR1NJYjNGQUVGZ2h3RUJCTUVn&amp;#xD;
UkN4VFluNkpNMDdSSWRRUjc2WEpwTGRNQllHQTFVZEpRRUIvd1FNTUFvR0NDc0dBUVVGQndNQ01D&amp;#xD;
SUdDeXFHU0liM0ZBRUZnaHdCQkJNRWdSQllrak91bDcrTlRvZ0RqWW84Q3I4YU1BMEdDU3FHU0li&amp;#xD;
M0RRRUJDd1VBQTRJQkFRQ29LSVlQa2QrTG5GWVBad2ZmejZ3R0hGam5DcmM2NzB6YjAxMHhaU1o3&amp;#xD;
ckR3V1dSWXVZZWVXKzcvOTRsbFRJdjk2OWhMd0NXN20ybUIrWXBZYzlPTEpLTFowYmV2Y3Z6dFNT&amp;#xD;
NUxHUThZRSt2R25CUHdoT2NlNnp3SGhRT1VyczE0UmwvY1lSSTZmRXVlTUxueDJmaXhVOC85NE9u&amp;#xD;
eTljU1p1V1JWa1hGdzFHek1IYmZMaGIzRVA5Mzcray9RcEZvYmQrSkdFWjRneWhxbmF4cktMUkFR&amp;#xD;
V2tDYWJlUjgweXBUNUFzQnZTN3N5akdaT0c0ZGJwb09LMDYvV3EvY0h0OHp6V2xLbkJEdjRTUkcz&amp;#xD;
OTVJSnBzZW9lNFZTK2JKOXlKUEdNNCtOSHF2aDlFK2x1Q3ozTVllMTBYR2t6MVM1bmZRRytrNC9n&amp;#xD;
bkhXdVBnakJNSzJBQlB4IiAvPg0KICAgICAgICA8L2NoYXJhY3RlcmlzdGljPg0KICAgICAgPC9j&amp;#xD;
aGFyYWN0ZXJpc3RpYz4NCiAgICA8L2NoYXJhY3RlcmlzdGljPg0KICA8L2NoYXJhY3RlcmlzdGlj&amp;#xD;
Pg0KPC93YXAtcHJvdmlzaW9uaW5nZG9jPg==&lt;/BinarySecurityToken&gt;&lt;/RequestedSecurityToken&gt;&lt;RequestID xmlns=”http://schemas.microsoft.com/windows/pki/2009/01/enrollment”&gt;0&lt;/RequestID&gt;&lt;AdditionalContext xmlns=”http://schemas.xmlsoap.org/ws/2006/12/authorization”&gt;&lt;ContextItem Name=”UserPrincipalName”&gt;&lt;Value&gt;mw@maweeras2.lab&lt;/Value&gt;&lt;/ContextItem&gt;&lt;/AdditionalContext&gt;&lt;/RequestSecurityTokenResponse&gt;&lt;/RequestSecurityTokenResponseCollection&gt;&lt;/s:Body&gt;&lt;/s:Envelope&gt;</Data>
<Data Name=”RegistrationServiceUri”>https://sts.maweeras2.lab/EnrollmentServer/DeviceEnrollmentWebService.svc</Data&gt;
</EventData>
</Event>

 

This cert is installed in the user store for the requesting user (mw@maweeras2.lab). You can see it via certmgr.msc .

or PowerShell like so.

PS C:\Users\mw.MAWEERAS2> dir Cert:\CurrentUser\My | Where-Object {$_.issuer -match ‘ms-org’} | fl
Subject : CN=2e8db112-bdde-4794-bf00-cadbfe844341
Issuer : DC=lab + DC=maweeras2 + CN=MS-Organization-Access + OU=b35c79a2-5c37-4f0f-af14-08e0a7a54f7a
Thumbprint : 5B2E5DA7170B6DA0E6013D982CB287CB1DDEDCF6
FriendlyName :
NotBefore : 05/12/2015 13:00:24
NotAfter : 02/12/2025 13:05:24
Extensions : {System.Security.Cryptography.Oid, System.Security.Cryptography.Oid, System.Security.Cryptography.Oid,
System.Security.Cryptography.Oid…}

 

We can now look in AD to see the object representing this device.

Here is the object’s dump from ldp.exe.

Expanding base ‘CN=2e8db112-bdde-4794-bf00-cadbfe844341,CN=RegisteredDevices,DC=maweeras2,DC=lab’…
Getting 1 entries:
Dn: CN=2e8db112-bdde-4794-bf00-cadbfe844341,CN=RegisteredDevices,DC=maweeras2,DC=lab
altSecurityIdentities: X509:<SHA1-TP-PUBKEY>5B2E5DA7170B6DA0E6013D982CB287CB1DDEDCF6td6Sl8QssMQnIgD5mao8GPWQtL36xeBB80Gxpm4GFIY=;
cn: 2e8db112-bdde-4794-bf00-cadbfe844341;
displayName: PC1;
distinguishedName: CN=2e8db112-bdde-4794-bf00-cadbfe844341,CN=RegisteredDevices,DC=maweeras2,DC=lab;
dSCorePropagationData: 0x0 = ( );
instanceType: 0x4 = ( WRITE );
msDS-ApproximateLastLogonTimeStamp: 130937943261311661;
msDS-CloudIsManaged: FALSE;
msDS-DeviceID: <ldp: Binary blob 16 bytes>;
msDS-DeviceObjectVersion: 1;
msDS-DeviceOSType: Windows;
msDS-DeviceOSVersion: 6.3.9600.0;
msDS-IsEnabled: TRUE;
msDS-IsManaged: FALSE;
msDS-RegisteredOwner: S-1-5-21-194226691-3252264409-2149212596-1109;
msDS-RegisteredUsers: S-1-5-21-194226691-3252264409-2149212596-1109;
name: 2e8db112-bdde-4794-bf00-cadbfe844341;
objectCategory: CN=ms-DS-Device,CN=Schema,CN=Configuration,DC=maweeras2,DC=lab;
objectClass (2): top; msDS-Device;
objectGUID: 95ade505-4d65-4dd6-b8ca-efda9c235053;
showInAdvancedViewOnly: TRUE;
uSNChanged: 40325;
uSNCreated: 40325;
whenChanged: 05/12/2015 13:05:25 GMT Standard Time;
whenCreated: 05/12/2015 13:05:25 GMT Standard Time;

 

And if we convert the SID of the owner using ldp.exe’s Sid Lookup functionality (accessible via utilities menu)

———–
***Calling SidLookup…
MAWEERAS2\mw [S-1-5-21-194226691-3252264409-2149212596-1109]
———–

mw@maweeras2.lab is indeed the user that registered the device. 🙂

If you want to view the fiddler trace yourself you can get it from here.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s