Confusion about Kerberos, delegation and SPNs - kerberos

I'm trying to write a proof-of-concept application that performs Kerberos delegation. I've written all the code, and it seems to working (I'm authenticating fine), but the resulting security context doesn't have the ISC_REQ_DELEGATE flag set.
So I'm thinking that maybe one of the endpoints (client or server) is forbidden to delegate. However I'm not authenticating against an SPN. Just one domain user against another domain user. As the SPN for InitializeSecurityContext() I'm passing "someuser#mydomain.lan" (which is the user account under which the server application is running). As I understand, domain users have delegation enabled by default. Anyway, I asked the admin to check, and the "account is sensitive and cannot be delegated" checkbox is off.
I know that if my server was running as a NETWORK SERVICE and I used an SPN to connect to it, then I'd need the computer account in AD to have the "Trust computer for delegation" checkbox checked (off by default), but... this is not the case, right? Or is it?
Also - when the checkbox in the computer account is set, do the changes take place immediately, or must I reboot the server PC or wait for a while?

According to this ISC_REQ_DELEGATE is only ignored if you use constrained delegation. I'm pretty sure for constrained delegation to happen, you have to explicitly state which services the account is allowed to delegate to in Active Directory (delegation tab for a user or computer in the AD snap in).
I'm not sure of the rules using UPNs vs SPNs. Have you tried turning on Kerberos event logging and looking in the event log? The messages are often cryptic but usually possible to decipher.
Your description of the NETWORK SERVICE scenario is accurate. Trust for delegation is off by default, but NETWORK SERVICE might have permission to self register an SPN (I think this can be determined by group policy).
When you tick the box the change takes place immediately, but may have to propogate throughout all the domain controllers in the domain (I typically test in a test domain with a single DC). So, restarting your service app is enough, you don't need to reboot.
The Kerb tickets reside on the client machine. These have an expiry time, and can be flushed manually using klist or kerbtray.

Related

Securing JEA (Just Enough Administration)

I have recently deployed a JEA endpoint on a few Domain Controllers for a user (Domain User, non privileged).
The user had to be added to "Remote Management Users" AD group in order to have the ability to Powershell into a these DCs.
It occurred to me that outside of the provided, confined endpoint, the user can create sessions to default Powershell endpoint which has access to everything.
Following the great article, I would have to add the user under the permissions of the default windows.powershell endpoint which isn't a straight forward process.
What would be the sensible way to confine the given user to just the one particular endpoint?
Many thanks,

Limit user authentication by IP with PowerShell

After 2 days searching on the internet cannot find a way to limit user authentication by IP range.
I have 2 rodc(A and B) and a RWDC. I have user1 in my RWDC active directory.
I want to specify a user to RODC A, but both clients in both RODC can login to windows with user1.
Is there any way to limit user authentication by IP using PowerShell.
To agree with #Vasili Syrakis, how you are describing your problem, you have to do this with firewalls, or routing on your managed switch.
AD is designed for authentication of users. All it does is verify that the user exists, is a member of the appropriate groups, passwords match, is not disabled, and that's it. AD does no validation based on IP address, and is not capable, or designed for doing that.
You have to change the way you are thinking. Don't think about trying to limit user authentication, let AD do it's job and authenticate the user. You have to think about it in terms of limiting access to the resource.
How you limit access to the resource really depends on what the resource is. If you want to limit it at the Server level (i.e. don't allow anyone from 192.168.1.xxx subnet get to me), then you have to have a firewall or switch that manages access control. Firewalls and access control lists are designed to do this. They won't let the user even reach the resource, and so they won't even get the chance to authenticate with AD.
If it is specific computers (not necessarily IP addresses) that you want to stop people from logging into, then you do that with a combination of AD Groups and Group Policy See: Deny and Allow Logons with Group Policy

Jabber auto-login with random name

I'm building a live chat using JSJaC and ejabberd . It's all working except that all site visitors are given the account 'guest'. If two visitors try to livechat at the same time the responses get muddled or the first user is logged out.
I can randomly set the guest name but then I need to check whether that name is registered or auto-register and hope it hasn't been registered before. I tried assigning each login to a random resource name but this still merged the conversations.
In short i'm looking for the easiest way to allow multiple anonymous logins to start individual conversations with the livechat account. Even better (but optional) if the livechat could round-robin to a different user when the primary livechat account is in a chat.
The solution can be web-client or server based, I don't care since I control both (and ejabberd supports various modules).
BTW, when I try to auto-register a registered account the JSJaC simpleclient demo returns:
An error occured:
Code: 409
Type: cancel
Condition: conflict
I haven't established yet if this is something I can ignore or override with a custom client or server setup. I suppose I could just detect this error and try again without auto-register but I'd like to hear better/easier options.
Try enabling anonymous login mode on your ejabberd server? Then you don't have to register the client accounts, just pick any random username and password and ejabberd should accept them...
I guess you can use external authentication in ejabberd
I'm in the same situation: I want anonymous users to be able to login in the server, but some special users also be able to login for adiminstrative tasks...
So I decided to write a php script as an authentication handler for ejabberd.
Then it will accept all logins with the name starting with anon_*
and authenticate other users against a database.
We had a similar issue in a project - we wanted users to be able to login without requiring any account creation or clashes - auto-registration would not work for us because names could clash. In the end we chose anonymous login with SASL authentication in ejabberd - it allows anonymous login and dynamic account creation and I believe the accounts do not stay on the system (they are alive only whilst the connection is open), however from what I remember the server will generate a random ID for the user.
The GUID JID problem might be able to be solved with the use of Nicknames
Set up SASL
Ejabberd Support Page - SASL
If you can't get ejabberd's anonymous mode working, you might try creating a GUID for each user's base name, and just registering the user on the fly. You'll want to have a periodic script that deletes old unused accounts from the database.

Kerberos, delegation and how to do this correctly?

I've got two separate homemade applications that need to communicate among themselves. One is a frontend application (asp.net actually), the other is a backend interface to an accounting application. The backend interface was not created specifically for this frontend - it is a generic interface that many other applications use to integrate with our product.
For the convenience of users we wish to provide a Windows Authentication in our frontend application. That means however that we need to pass the credentials on to the backend application which has to check them.
We do not wish to set up our frontend as a "trusted" application to the backend which can authenticate itself as any user. If the frontend was to be hacked, it would then also compromise the backend system.
As I understand it, one way to do it with Windows Authentication is Kerberos Delegation. However this requires to be explicitly enabled for the user that is to be delegated, and the machine which does the delegation (the server with our frontend). By default these options are disabled in Active Directory, and I suspect that many sysadmins will have their reservations about turning them on for all their users.
Also, I'm not really sure that this is what Kerberos Delegation was meant for. I don't need our frontend to impersonate the user that is connecting. I just need to prove that this user has authenticated itself to me.
How would you do this?
I'm not clear what you can and can't do with your use case but I can answer the question what Kerberos Delegation was meant for.
First let's talk about what Kerberos does prior to delegation. It is important to understand this part well because it is subtle.
Kerberos authenticates the identity of BOTH ends of a communication between two end-points across a network, those end-points can be interactive users or services running on a computer.
This is strong authentication so it will not allow a man-in-middle attack in any form. If set up correctly an end point can guarantee they won't be compromised. To the level of the service name (if you are connecting to IIs on a machine it is different than connecting to SQL Server on the same machine). It makes heavy use of modern encryption techniques and requires the use of secure certificates. The details of the authentication protocol are complicated and not worth going into now, but it involves about 20 different distinct steps of confirmation between the two authenticating end points and authentication server (in windows the Domain Controller is the authentication server).
So what the heck is delegation?
Delegation is a Microsoft extension to the Kerberos standard which
allows a trusted source to continue the authentication to another
end-point.
This allows you to act as a "man in the middle" -- however many settings have to be explicitly setup, certificates installed, etc to allow this to work. It is far from simple. (EDIT: Here is another SO answer on the details - https://stackoverflow.com/a/954154/215752)
So, for example, you could have someone authenticate to a website and then have the .NET code connect to an SQL Server AS THE SAME USER to read data with that user's rights.
Now to answer your question, since I'm not sure what you want to do I present three choices:
1) You want to connect to the back end system as the SAME user as the one authenticating at the website.
In this case Kerberos delegation is perfect -- it does exactly what you want.
2) You want to connect to the back end system as a DIFFERENT user than the one authenticating at the website (eg a service account).
In this case you don't want delegation. Kerberos to the website and Kerberos (as a different user) to the back-end will work great.
3) You want to connect to the back end system as the SAME user some of the time and as a DIFFERENT user other times. (For example, you need to validate this is a legal user for the back end system, but want to perform trusted actions as a system account other times. This is (in my experience) the most common use case.)
In this case you use both. Delegation for the connections which need to validate the user identity and then revert to the service account identity for the times when you need system access to the back end. (A previous question of mine went into the details of how to revert to the system identity on the .NET platform see How to "un-impersonate" (un-delegate?) in Kerberos.)
Here is a post describing how Kerberos works and how to set it up.
ASP.NET passing along Windows Authentication credentials
Actually Kerberos delegation is designed exactly for this use case. But the challenge here is craft this on a legacy system and with AD's settings that you do not want to change.
One possible hack is to have the Front End just send the user and the time of authentication but the backend can query the Active Directory Event Logs to determine whether that user has authenticated to the Front end. This requires you to use WIndows Event Log API.and also play around with Event Log settings in AD to log the issue of service tickets. (MY recollection is that this is the default)
-

