IIS application pool identity account passwords shown in clear text - iis

When I use the appcmd list appool <ApplicationPoolName> /text:* command, it shows me the application pool identity passwords in clear text. I am able to view the passwords in clear text using Get-WMIObject in PowerShell as well. This can be a serious security threat as a user with correct access credentials can easily view the passwords.
The Application Pool in IIS (v7.5) is configured using domain user account/password. In the applicationHost.config file, the password is encrypted using IISWASOnlyAesProvider encryption provider. Still, the password is shown in clear-text when I use any of the above two methods.
Is there any way to encrypt passwords in such a way that they are not shown in clear-text when I use the above two methods?

Unless something has changed, the answer is no. The principal is best stated by Raymond Chen:
'It's like saying that somebody's home windows are insecure because a burglar could get into the house by merely unlocking and opening the windows from the inside. (But if the burglar has to get inside in order to unlock the windows...)'.
The point in summary, is that anyone that can get to your IIS server or can execute a WMI command remotely against your server, or can execute a powershell command against your server has access.
They are assumed to be admins, and are assumed to be trusted, as occassionally admins would need to pull passwords for recovery purposes, or adding nodes to a shared pool if proper notes or password management wasn't done [mainly needed when doing basic authentication on a domain cluster needing shared passwords].

The passwords are only decrypted if you run appcmd as Administrator. If you run as a normal account, you get back the encrypted string.
This will be something like [enc:IISSomethingProvider:…:enc], just as you find it in applicationHost.config.

Related

Is it possible to auth user in third party app with their ssh key used to login?

I'm writing CLI application secured with strong password. The users supposed to run it on a server inside of secured perimeter over ssh. My users complain it's too annoying to enter the password every time.
I'm trying to figure out if it's possible to use user's ssh keys to authenticate them in my app instead of inputting application password. I can't rely on $USER because I want bind authentication to user's ssh keys.
I considered ssh-agent but it runs on user's machine afaik. I'm considering PAM now, but not sure if it's possible to check the keys the user used to authenticate.
Could anyone suggest if it's possible and where to research?
As Martin Prikryl commented, there is no robust solution other then install custom OpenSSH server. More over, there is probably no way to prove cryptographically that the user utilized certain key to log into the system.
Setting up environment variable (in any way) is not sufficient to prove the user actually owns it.

How to store third-party credentials (no api, no OAuth) for automatic reuse?

