I'm using DPAPI ProtectData as follow:
var temp = new byte[32]
{
1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,3,
3,3,3,3,3,3,3,3,
4,4,4,4,4,4,4,4
};
ProtectedData.Protect(temp, null, DataProtectionScope.CurrentUser);
string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
Lets assume that now temp look likes:
temp = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,....31 };
I want to execute this code from .exe file and also from my WebService (IIS).
The problem is that if I'm running the code from the exe the current user is MyDomain/Administrator and if i'm running the code from WebService the current user is IIS APPPOOL/MyApp.
How can i solve this issue?
I'm trying to run from the WebService the .exe file as follow:
Process.Start(#"C:\myexe.exe");
But Its not worked from some reason (i have full access to my iis application) and anyway i dont think this is the right solution for this case.
Note: From security reason i cant change from DataProtectionScope.LocalMachine to DataProtectionScope.CurrentUser
If you don't want to use DataProtectionScope.CurrentUser, you could install it as LocalMachine to begin with. Then, have the WebService decrypt it, then re-encrypt it using CurrentUser. Make sure to delete the old value and all its transient copies. In this way, you can take it from LocalMachine and lock it down once the appropriate user is running.
This still leaves the key exposed at LocalMachine level, but for a shorter window of time.
Another solution is to use LocalMachine and use the additional entropy feature with a secret shared between the two executables. This could be an obfuscated value known to the application (no "real" security), or a user-provided password. The user-provided password solution could be more secure but is also more of a pain and more programming overhead.
If the time window between installation and WebService running is small, the first solution may be a good fit.
The problem was solved.
I running the IIS application from local user.
You can find this by selecting the app pool and clicking Advance Settings... under the Actions pane menu. Select Identity and then click the button beside the current user listed. Select Custom account and click Set. Use the format domain\username for the username and enter the password for the user.
Related
I'm running (on my local machine) the GPG (wingpg ) - command line version.
My login name at win7 - is RoyiN. ( so I have a profile for it)
When I logged in - I've installed the keys (using PKA.exe) both private and public.
All fine.
Then I wrote this code ( which is working )
Process proc = new Process();
proc.StartInfo.FileName = cfg.PGP_Program_FullPath;
proc.StartInfo.UserName = "Royin";
proc.StartInfo.Domain = ...;
proc.StartInfo.Password = ...
proc.StartInfo.Verb = "runas";
proc.Start();
...
However if I write in the UserName field - another user which is also Administrator on my local machine - it says :
gpg: decryption failed: No secret key
Then I swapped again to RoyiN and it did work
Are keys installed per user? is there a way to change that so it will be global ? ( so every user on the machine will be able to use these keys - without having to install the keys under each every profile) ?
It also implies that if i want to allow other's to connect to my computer - I must be logged on with RoiyN 24/7....
Is there any workaround for this ?
There are two different things happening here that are related to the "person" running gpg.
GPG searches for keys in the default keyring files, which are installed in your user profile directory (under a folder named .gnupg). This will be a set of files like pubring.gpg and secring.gpg. This part is easy to work around: pass --secret-keyring "path\to\file" as one of the parameters and it will add that keyring file to its search path. You may want to move it to a publically readable location, like %ALLUSERSPROFILE%, first.
Apart from that, GnuPG keys are generated for and tied to an identity, which is usually your email address. When receiving files, the data will specify the identify of the person who's key is needed to decrypt and/or verify the integrity. When encrypting or signing files, you have to tell GPG who's key to use. Your secret key is used when you sign things for others, or when you decrypt data sent to you. You need to make sure the appropriate keys are in whatever keyring file you use, regardless of where it is.
There's no need for you to actually stay logged in when you run gpg, if you give it an explicit location for the data. It's simply that gpg, by default, reads the current environment variables, set at login, to determine where those things are.
You'll probably need to specify a keyring file path, a secret keyring file path, and a configuration file path if you want to run GPG unattended. The entire list of options you can specify is on the GPG Configuration Options page.
(You may want to try starting with just the --homedir option, which I think will override the default paths for everything else in one go, but you'd need to test that to make sure.)
Yes, they are installed on per-user basis
Simple answer - just export the private/public key pair, and install it for the Administrator account as well.
Although, it'd be better to create a separate key for your automated system with own public key - whoever has your key with a high level of trust, will accept this one as well.
I basically want to automatically mount a (non-system) Truecrypt volume or start Keypass just protected with a single (secure) password, the one windows 7 use for default authentification.
I'm using C#.
Is there anyway to get this password when already being logged in?
Or anyway to get this password while I'm actually typing it during the login process.
For 1. I couldn't find anything (the password is not stored anywhere, just a hash of the password is stored)
For 2. I already tryed some things. I got a program to execute before a user logs on using
GPEDIT.MSC Computer Configuration -> Windows Settings -> Scripts -> StartUp.
Then I tryed to get the password using global key hooks (tryed GetAsyncKeyState and SetWindowsHookEx). Both work well when I try to capture keys when I'm already logged in, but not during the login process.
But I found a keylogging software (Elite Keylogger) which is actually able to get the password that way (when logging in). (I tryed the trial version in VMWare). The other things if tryed in VM Ware and also on a real machine.
Thank you for any help or tips.
I'm doing something similar with batch scripting in order to automatically mount a Truecrypt (or Veracrypt if you prefer) volume upon Windows login with Windows 10. I use a KeePass file setup to use Windows Authentication to securely house the encrypted volume password.
Here's the process:
1) Create your truecrypt or veracrypt non-system volume
2) Create a KeyPass file to hold an entry containing the password to the encrypted volume. Setup the KeyPass file to use windows authentication under the login you will use when you want the drive to automatically mount.
3) Use a batch script like the one below to open the encrypted volume. By housing the password in the KeyPass file with windows authentication you prevent exposing the password in plain-text in the batch file. You'll need to modify this script to your specific system.
#ECHO Mounting Secure Drive (S:)
#ECHO OFF
SETLOCAL EnableDelayedExpansion
SET x=0
FOR /F "usebackq" %%F IN (`"C:\Program Files (x86)\KeePass Password Safe 2\KPScript.exe" -c:GetEntryString C:\<LocationOfYourKeePassFile>\<keepassfilename>.kdbx -useraccount -ref-Title:<entrytitle> -Field:Password`) DO (
SET Pass!x!=%%F
set /a x+=1
)
"C:\Program Files\TrueCrypt\truecrypt" /v \Device\Harddisk0\Partition4 /ls /s /q /p %Pass0% /b /h n /w
4) Lastly, set up a windows Task Scheduler to run the batch upon windows login. Trigger should be "at log on" for the target user account. Action should be "Start a Program" with the target the full path to the batch script
Another feature I like about this approach is that I can save the encrypted file volume password elsewhere incase the windows account is corrupted or deleted. I.e. I may lose access to the KeyPass file that is setup to use windows authentication but if I've saved the actual encrypted disk password somewhere else, I can still restore access to the encrypted volume.
There is a way of unlocking a KeePass database with its master password automatically after the Windows log on. You can use the same database on other computer, because it will not be bound to your Windows user account. See this Super User answer for details.
You change your KeePass database to use your Windows account as the master key, then install the TrueCrypt plugin for KeePass. You then have an entry in KeePass that contain the password for the TrueCrypt mount also registered with the TrueCrypt plugin.
With that in place, after you've logged in, open KeePass and select the entry and click Ctrl + T and you have the volume mounted in TrueCrypt.
I'm developing ASP.NET 4.0 web application, and I want to read the current user certificates from X509Store. Reading the LocalMachine certificates works fine, but if I set the StoreLocation to CurrentUser, it gives me an empty collection.
The following code works fine :
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine); // StoreLocation.CurrentUser
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
I've checked my personal store (via certmgr.mmc) and I'm sure that I have the certificates.
What am I missing ? ( store.Certificates is empty )
It appears that you can not access the Personal Certificate Store via web application, no matter what application pool identity you're using.
It makes sense, a web application has no access to that location. :)
My solution :
I've developed an ActiveX control which I think its the only way to access the Store.
(Also, a Java Applet offers the same functionality).
I use the ActiveX control via JavaScript to access the Store, and send that information to the server.
If your worker process cannot access cert store, maybe it's just account setup problem. Try go ing to IIS Configuration, open ApplicationPools, right click on yours, select Advanced and try setting LoadUserProfile to TRUE. And restart the pool. It worker for me - no more exceptions when loading .PFX with private keys.
I had a similar problem. The solution was:
IIS admin->[your virtual dir]->Authentication->Anonymous Authentication (select then click "Edit...") and change it to use "Application pool identity".
Otherwise it may be running as the generic "IUSR"
When installing a windows service, is there a way to let the user installing choose between a specific user account and a computer account, such as LocalSystem? I see how to do this at build time through service installer properties, but not during install.
#Doobi, #Eric, in my experience (Win7Home 64-bit, VS2010Express, not on a domain)
processInstaller.Account = ServiceAccount.LocalService;
processInstaller.Username = null;
processInstaller.Password = null;
will install the service as LocalService without a password prompt.
To install the service as a local user account (and provide a password prompt to enable the user to supply the credentials) I had to use:
this.serviceProcessInstaller.Account =System.ServiceProcess.ServiceAccount.User;
this.serviceProcessInstaller.Password = null;
this.serviceProcessInstaller.Username = null;
The important step I had to take to get the service installed is to put the computer name in the credentials dialog box, ie MYPC\dave instead of dave. I was surprised that I'd have to do this as it's not on a domain. I've added this comment as no other posts I've seen about this mention having to prefix the username with the PC name.
Yes there is, it's on the process installer. I think in the newer frameworks it's a visible property if you select the process installer on the design surface. The last time I did it (.NET 2.0) you have to add something similar to this to the *.designer.cs file:
processInstaller.Account = ServiceAccount.LocalService;
processInstaller.Username = null;
processInstaller.Password = null;
Adding to previous answers, don't forget to append Machine name to Username while entering "Username" Field of password prompt. Otherwise service will not accept the credentials although if you give correct username and pwd. It will keep on pop up prompt to enter credentials. It took me one day to figure out this. Thanks to Badgerspot!
I am attempting to Impersonate an administrator account from a LocalSystem Service in order to get data from administrators HKEY CURRENT USER registry - in order to impersonate I am using the codeproject code found at the following site written by Uwe Keim: Impersonator
My source code is as follows:
using (new Impersonator("user", ".", "pass"))
{
RegistryKey rk = Registry.CurrentUser.OpenSubKey("Software\\CompanyName");
string sValue = rk.GetValue("Value", "").ToString();
rk2.Close();
}
My expectation was that sValue would be from the user/pass account (as I am impersonating it) but oddly enough it is still the sValue from the LocalSystem account where my service is runnning ...
Any clues on what I am doing wrong? Any help would be much appreciated.
Thanks,
I know this is an old thread but I recently came across the same issue (albeit from a C++ Windows service) and thought I'd share my findings, because many forums have asked the same question and none have left a satisfactory answer.
Basically, I've found two ways to approach this, though this is an answer more for C applications rather than .NET (I haven't tested with pinvoke but it may work).
Solution 1:
Instead of using RegOpenKey, use RegOpenCurrentUser() to get the key handle. Apparently, the reason RegOpenKey doesn't get the impersonated user's key is because HKEY_CURRENT_USER is cached in the running thread.
Solution 2:
RegDisablePredefinedCache(). This disables the cache mentioned above and lets subsequent calls to HKEY_CURRENT_USER be of the actual impersonated user. This is the solution I went with.
Hope this helps.
Everything I've read on the subject seems to indicate that impersonation should get you access to the HKEY_CurrentUser for the impersonated account. However, it could be a quirk in the .NET Registry implementation.
This is just a hunch, and an untested one at that, but have you considered using Registry.Users instead of Registry.CurrentUser?
You'll need to find the SID for the Administrator account, but you should be able to deduce that using Regedit
By default the HKEY_CURRENT_USER handle is cached on a process wide basis. So when you impersonate a user and then access the current user hive you will be accessing the hive of the user that started the process not the user being impersonated. This is true for all Win32 processes not just .Net. If you wish to disable this caching so that all current user calls go to the correct user hive under HKEY_USERS then you must call RegDisablePredefinedCache via pInvoke.
Be warned that if the user being impersonated has not had their profile loaded then any CurrentUser requests will be forwarded to the .DEFAULT user. So you may also need to call LoadUserProfile.
Disabling the handle caching will also cause a slight slowdown in all CurrentUser requests.
I'm guessing you're going to find that you're out of luck. It can't be done.
If applications were able to impersonate an Administrator account and write values to the Registry in Windows, it would present a huge security hole. My guess is that the Registry.CurrentUser property will ALWAYS reference the user running your application...whether or not you try impersonation or not.
EDIT
Turns out that I didn't read the implementation details of the Impersonator code you were using. Your problem could be something completely different.
Does your code refer to the Registry static class prior to your impersonation code being run? If so, that would be the problem. If you look at the Registry.CurrentUser property in Reflector, you'll see that it is set by the static constructor of the Registry object. Static constructors get called when the static object is first referenced.
In your case, if you're referencing the Registry object (whether it involves CurrentUser or not) the static constructor is being called which is setting CurrentUser to your original user...not the Impersonated account.