How to programatically add mapped network passwords (WinXP)? - windows-xp

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.

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,

Is it possible to somehow cast or convert a WindowsIdentity type to PSCredential type?

Context: working in PowerShell, need PSCredential object, have an object of WindowsIdentity type.
Say you obtain WindowsIdentity type using:
"[Security.Principal.WindowsIdentity]::GetCurrent()"
You need PSCredential object to make a network call, e.g., Invoke-RestMethod.
Instead of calling the usual Get-Credential and prompting the user for username and pw, can we actually use the current security context to create a credential object? e.g, can we cast the WindowsIdentity object into the PSCredential (if not directly - then through a sequence of steps?).
If not then any other ideas about creating a PSCredential object from current security context (without specifying username or password - or storing encrypted username and pw as that would also require updating as the passwords change)?
Similar questions have probably been asked before but I could not find an approach of trying to convert WindowsIdentity into PSCredential type - or any definitive answer on why this might be prevented by design. If this is not fundamentally possible - what might be the reason for not supporting it? Do you see any plausible workaround?
(I tried to add a tag: PSCredential but this tag does not already exist and I do not have enough reputation to create it: I would like to add that tag: perhaps someone from the community can add it. Thanks)
I am sure others will have their take on this, but here are a few things as I understand them that would make this a real challenge and not prudent as a operational deal.
[Security.Principal.WindowsIdentity]::GetCurrent(), gives you information about your authenticated identity on the network. It does not contain any info about the user password
(https://msdn.microsoft.com/en-us/library/system.security.principal.windowsidentity(v=vs.110).aspx),
which is needed by System.Management.Automation.PSCredential
(https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.pscredential?view=powershellsdk-1.1.0).
Remember, the goal of GetNetworkCredential
(https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.pscredential.getnetworkcredential?view=powershellsdk-1.1.0#System_Management_Automation_PSCredential_GetNetworkCredential)
(which of course is a method System.Management.Automation.PSCredential), is to breakdown your user name into separate Domain and UserName strings and hands you the credential password in clear text.
For network, client access, PSCredential will not work without a valid password being provided. Of course, if you personally entered the information, you and only you can reverse it, not some remote person or service.
Think about it for a moment. Can you imagine the risk ramifications of being able to do this unabated?
Being able to just pull, dynamically, all the auth entropy of the current logged on user. This would be an instant ESP (impersonation / escalation of privilege) problem. Password obfuscation, length, complexity, with an approach like this would be meaningless. Think Pth (Pass the Hash -like attacks) situations without ever needing toe grab the hash.
Imagine, firing off a remote session to any remote host (regardless of who is logged on to it), leveraging what you state here, thus impersonating (with all their rights and privileges) the user to do very nefarious things or even just mean things (changing their passwords, desktop settings, ADDS attributes, say if they are allowed to change there Picture, phone number, maiden name, etc. all being recorded in the audit logs as if that user did it). You could log into their personal human resource files, passing the cred object to the HR website, etc. I am sure that is not your intent (at least I hope not), but still.
All that being said, if you are after user impersonation, then there are resources that present approaches on how to do this. Yet, as you look at the code to do it, it's more involved than just what you are asking for in the MS PowerShell Gallery, but even it expects you to pass it a real cred object not a WI object.
Reaching out across a network requires a full identity, user and password. Every time to try and touch a resource you have not yet touched, or who has not in a long while, you KDC (domain controller) will be engaged and without full creds the KDC Kerb TGT will fail.
Update
shivesh suman
As for ---
Thanks. Regarding: "Yet, as you look at the code to do it, it's more
involved than just what you are asking for ..." - Would it be
possible for you to point me to some of the code that you are
referring to in your comment?
Here is the code I was referring to.
Impersonate a User
New-ImpersonateUser uses the LogonUser method from the advapi32.dll to
get a token that can then be used to call the
WindowsIdentity.Impersonate method in order to impersonate another
user without logging off from the current session. You can pass it
either a PSCredential or each field separately. Once impersonation is
done, it is highly recommended that Remove-ImpersonateUser (a function
added to the global scope at runtime) be called to revert back to the
original user.
https://gallery.technet.microsoft.com/scriptcenter/Impersonate-a-User-9bfeff82

qliksense, how to login with another account than autologin with domain account

I'm using Qlik sense ver 2.1.1, according to the manual of Qlik sense:
4.1.1 Users and licenses
Before anyone can use Qlik Sense, they must be added to the system and licensed. There are two ways that users are added to Qlik Sense Enterprise.
Local Security Layer—Any user already in the operating system’s security layer (Local User Directory or Active Directory, for example) who tries to connect to Qlik Sense is added to the user directory. Those users are not granted access to any resources until they are licensed, but they appear in the user directory.
Directory Sync—After a User Directory Connector (UDC) is configured, users from that directory can be added or synchronized into Qlik Sense. Those users are not granted access to any resources until they are licensed, but they appear in the user directory.
The problem is that I don't want to use domain account to login QLik sense page. I have some pre-defined users on Qlik server for corresponding groups. But, when a new user access Qlik sense page, they're logged in as their domain accounts automatically, and even can't log out, then it's impossible to log-in by my pre-defined user.
How can I change the setting of Qlik sense to disable of this silly automatic log-in mechanism?
The problem you have is that the default Virtual Proxy created during the Qlik Sense installation always attempts to authenticate people against Windows accounts and it only uses Http Authentication to transmit credentials. (If you want something different, you have to create a different Virtual Proxy.)
If your users don't have a chance to type in credentials, it means the browser is configured to automatically supply them when the site asks. You have to turn that setting off. In IE, you can turn it off by going to Internet Options -> Security Tab -> Local Intranet (or whatever makes sense for you) -> Custom Level -> User Authentication (Scroll to the bottom). Set it to the "Prompt for user name and password" setting. Chrome uses IE's settings. In Firefox, go to "about:config", search for "network.automatic-ntlm-auth.trusted-uris", and make sure the domain of your Qlik install is not in the list.
Unfortunately, with Http Authentication, the only way to logout is to close the browser completely (unless there's some browser extension that works around that).

Confusion about Kerberos, delegation and SPNs

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.

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)
-