I've read several Stack Overflow threads, I still can't decide what is the best option for my case. And the most secure one.
Here is the story. My webapp is to help users automatically get an overview of some of their data available in some third-party website. I need to store for each user some third-party credentials. Each night or so, my server will connect to the third-party services on the users' behalf and retrieve the required data.
Most of those third-party sites do not implement any API or OAuth mechanism, so I was thinking to do some web scraping.
I've read in many places that storing the credentials in the DB is not a good idea - especially because my app needs access to the password (so it has to be encrypted in such a way I can easily reuse it).
So, I have two options left:
Whenever I access (via webscraping) the third-party service, I store on the server the cookies issued by that service, for future reuse. I encrypt them and keep them encrypted in a DB, and decrypt them only when I need them. The problem is that the cookie can be denied or expired after a while, and so the automatic process wouldn't work any more.
I store the credentials in the environment variables. I will be on Node.js and Heroku. That's an idea I found in another SO thread. But I'm wondering about the security of this idea. Is it really safe? No one can access them but me? And what about if I reach many users. Like 1000 users, with 10 services. That's 10000 credentials to store in the env variables. That doesn't seem like a good idea.
I found two interesting questions on Stack Overflow but they don't fit 100% with my use case.
Security model: log in to third-party site with user's credentials (that gave me the idea in point 1)
Rails storing third party credentials.. Anyone know best practice? (gave me the idea in point 2).
I add another answer because maybe this one will do the trick for you.
You said the main goal of your website is to have an overview of third party applications. But what if instead of updating this overview every night, you update it when the user logs in ? It changes everything, because you could use the user's password (of your website) as master password to encrypt (using AES) all the others.
If you do that, the communications between your server and the clients have to be encrypted with SSL pinning, because an attacker could perform a MITM, get the master password and all the others stored in the DB... (Even if in practice it's very hard because you need to hack the client AND the server)
Storing a lot of data that changes and grows in environment variables will never be practical, no matter if it's secure or not so this is pretty much out of the question, unless if you have a small fixed number of users.
Not storing credentials in the database is a very good advice, but the cookies are credentials and even if you store them encrypted, your app needs to be able to encrypt it to use it. (This is unlike the situation with verifying passwords of your users when you don't need to ever encrypt them, you only need to see if the provided passwords hash to the same values that you have stored).
This is a hard problem because to make it work you need to have some form of credentials (whether those are passwords or cookies) stored and ready to be used unencrypted (even if they are stored encrypted, you need to store the keys to encrypt it as well).
Also, what you are trying to do can be illegal. Mayke sure that you follow the TOC of every service that you're using or otherwise you may face legal trouble.
Plan for the attacker gaining admin access to the server. Your site will be very attractive to attackers, kind of a one-stop-shop for user credentials so you will need very good security of the login credentials.
There are more than two options for storing the credentials:
Use an HSM for the storage or individual credential encryption keys.
Keep the credentials on another dedicated server with no Internet access, 2-factor authentication and limit admin personal. Rate limit the access to this server and add rate alarms. Access this server on a per user credential basis over a non-Internet connection. The credentials will only be available to the Internet connected server in memory as used, not at-rest in a file.
Storing users credentials in a reversible way looks like a terrible idea anyway. But if you really want to store them, I suggest you to use the environment variables solution. But you can improve it. To limit the amount of data you store and don't have 1000000 variables as you said, you can just store an AES encryption key, store all credentials in a DB encrypted with this key, and you just have to get this key (which is in memory) and decrypt the DB. But there is another problem with this solution. As I said, this is stored in RAM memory, so it's not persistent, imagine your server has to reboot for X or Y reason... You will lose the AES key and also the credentials of your users... Moreover, if the attacker performs a memory dump, he will have access to the AES key...
I think the better idea is to store the cookies (in an encrypted way) and when this one expires, you alert the user (by mail, phone, notifications, ...) and ask him to fill his credentials again. But it's not a perfect solution ! Indeed the cookies are a type of credentials and shouldn't be stored either...

How to securely store and share log in credentials?

Hi and thanks in advance,
I am looking for industry best practice or a ready made app to store and share passwords for for network resources.
My current situation is that I have a number of people that need to access applications as a specific superuser in order to access some features of these applications. The applications are third party build and cannot be changes to grant access to the required features for anyone but the superuser account. Normal admin accounts have elevated rights but things like creating accounts have to be done via the superuser account.
For security reasons I would like to periodically change the superuser accounts' password. Because of the number of people that need to be able to log in as superuser changing the password would be problematic and a logistical nightmare.
I'm looking to purchase or create an application that would:
Track who is looking up the password and to what resource
Allow me to specify what passwords a user can retrieve
The data should be stored and transmitted ultra securely
Preferable this would be an on-line application (I have Mac and Windows clients)
Keypass is great for this kind of thing. It provides a strong encrypted database of passwords and secure information. This can be accessed share via svn/dropbox/fileshare implementations using a master password.
This is more for a master database of secure data you can set up additional databases, maybe per user, but it starts to get a little away from what it's deigned for.
I would do a C# app that checks with a web service if the user can run the app and with what permissions, it would then be sent the encrypted credentials for a 1 time run, the service would log the request. This would all have to be done securely, so the service would use SSL and preferably certs between the systems. You have a good bit of research here to figure this all out, and you might have to use Java if you want mac... but I dont know how well that can launch apps as other users.
Solution #2 would be to use KeePass. You will have to be creative.

Microsoft Access 2010 and ODBC Connection string security

I am using Microsoft Access 2010 with unbound forms. No linked tables allowed, otherwise the connections string is stored in the table definitions. So it follows that we will use a query definition with no name to access SQL SERVER. This is recommended by Microsoft. We need to get the connection string from somewhere though. So it is recommended to return it from a method with a obfuscated name. It is recommended not to embed the connection string in plain text in the application source. So we use encryption.
A good way of doing this is to require the applications administrator to define the connection string at the first run of the application and according to this msdn article
...encrypt its value via DPAPI with a user-specific key of the account under which the application runs, and save the encrypted value in the Windows registry.
The accde launches from the logged on windows user account, after which the apps admin can login and setup the connection to the database, following the recommendations above.
The weakest link i now seem to have is the windows user account. It seems that anyone logged in to that account could decrypt the connectionstring if they knew the implementation of the security scheme. Which means that the system still is not secure enough.
I could create a new windows user, but that would mean that the password for that user must be kept safe, which means we are back at square 1, securing the password that is used to access some secret information.
There must be an easier way, any ideas?
Is there a reason you need to persist the connection string from session to session? Could you instead build a log-in form in your application where you accept the user's credentials, server instance and database name that they will be connecting to and keep this information in memory while the application is running?
This might provide more flexibility in that the administrator could decide to move the database to a new server and wouldn't have to worry about decrypting the connection string to change it and re-encrypt it. It would also allow for multiple databases to be defined - I'm thinking of a situation where you would have a QA server defined for testing changes before rolling out to the production server.

How can I encrypt a user's password in Silverlight?

I have a Silverlight 3 app which connects to a server to perform various actions. My users log in using Forms Authentication but the actions they request are run on the server using the AppPool account so when they go in the audit logs they're recorded against the AppPool account. PCI DSS regulations now require that the user's own ID is in the audit logs which means the action must be taken using the user's creds. Now, I can save the user's creds when they log on and submit them with each request and the actions being taken by the server can use those creds. But the PCI regs say that if creds are saved they must be encrypted (to avoid someone taking a memory dump of the PC and getting the password).
The only way I can see of doing this is to get a public key from the server and encrypt the password with it, then submit the encrypted password and decrypt it on the server using the private key. But Silverlight doesn't have asymmetric cryptography.
I guess I'm too close to the problem and there must be another solution but I can't see what it is. Can anyone help?
CLARIFICATIONS
It's an internal application. Up until now, I've been using IIS Forms AuthN over SSL to Active Directory - I'm not worried about protecting the password in transit, just whilst it's held in memory on the client. As I understand it, because I'm using Forms Authentication, impersonation is not possible on the server unless I use LogonUser, which means I need the password on the server, so I need to transmit it each time, so I need to hold it in the client, in memory, until the app closes.
Are you saying you need to store the password for re-use in the silverlight app? If you are concerned about the password appearing in memory un-encrypted then Silverlight then I think you're in trouble.
The .NET framework does have a SecureString class for exact purpose you outline.
Unfortunately the Silverlight version of the framework does not have this class. Hence even if you were to keep the logical storage of the password encrypted at some point your code would need to decrypt it before using it. At the point there is memory allocated containing the string in unencrypted form.
I don't know much about Forms authentication but if you can map the User principle to a domain user (which you seem to indicate you need) then you will want to use impersonation when running your code on the server.
Alternatively stop using Forms authentication and use Windows integrated authentication where you definitely can use impersonation server-side.
Encryption should never be used for passwords. When you encrypt something then it follows there should be a way to decrypt it. One way hashes should always be used for passwords. md5 and sha1 have been proven to be far too weak for any secuirty system.
Sha256 should be used, and in silverlight this library will take care of it:
http://msdn.microsoft.com/en-us/library/system.security.cryptography.sha256%28VS.95%29.aspx
In fact storing passwords using "encryption" is recognized by the vulnerability family CWE-257. The use of a message digest is the ONLY way to safely store passwords. I didn't just make this up, this is coming from NIST. There are many other vulnerabilities that come up when storing passwords. Here is THE LIST that NIST has put together:

Resources