How to programatically add mapped network passwords (WinXP)?

In WinXP (SP2) you can store mapped network passwords...
Start->Control Panel->User Accounts->Pick one then choose "Manage my network passwords" from Related Tasks.
I normally have about 25-30 servers mapped this way to a few different accounts/domains. The problem is that at some point during our policy updates they get wiped out and it's a real PITA to add them all back again.
Does anyone know how to add them programatically using some sort of script?
Just to clarify, the end goal is not to map drives, it's to actually create the entries in that section. This allows us to use Windows authentication for connecting to our servers (via Dameware, SSMS etc.).
Addendum:
Mark's CredWrite tip led me here...
pinvoke.net -- CredWrite (advapi32)
Which in turn led me here...
Peer Channel Blog -- Application Password Security
Both have proved very helpful.
cmdkey.exe is the CLI version of the tool - but I believe it's only included on Win2003+. I'd suspect a copy to XP would work - but may violate your EULA.
net use also has a savecred option, if you're mapping drives
According to this fairly detailed info, the CredMgr stores it's database in 2 locations. It may be enough to just back up these files:
%APPDATA%\Microsoft\Credentials\%UserSID%\Credentials
%USERPROFILE%\Local Settings\Application Data\Microsoft\Credentials\%UserSID%\Credentials
There's an API to read the credentials, CredEnumerate - but no immediate obvious way to add your own. A couple of candidates:
CredWrite takes a normal CREDENTIAL, but nothing to indicate storing past the current session.
CredUIStoreSSOCredW takes a bPersist parameter - but specifies a "realm" instead of a server or network location.
Edit: D'oh. I missed the PERSIST member of CREDENTIAL. It can be one of the following values:
CRED_PERSIST_SESSION:
The credential persists for the life of the logon session. It will not be visible to other logon sessions of this same user. It will not exist after this user logs off and back on.
CRED_PERSIST_LOCAL_MACHINE:
The credential persists for all subsequent logon sessions on this same computer. It is visible to other logon sessions of this same user on this same computer and not visible to logon sessions for this user on other computers. (This is what's stored into the Local Settings file)
CRED_PERSIST_ENTERPRISE:
The credential persists for all subsequent logon sessions on this same computer. It is visible to other logon sessions of this same user on this same computer and to logon sessions for this user on other computers.
This option can be implemented as locally persisted credential if the administrator or user configures the user account to not have roam-able state. For instance, if the user has no roaming profile, the credential will only persist locally. (This is what's stored into AppData)
It looks like CredWrite is the API you want.
NET USE(command) and WshNetwork.MapNetworkDrive(windows scripting host) are two common ways of scripting the mapping of network drives, both allow you to specify user and password.
I don't know how this would work/not work with stored passwords as you said other than knowing that if you leave the user option blank it will attempt to use the credentials of the current user.