"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.

k31

Once you do this, and grant Bob proper SQL rights to read the database, you should see the page come up OK as Bob.

k32

 

 

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.

 

k33

 

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.

 

k34

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.

k35

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

 

k36

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.

k37

k38

 

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.

 

k39

 

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)

 

k310

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

k311

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

traces.zip