"Kerberos delegation .. end to end" Part III
When we last left off, we had just installed SQL.
Also my standard disclaimer for this series:
First off let me say that I am not a “SQL guy” nor am I an “IIS guy” .. I am primarily a platforms OS kinda guy.
However, I can wing my way thru some of those two technologies. This series of posts may not exactly follow best practices when it comes to SQL or IIS but it will definitely get you up and running.
You may be thinking, there are already a ton of resources to show how to get this up and running. Simply use your favorite search engine and look for ‘Kerberos delegation SQL’ and you will find dozens of HOW TO articles, blogs etc..
I am hoping that this one will differ in two ways. One, is that it is an exact step by step. Two, is that we will go into the WHY’s of why we do certain actions to make it all work ( mostly from an OS authentication perspective ) .
OK – so back to when we left off.
After we had installed SQL and tried to connect from the client machine we got this error:
Exception Details: System.Data.SqlClient.SqlException: Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'.
The IIS Server was connecting as anonymous due to the fact it could not impersonate Bob , or in kerberos terms it was not enabled for delegation.
More specifically - “it” in the above sentence is the service account domain\SVC_IISPool under which the web site was running as.
Let’s fix that. On the DC open the SVC_IISPool account and enable it for “trust this user for delegation” – don’t worry about all the other knobs and switches for now.
Once you do this, and grant Bob proper SQL rights to read the database, you should see the page come up OK as Bob.
Here is a list of some of the tools we will use to examine the transaction in more detail:.
Klist.exe
Kerbtray.exe
Wireshark
Netmon3
Netmon2
The reason I use all those different net sniffers is just because I like certain features from each one.
When it comes to delegation, https://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/distrib/dscd_aun_ndxr.mspx?mfr=true states:
Multi-tier client/server applications present a special situation for the Kerberos protocol. In this kind of application, a client might connect to a server that must connect to a second server on the back end. For this to happen, the first server must have a session ticket to the second server. Ideally, this session ticket should limit the first server's access on the second server to what the client is authorized to do, rather than what the server is authorized to do.
The Kerberos protocol deals with this situation through a mechanism known as delegation of authentication . Essentially, the client delegates authentication to a server by telling the KDC that the server is authorized to represent the client.
<snip>
Forwarded Tickets
If a client wants to delegate the task of obtaining session tickets for a back-end server to a front-end server, it must ask the KDC for a forwardable TGT. It does this through an AS Exchange by indicating to the KDC the name of the server that will act on the client's behalf. If Kerberos policy permits forwarding, the KDC creates a TGT for the front-end server to use in the client's name, sets the FORWARDABLE flag in the TGT, and sends the ticket back to the client. The client then forwards the TGT to the front-end server.
When the front-end server requests a session ticket to the back-end server, it presents the client's TGT to the KDC. When the KDC issues a session ticket for the back-end server, it sees the FORWARDABLE flag in the TGT, sets the FORWARDED flag in the session ticket for the requested server, and returns the session ticket to the front-end server. The option of setting the FORWARDED flag in a session ticket provides an added level of security because it permits administrators to configure individual servers to reject session tickets that have been forwarded.
The reason I highlighted the section in blue above - is because I have never actually seen it ( the blue part ) work this way ( read as , I think it is wrong unless someone can show me otherwise )
So let’s take a look at this.
Here is a link to the trace I am looking at below:
This trace is taken on the XP client as he opens the web page.
FRAME 11 and 12:
You can see the typical deny\negotiate HTTP packets – see https://msdn2.microsoft.com/en-us/library/ms995330.aspx for more info on that.
FRAME 14:
We see the TGS request for the HTTP SPN..
FRAME 15.
The KDC responds with the TGS_REP
KERBEROS: Client name (cname[4]) =bob
KERBEROS: Server name (sname[2]) =HTTP/sp132027c.request132027.local
That's all the kerberos or authentication traffic we see after that he get access to the web site.
We seem to be missing something. Where is the forwarded TGT to the IIS Server?
Does the IIS Server ask for the clients TGT? Let’s think about that.
In order to do so, he would need to know Bob’s password, which he does not – so this is not possible ( disregard any S4U thoughts here – we are talking straight unconstrained delegation here )
OK so if the IIS server does not ask for the TGT where is it – let’s look at the same requests from the KDC’s perspective.
See the previous link or the bottom of this post for the actual net traces.
This trace is taken on the KDC as the client opens the web page.
FRAME 30 and 31:
A TGS_REQ and response from the XP machine to authenticate to the HTTP service.
KERBEROS: Server name (sname[3]) =HTTP/sp132027c.request132027.local
FRAME 76
A TGS_REP from the KDC in response to the TGS_REQ from the IIS Server for authentication to the SQL service. Note that the principal name ( authenticated as ) is Bob
KERBEROS: Principal name value (name-string[1]) =bob
KERBEROS: Server name (sname[2]) =MSSQLSvc/sp132027b.request132027.local:1433
For now , that is all we care about. How did we go from the client asking for HTTP to the IIS Server getting a successful TGS_REP for Bob?
BACKGROUND:
Let’s do a clean logon and see where we start off:
I am going to use a combination of 2 tools – klist.exe and kerbtray.exe.
As soon as we logon we can see our tickets via kerbtray.exe
Looks normal, we have our CIFS ( for the SMB connections we made for group policy ) , our LDAP ( for ldap requests ) and our krbtgt ( our TGT ). But why do we have 2 TGT’s?
Look at them closer via the flags tab.
Notice that one has the “forwarded” flag set.
One of them is the “delegation TGT” – or the one which we will pass on to other services when it is needed for delegation.
Can we prove this?
Use klist.exe to purge the tickets “klist purge” and then say yes to purge each one.
Now – look at another net trace when you open IE and go to the web site. See XP_trace2.cap in the file attached to this post.
We see quite a bit more than the first trace. ( remember the client only sent one TGS_REQ for HTTP ? )
This time we see the HTTP/1.1 401 Unauthorized, then some ldap and dns, and then an AS_REQ
FRAME 20\21
TGT request.
KERBEROS: Principal name value (name-string[1]) =bob
KERBEROS: Server name (sname[3]) =krbtgt/REQUEST132027.LOCAL
Then we see two TGS_REQ’s
FRAME 22\23
TGS_REP data shows:
KERBEROS: Principal name value (name-string[1]) =bob
KERBEROS: Realm (realm[1]) =REQUEST132027.LOCAL
KERBEROS: Server name (sname[2]) =HTTP/sp132027c.request132027.local
FRAME 25
This is the TGS_REP
KERBEROS: Principal name value (name-string[1]) =bob
KERBEROS: Realm (realm[1]) =REQUEST132027.LOCAL
KERBEROS: Server name (sname[2]) =krbtgt/REQUEST132027.LOCAL
Now that’s an odd TGS reply .. krbtgt?
Why isn’t it coming across as an AS_REQ?
In fact, this is a special TGS_REQ, it is a delegation TGT request, which is satisfied via a TGS request.
Look at the request ( frame 24 ) closer… note the “forwarded bit” which is set. This would indicate that this is a request meant to be forwarded - or as netmon3 parsers put it “this is a request for forwarding.
Forwarded: (..1.............................) Indicates that this is a request for forwarding
KDCOptions: 60810010 (Forwardable, Forwarded, Renewable, Canonicalize, Renewable OK)
It is starting to make sense now.
· Get a TGT via the AS_REQ
· Get the ticket for the HTTP service - HTTP/sp132027c.request132027.local
· Get a delegation TGT - via the TGS_REQ ( fwd'd bit set )
· Pass the delegation TGT on to the IIS Server
· IIS Server requests MSSQLSvc/sp132027b.request132027.local:1433 as Bob
Also note the large HTTP packets which follow – we send 3 frames from the XP to IIS server
If we use wireshark to open this same trace and use Follow TCP stream we can easily see the conversation data
Then to put it all in context here is what we see:
FRAME 14 HTTP/1.1 401 Unauthorized Content-Length: 1656 Content-Type: text/html Server: Microsoft-IIS/6.0 WWW-Authenticate: Negotiate WWW-Authenticate: NTLM X-Powered-By: ASP.NET Date: Thu, 22 Nov 2007 00:17:18 GMT <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "https://www.w3.org/TR/html4/strict.dtd"> <HTML><HEAD><TITLE>You are not authorized to view this page</TITLE> <META HTTP-EQUIV="Content-Type" Content="text/html; charset=Windows-1252"> <STYLE type="text/css"> BODY { font: 8pt/12pt verdana } H1 { font: 13pt/15pt verdana } H2 { font: 8pt/12pt verdana } A:link { color: red } A:visited { color: maroon } </STYLE> </HEAD><BODY><TABLE width=500 border=0 cellspacing=10><TR><TD> <h1>You are not authorized to view this page</h1> You do not have permission to view this directory or page using the credentials that you supplied because your Web browser is sending a WWW-Authenticate header field that the Web server is not configured to ccept. <hr> <p>Please try the following:</p> <ul> li>Contact the Web site administrator if you believe you should be able to view this directory or page.</li> <li>Click the <a href="javascript:location.reload()" mce_href="javascript:location.reload()">Refresh</a> button to try again with different credentials.</li> </ul> <h2>HTTP Error 401.2 - Unauthorized: Access is denied due to server configuration.<br>Internet Information Services (IIS)</h2> <hr> <p>Technical Information (for support personnel)</p> <ul> <li> Go to <a href="https://go.microsoft.com/fwlink/?linkid=8180" mce_href="https://go.microsoft.com/fwlink/?linkid=8180">Microsoft Product Support Services</a> and perform a title search for the words <b>HTTP</b> and <b>401</b>.</li> <li>Open <b>IIS Help</b>, which is accessible in IIS Manager (inetmgr), and search for topics titled <b>About Security</b>, <b>Authentication</b>, and <b>About Custom Error Messages</b>.</li> </ul> </TD></TR></TABLE></BODY></HTML> |
FRAME 20\21 TGT request. KERBEROS: KRB_AS_REQ KERBEROS: Principal name value (name-string[1]) =bob KERBEROS: Server name (sname[3]) =krbtgt/REQUEST132027.LOCAL
|
FRAME 22\23 TGS_REP data shows: KERBEROS: KRB_TGS_REP KERBEROS: Principal name value (name-string[1]) =bob KERBEROS: Realm (realm[1]) =REQUEST132027.LOCAL KERBEROS: Server name (sname[2]) =HTTP/sp132027c.request132027.local |
FRAME 25 KDCOptions: 40810000 (Forwardable, Renewable, Canonicalize) This is the TGS_REP KERBEROS: KRB_TGS_REP KERBEROS: Principal name value (name-string[1]) =bob KERBEROS: Realm (realm[1]) =REQUEST132027.LOCAL KERBEROS: Server name (sname[2]) =krbtgt/REQUEST132027.LOCAL |
FRAME 26,27,28 GET / HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, */* Accept-Language: en-us UA-CPU: x86 Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727) Host: sp132027c Connection: Keep-Alive Authorization: Negotiate YIIJowYGKwYBBQUCoIIJlzCCCZOgJDAiBgkqhkiC9xIBAgIGCSqGSIb3EgECAgYKKwYBBAGCNwICCqKCCWkEggllYIIJYQYJKo ZIhvcSAQICAQBugglQMIIJTKADAgEFoQMCAQ6iBwMFACAAAACjggOnYYIDozCCA5+gAwIBBaEVGxNSRVFVRVNUMTMyMDI3LkxPQ0FMojAwLqADAg ECoScwJRsESFRUUBsdc3AxMzIwMjdjLnJlcXVlc3QxMzIwMjcubG9jYWyjggNNMIIDSaADAgEXoQMCAQKiggM7BIIDN8Mm+bApDyh+NYtEzvSPOBt/b vre6ypVisKBYfT0OEbvrKwb+x6D01AhMBaU4LByQc54yPk82C6+1zvN/1Olp6cd3MxmRh0x3qV6Oz9KSEMsi8gqsBDv3RWHGubyXSqklYuVtDHeYf8 CBcCNCDOf0Si6cdhs+inwSv6aTG32asllC23xXVf8tlC0UqmZNlYlqNkOEySLAWYBs7mMkHOjshSpC+iTxLK884tdY1mfUSqqKzLLDWWTGGqK9nw0k FHtk+2I1YwvhgHOcHI0+Mv7pME/tNVcVONL9GNPF/M/r2uErP5P5QyUm89wkY2DWi8m1UkzXumDJl7IW+8jRW/H8I4c2nlsQ3jNMOE0Ct1KIGDsPWs 4W9I4vfQ0qUUwg/iOn2PU03sM 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 |
Frames 26,27,28 are the HTTP get requests, which include the Kerberos data.
In Kerberos terms – this is the AP_REQ. We include the data from the TGS_REQ for HTTP as well as the delegationTGT in this data.
Wheww .. OK so now we know how the basics of delegation work. The client code will call InitializeSecurityContext and pass ISC_REQ_DELEGATE if you want a breakpoint there in IE.
As you probably know, this form of delegation is not secured against malicious use by the server or the SVC_IISPool account. In fact, now that this service has Bob’s TGT he can do most anything with it.
This brings up constrained delegation and something we call S4U.
Next up – constrained delegation details.
Spatdsg
Comments
Anonymous
January 31, 2008
I enjoy these deep dives immensely. Looking forward too constrained delegation. Keep up the good work! LerunAnonymous
February 01, 2008
So...when we'll have a pleasure to read "Part IV" :)?Anonymous
March 18, 2008
Hopefully part 5 will be "getting this all to work with NLB" ;) Which is the piece I am currently having issues with.Anonymous
April 14, 2008
Last week, I spent an all-nighter troubleshooting a Kerberos issue for a MOSS installation. AlthoughAnonymous
April 16, 2008
So much information to digest - thank you!. We are running into this issue intermittantly (Login failed for user 'NT AUTHORITYANONYMOUS LOGON'). The App pool is configured to use Network Service so in your example above you gave permissions for delegation to the service running your app pool (SVC_IISPool) - there is no specific "Network Service" user to configure. We added delegation to the IIS Server itself to be able to delegate the MSSQLSvc on the database server. Like I said, it's intermittant - one minute it's working, then next it is not! Any tips to trap and correct this behavior?Anonymous
April 16, 2008
did you enable the kerberos logging I outlined? That - and a network sniff ( if you can get one ) will be really helpful. Also we want to see the security audit logs to track where the logon worked and or failed as the end user.Anonymous
January 10, 2009
GmOVcL <a href="http://mjegmczqtdao.com/">mjegmczqtdao</a>, [url=http://wbswjutneggk.com/]wbswjutneggk[/url], [link=http://hoblelmmtekq.com/]hoblelmmtekq[/link], http://oxicvrbkyplc.com/