Programmatically discovering "guest only" sharing/security model - windows

On Modern Windows, the default configuration is done in such a way that if I network-login as a local user, I actually only get authenticated as a guest (more details about this behavior is explained in http://technet.microsoft.com/en-us/library/cc786449(WS.10).aspx)
When my program tries to access WMI on this kind of servers via DCOM, I simply get "Access Denied" error, presumably because a guest user isn't allowed to connect to WMI.
I'd like to differentiate this error from other kinds of access denied errors, such as a wrong password or non-existent user name, so that I can explain to the user what they need to fix the problem.
So my question is, what can I do to detect such a server. I'm thinking that if there's some COM components that can be activated by a guest, that would do --- I can try to activate such a component, and if that works, I know that my login credential was correct. But I can't think of any such concrete component.
Does anyone know such a component? Or any other ways of diagnosing this situation?

No, I cannot recall that there is a DCOM server that can be accessed by a guest. Wouldn't that be unsafe?
If you have time you can check all security settings of DCOM servers using dcomcnfg. Maybe there is a guest. But I don't think so.
On the other side. You cannot see the reason behind AccessDenied on the client side because that would make the server more vulnerable. If an attacker could distinguish between different kinds of access denied errors, he probably would be able to adapt his actions accordingly.
But if you have access to the server you can activate DCOM logging (see http://support.microsoft.com/?scid=kb%3Ben-us%3B892500&x=18&y=11)
As a solution, I suggest that you write such a and similar problems and how they happen into a FAQ/Readme/Webpage. People tend to rather search the web than read a message box.

Related

Windows event 4771 , different use case between computer and user

I am using powershell to get audit fail events 4625 and 4771 from the Domain Controllers. Most of these are 0x18 Status. Now i understand the events with usernames (don't end in a $) as having bad passwords from a machine. Most of the google examples show 4771's from users.
What i want to understand, is what it means when it is coming from a machine?
i.e. surely it is an account on the machine which has an issue, how does a machine have a bad password? And if it can, how does one find out what the issue is ?
Active Directory is an identity management system, and so anything that authenticates with Active Directory needs an "identity" of some sort. Since computers themselves can be joined to a domain and must authenticate against it (with a username and password via Kerberos the same as a regular user logon), they have a username. The AD machine account username is the computer's DNS hostname followed by a dollar sign, for example: Desktop-AB123$
Since every computer in the domain must authenticate against the domain with a username and password, it is possible for that authentication to fail. And it can fail for all of the same reasons that a regular user logon can fail: unrecognized or misspelled username, incorrect password, wrong domain or UPN suffix, or any number of authentication errors.
Event ID 4771 indicates a Kerberos preauthentication error and status 0x18 (usually) indicates a bad password. Source.
Machine accounts renegotiate their password automatically with the Domain Controller when they connect to the domain. If a domain-joined workstation is unable to communicate with a domain controller long enough for the password to expire, it will not be able to log in and you will get a failed logon for that computer's machine name. The computer will need to be rejoined to the domain (or have its password reset using Reset-ComputerMachinePassword and a domain admin credential). The same is also true if a domain controller is unable to communicate with the PDC Emulator. This will be the most common type of error that will lead to failed machine account logins. The second most common will probably be due to computers being renamed while unable to contact a DC, changing the computer's logon username without updating AD.
Beyond password expiration or computer renames, you have to start looking deeper for root causes. These are likely going to be Kerberos negotiation errors caused by services attempting to authenticate in order to perform certain actions. Note that the authentication error does not necessarily occur at service start and may occur when the service is accessed or triggered by another application. I recommend reviewing my question & answer in ServerFault regarding one such example where a server's DNS name didn't match its NETBIOS name, which caused Kerberos authentication to fail and fall back to NTLM.
As that ServerFault question illustrates, tracking down the root cause of a failed machine logon, once you've ruled out username and password errors, can be extremely difficult. Your first step should probably be to enable Netlogon debug logging and then searching the netlogon log file for your failure events. You can also search the SYSTEM event log for any events related to services failing to start. After those two starting points you're basically on your own and will need to develop some advanced troubleshooting and investigation skills to track down the root cause.
One final note, your question is not exactly related to programming or software development, so SuperUser or ServerFault might be a better place for questions such as this in the future. ServerFault is geared towards professional sys admins working in production environments while SuperUser is more geared towards hobbyists, enthusiasts, home servers, and DIYers.

Working around the Windows OS limitation of not allowing multiple connections to a server/shared resource

We are building a system on windows where we centrally (server) need to do fopen to either local files or remote smb resources. The idea is to authenticate in the case of remote resources before doing fopen (with unc paths).
We need to authenticate with the credentials the user (client application) supplied for this resource on that remote share. We don't want to copy any resources.
Using the Win Net Api this works smoothly since it stores the given credentials so that subsequent fopens in the same or in different processes succeed.
But there is a problem:
Many of you probably know the following message from windows when trying to connect to a smb share with different credentials then the ones used for a previous connection:
"Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. Disconnect all previous connections to the server or shared resource and try again."
See http://support.microsoft.com/kb/938120 for the defined limitation and possible "work arounds".
Since we have a central server application running as a service ('Local System' account) we hit this limitation with having already two different users :).
Closing the previously established connection to allow for the 2nd one is not an option (ongoing processing).
On the one hand it's great that windows caches authentication information on the other hand it's too limited.
Modifying the hosts file for each user does not look very nice.
Using smb client libraries (like libsmb++, impacket) doesn't seem to be the solution since we need "over process" authentication.
Configuring a "master" smb share user is also not wanted.
Maybe passing windows user auth tokens around is a way?
This problem is of general nature (i.e. independent of language) and I'm convinced that there are people out there who solved it (in a more or less elegant way ;))
I hope my explanation is understandable.
Thanks in advance for any hint.
felix

Pass current user credentials to remote server

I have an application server (webservice or remoting, not yet decided) on a remote machine and a client on the same domain. I want to authenticate the user as a domain user on the server.
I can ask the user to enter their Windows username/password and send those to the server and get the server to check them against Active Directory but I would rather not. Is there any way I can get the client to send some kind of token which the server can then use to identify which domain user is sending it a request? Obviously I want to protect the server against someone sending a fake user ID and impersonating another user.
Clarification
The client on computer A will communicate with the server on computer B. I think I will probably using .NET remoting for this communication. On the server I merely need to know the ID of the user on computer A; if the app on computer A must send the ID I need to be sure that it hasn't sent the ID of a different user.
I don't need to impersonate the other user, I merely need to know (for certain) who it is.
Are you saying that the client communicates against your server, and you need to use the client's privileges at a third server? That scenario describes The Double-Hop Problem. The blog most describes it in detail, and what can be done to circumvent it (domain modifications).
[...] you can get around the problem and use proper delegation if you set up your network to use Kerberos and set up the web server in question as trusted for delegation.
Added:
I know of no way you can identify the user on computer A. Would it be enough if it was just the user executing your program? You could use windows authentication in a domain scenario, but that would only give you the privileges used by the program to authenticate, which may differ from the actual evil user in front of the keyboard.
Added:
Your comments to this post indicates that windows authentication with impersonation would work for you. Check http://community.bartdesmet.net/blogs/bart/archive/2006/08/26/4277.aspx for code examples.

What is the best way to restrict access to a development website?

I have a site i am working on that i would like to display only to a few others for now. Is there anything wrong with setting up windows user names and using windows auth to prompt the user before getting into the development site?
There are several ways, with varying degrees of security:
Don't put it on the internet - put it on a private network, and use a VPN to access it
Restrict access with HTTP authentication (as you suggest). The downside to this is it can interfere with the actual site, if you are using HTTP auth, or some other type of authentication as part of the application.
Restrict access based on remote IP. Just allow the IPs of users you want to be able to access it.
Use a custom hostname. Have it on a public IP, but don't publish the hostname. This means make an entry in your HOSTS file (or configure your own DNS server, if possible) so that "blah.mysite.com" goes to the site, but that is not available on the internet. Obviously you'd only make the site accessible when using that hostname (and not the IP).
That depends on what you mean by "best": for example, do you mean "easiest" or "most secure"?
The best way might be to have it on a private network, which you attach to via VPN.
I do this frequently. I use Hamachi to allow them to access my dev box so they can see whats going on. they have access to it when they want , and/or when I allow. When they are done I evict them from my Hamachi network and change the password.
Hamachi is a software VPN. Heres a link to Hamachi - AKA LogMeIn
Hamachi
They have a free version which works quite well.
Of course, there's nothing wrong with Windows auth. There are couple of (not too big) drawbacks, though:
your website auth scheme is different from the final product.
you are giving them more access to the box they really need.
you automatically reimaging the machine and redeploying the website is more complex, as you have to automate the windows account creation.
I would suggest two alternatives:
to do whatever auth you plan on doing in the final website and make sure all pager require auth
do a token cookie based auth - send them a link that sets a particular token in a cookie and in your website code add quick check for that token before you even go to the regular user auth
If you aren't married to IIS, and you need developers to be able to change the content, I would consider Apache + SSL + WebDav (aka Web Folders). This will allow you to offer a secure sandbox where developers can change and view the content without having user accounts on the server.
This setup requires some knowledge of Apache so it only makes sense if you are already using Apache or if you frequently need to provide outsiders access to your web server.
First useful link I found on the topic: http://pascal.thivent.name/2007/08/howto-setup-apache-224-webdav-under.html
Why don't you just set up an NTFS user and assign it to the website (and remove anonymous access)

Sending a password to a Windows Service

What is the best way to send a password to a Windows Service? Our application needs a password in order to start. I don't care that services are "normally" supposed to run without user interaction. Its good enough for us that an operator can start the application and then log off.
On a unix system, I would just echo the password over stdin but the service has no stdin.
Currently, we use the DPAPI to just store the password using CryptProtectData. While this, works, it presents other problems that are beginning to become troublesome.
I'm guessing that I'll need to use some form of IPC between the service and the application that is sending the password but I'm not sure which method is appropriate, if any.
Thanks
Two main options:
You could listen on a socket on startup and wait for the required password to be supplied (maybe embed an SSH server in there, so that the password cannot be snooped over the wire)
My preferred option would be to read the password from a configuration file (that can be secured to the minimum readership) or registry setting (again, sufficiently secure such that only your service and administrators can read/change it)
Thanks for responding Rowland.
You could listen on a socket on
startup and wait for the required
password to be supplied (maybe embed
an SSH server in there, so that the
password cannot be snooped over the
wire)
I considered that but without certificate verification, wouldn't that leave us open to a man in the middle attack?
My preferred option would be to read
the password from a configuration file
(that can be secured to the minimum
readership) or registry setting
(again, sufficiently secure such that
only your service and administrators
can read/change it)
We're trying to follow "defense in depth" as much as possible such that if an attacker compromised the machine, he would not able to access our application.
You can use kerberos mutual authentication. There are few options and examples there.
But just wondering. On a compromised machine, There may be a key logger. So typing the password is never secure if you want to maintain security in this environment. The same problem exist afaik for unix terminals.
DPAPI in UserMode is really the best option, and storing the encrypted data in a protected location, e.g. registry key with limited ACL.
What exactly were the problems that are beginning to be troublesome? Maybe we can just solve those...
What exactly were the problems that
are beginning to be troublesome? Maybe
we can just solve those...
Currently, the application runs as the Local System account.
Our application stores a number of credentials in an encrypted file and uses the DPAPI (in UserMode) for the encryption.
Thus, when the application is installed, the installer is run as the Local System account. We also have a set of tools that ship with the application, some of which need access to this encrypted file and thus, they too need to run as the Local System account.
By the time the application is installed and started, we're heavily dependent on that account.
We're running into problems because one of our users wants to use the application to access a shared network drive. The Local System account has no such privileges and we can't simply run our service as a different user because our encrypted information is protected under the Local System Account.
We've tried to avoid the process of setting up a user account just for our application because it is installed across many different customers and environments, all of whom have wildly different security policies.
You can access a remote drive from a service running under system account. However, you will need to have credentials & share information to connect to the remote machine. You can use the API wnetaddconnection to gain access. Probably your encrypted file can store this credential as well.

Resources