Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is administrators_authorized_keys a security problem? #1324

Closed
gpduck opened this issue Jan 15, 2019 · 28 comments
Closed

Is administrators_authorized_keys a security problem? #1324

gpduck opened this issue Jan 15, 2019 · 28 comments

Comments

@gpduck
Copy link

@gpduck gpduck commented Jan 15, 2019

Can someone please explain the reasoning behind PowerShell/openssh-portable/pull/369?

Unless I just don't know what I'm doing, it seems like this lets anyone with a key in administrators_authorized_keys log in as any other user in the administrators group? I feel like this should not be a default configuration (or anyone's configuration really)...

@manojampalam
Copy link
Contributor

@manojampalam manojampalam commented Jan 16, 2019

Reason behind this change: You could otherwise do the following in a non-elevated session, when sshd is running:

cd %userprofile%
ssh-keygen
copy .\.ssh\id_rsa.pub .\.ssh\authorized_keys
ssh localhost "i can do a privileged task"

This would bypass Windows UAC and lead to privilege escalation.

How can we solve this?
By making sure that the default location of authorized_keys for administrators is itself in a privileged location that only Administrators have access to.

Where could it be?
Why not %programdata%\ssh since it hosts the rest of ssh/sshd config too

Should we separate out authorized_keys for different users in Administrators group?
Lets see. If I'm an admin, there nothing stopping me to play around with sshd config and do something like this

Implant this in sshd_config
AuthorizedKeysFile c:\mystaticauthorized_keys

and effectively login as any user I wish. So, there is no real security benefit in separating authorized_keys for users in Administrators group. With an intent to keep things simple, we decided to go with a single file. If you wish, you could override it with something like this:

Match Group administrators
       AuthorizedKeysFile __PROGRAMDATA__/ssh/%u/authorized_keys

@jborean93
Copy link

@jborean93 jborean93 commented Jan 16, 2019

So does this mean for a user in the Administrators group, it's authorized_keys file needs to be in C:\Program Data\ssh\<username>\authorized_keys and C:\Users\<username>\.ssh\authorized_keys is no longer valid?

Isn't the whole point of the LocalAccountTokenFilterPolicy the usual way to control this? Why would SSH be different when you could also say the same thing about a loopback WinRM command, or anything else that does a network logon.

This is a bit concerning as you now have different behaviour from what users may expect which is to have this file in the user's .ssh folder in their profile directory. This coupled with the fact that the MS stance seems to be that UAC is not considered a security boundary* means you are treating it like it is when there are other ways to get around this. I could be misinterpreting the situation so please let me know if that's the case.

* See the below for references

One important thing to know is that UAC is not a security boundary. UAC helps people be more secure, but it is not a cure all

This is saying UAC is a defence in depth and not a security boundary

@gpduck
Copy link
Author

@gpduck gpduck commented Jan 16, 2019

It's my understanding that UAC is not a security boundary (so technically no privilege escalation is occuring). However I believe separate accounts are supposed to be a security boundary and out of the box, this configuration would allow any administrator to log in as any other administrator with no logging or auditing that it occurred. This seems to violate that security boundary.

The new default configuration is the equivalent of just having everyone in an organization log in using a shared admin account. Shipping with the extra %u in the file by default would preserve the expected security boundary of using separate accounts (and allow filesystem auditing of administrators changing other user's authorized_keys files) while still mitigating the UAC problem.

@jborean93
Copy link

@jborean93 jborean93 commented Jan 16, 2019

this configuration would allow any administrator to log in as any other administrator with no logging or auditing that it occurred

An admin can do this anyway if they have enough privileges set (the default set is enough). If you have the SeTakeOwnershipPrivilege and SeRestorePrivilege you can adjust the other admin user's profile to put your own key in there with the correct privileges which is the same thing here. If you have the SeDebugPrivilege, you have enough to impersonate the SYSTEM account and call LsaLogonUser and log on any user without a password. There's bound to be other scenarios that could achieve the same result but this is just how Windows works. Once you have admin privileges you can pretty much do anything locally.

The key part here is that you don't have delegation capabilities so you cannot interact with network resources as that user unless you have the password. What I'm concerned about is the behaviour change for admin accounts that doesn't really achieve anything. This leads to fragmentation , confusion for end users, and adds complexity.

@gpduck
Copy link
Author

@gpduck gpduck commented Jan 16, 2019

I realize that as an administrator you can eventually accomplish anything, but calling a bunch of APIs to take over someone's account and typing "ssh otheruser@server" are on totally different levels. If you had two people with similar names you could accidentally end up logged in as someone else because of a typo, and that seems like we've set the bar a bit too low.

@jborean93
Copy link

@jborean93 jborean93 commented Jan 16, 2019

You would still need to set up the key for that user under that directory. It's not one shared key just the location of the key is different. E.g there would be a key for Administrator under C:\ProgramData\ssh\Administrator\authorized_keys and then a key for otheradmin under C:\ProgramData\ssh\otheradmin\authorized_keys.

@gpduck
Copy link
Author

@gpduck gpduck commented Jan 16, 2019

The configuration that is shipping now is a single administrators_authorized_keys for everyone in the Administrators group. I would be fine with the version that includes %u.

Match Group administrators
       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

@jborean93
Copy link

@jborean93 jborean93 commented Jan 16, 2019

Oh I did not realise that I thought the default was with %u. This is more troubling then I thought.

@manojampalam
Copy link
Contributor

@manojampalam manojampalam commented Jan 16, 2019

Feedback taken. We'll consider a change in the next release. For the time being, please override. Also bear in mind the implications with domain accounts (%u would resolve to domain\user).

@jborean93
Copy link

@jborean93 jborean93 commented Jun 24, 2019

@manojampalam did you end up making a decision on this, I see the next release is out and still contains this entry.

@manojampalam
Copy link
Contributor

@manojampalam manojampalam commented Jun 27, 2019

Not yet. Contemplating on making yet another breaking change. The only drawback of the current setting is a potential "accidental log in as someone else because of a typo". In its defence, the current setting sets a clear expectation that all admins on a machine are equal. One can easily impersonate other, irrespetive of how the this path pans out. Its also easy to use and manage since there is no user specific variability in its path.
Otherwise, I believe this would not be a practical problem as "admin" in most cases is a single principal. If it were ever a problem, one could easily customize this path to suit their needs.

@jborean93
Copy link

@jborean93 jborean93 commented Jun 27, 2019

Thanks for the update.

My main objections to it is that it's a breaking change in the first place and a change in the expected behaviour for SSH in POSIX. We all know that by default an SSH key should be located in ~/.ssh/authorized_keys and even for root that would be relevant. From a security perspective I agree with what you are saying I just think it's too different a change in behaviour and if the ultimate goal was to merge this back into the upstream repo as 1 package then this might be a barrier that has to be changed again. I'm not a maintainer there so it's just my thoughts.

@gpduck
Copy link
Author

@gpduck gpduck commented Jun 27, 2019

The only drawback of the current setting is a potential "accidental log in as someone else because of a typo".

With a shared authorized_keys file you also cannot audit that one admin is editing another admin's authorized_keys file. Anyone setting up an SSH key is implicitly also enabling a backdoor login as any other admin. This would be the equivalent of me resetting my password and then being able to log in as any other user in AD. If the stance is that "any admin can [eventually] impersonate any other admin, so let's just enable it by default", then why even allow individual user accounts to be added to the administrators group? Just create a default "administrator" user and make everyone share the password.

@jborean93
Copy link

@jborean93 jborean93 commented Jun 27, 2019

@gpduck I think what he is saying is once you can log in as 1 admin on the host you can then impersonate, or even logon as any other user (including domain accounts) on that host without knowing their password. You cannot authenticate over the network as that user but you can be sure I can pretend to be any account I want on that host. So sharing the key doesn't open any new security holes, maybe making the audit logs a bit more useless though and somewhat easier to execute. I do agree that it shouldn't be shared though.

@gpduck
Copy link
Author

@gpduck gpduck commented Jun 28, 2019

I understand that once an admin logs in, they can do any number of terrible things to a system. But do we not setup auditing, PowerShell logging, malware detection, and sysmon, etc to try and detect these behaviors? Do we not audit for password resets and question why someone reset someone else's password? Do we not audit for local account creation because we can't track who is using a generic local account?

If I see UserA log in and edit UserB's authorized_hosts file, I know something is not right. If the system is configured for a shared authorized_hosts file there is no difference between setting up SSH and setting up a backdoor into someone else's account. With the shared file configuration you have 2 choices: no one can ever use SSH keys OR there is absolutely zero traceability for anything ever.

@cdeadspine
Copy link

@cdeadspine cdeadspine commented Aug 7, 2019

Something to do with windows 7 isn't quite explained by this thread:

Windows 10

Works by commenting out or removing the "Match group ..." lines from the config

Windows 7

This thread is very confusing and I can't figure out how to fix the problem.

I added to the configuration:

Match Group administrators
       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

I copied my authorized_keys to:

__PROGRAMDATA__/ssh/administrators_authorized_keys

I removed the privileges for "authenticated users" and the extended debugging still says

<correctly identifies it is using the file and does not complain about priveledges>
mm_answer_keyallowed: publickey authentication test: RSA key is not allowed

@NoMoreFood
Copy link

@NoMoreFood NoMoreFood commented Aug 9, 2019

@cdeadspine What version are you running? Reason I ask is because an issue related to using multiple matchgroup lines was fixed in this latest version. Might be a separate issue, but thought I'd mention it.

@ChrisITpro
Copy link

@ChrisITpro ChrisITpro commented Aug 14, 2019

I don't really see how this:

Match Group administrators
       AuthorizedKeysFile __PROGRAMDATA__/ssh/%u/authorized_keys

...offers better security than just commenting/removing this:

#Match Group administrators
#       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

From my tests, if you SSH as a normal user, you'll always get an 'Access Denied' if you want to stop/start a service or add/delete a registry key for example. As far as I can see, there's no way to escalate privileges if you SSH as a non-admin user.

If you SSH as an admin user though, no matter the above sshd_config setup (whether the key is under %programdata% or %userprofile%), you're then able to stop/start a service, add a registry key, etc... without UAC control anyway.
OpenSSH on Windows just seems to give you an elevated command prompt if you're an admin user. If there is a way to get by default a non-elevated command prompt when you SSH with an account with admin privileges, then I didn't get how.

Lastly, I agree that the default sshd_config setup is generally really insecure (depending on use, of course):

Match Group administrators
       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

The OpenSSH event logs still show which key was used, but as noticed previously, this config offers the same security as multiple users sharing the same admin account (since any key in there can log in to any admin account)...

To conclude, I just don't see the point of these last 2 lines in sshd_config, except if we don't want any admin to log in through SSH - but couldn't this be made simpler? This default configuration just adds confusion which took me days to figure out.

@jeremybusk
Copy link

@jeremybusk jeremybusk commented Jan 9, 2020

Totally agree on this. Rip it out. I don't think it adds value just is confusing. If I have admin shell on a box I will own your host even with confusing rules like this.

@joshudson
Copy link

@joshudson joshudson commented Jan 23, 2020

I found it expedient to comment out the lines in sshd_config that enable this feature.

We're running server core. There's no point in defending against UAC elevation.

@boschkundendienst
Copy link

@boschkundendienst boschkundendienst commented Oct 16, 2020

I am of the same opinion as jborean93 and I think this is a clear identity mismatch when a local administrator on the machine running the OpenSSH server can edit the administrators_authorized_keys file and add any public key and then initiate a connection from a remote host as <domain>\<any domain admin user> and gets a connection because Domain Admins are members of the local Administrators group by default. Even a profile is generated with that account and the Windows security log logs entries for the spoofed user. As far as I can see the NTFS rights on the generated user folder also have the permissions for the spoofed domain admin account.

I understand, that this must be initiated by a local administrator but imho it should not be able to authenticate locally as a domain administrator on the OpenSSH server this way. It is quite usual to have developers being local administrators on domain member machines so I see some implications coming up here.

Also everything can be undone just by removing the public key from the administrators_authorized_keys file without restarting the SSH server so we would have no tracks wo did it, too.

I opened a vulnerability report with MSRC to clarify the problem and to maybe force some changes here.

@jantari
Copy link

@jantari jantari commented Dec 21, 2020

Hello all,

good discussion so far. Please let me explain in detail why I too think PR 369 was a mistake and must be reconsidered.
My perspective is from an IT professional automating the build- and deployment-process of Windows Server (templates) at work,
as well as a home user fumbling about with a little ssh to make some things easier on a daily-use computer.

It is my understanding that the concern that motivated the change was the following:

If an Administrator (any user who is in the Administrators group)
could log in with ssh-keys stored in their own profile folder,
they could generate a keypair in a non-elevated process, then connect
to localhost as themselves and would land in an elevated ssh-session
thereby bypassing UAC.

I tested this and it is true. ssh-ing to localhost as an administrator from an unelevated shell will land you in an elevated shell.

Moving the ssh-keys for administrative users to a location that one cannot write to from a non-elevated process does indeed prevent this put this behind one extra step. Now, the Administrator-User would need to elevate at least once (via UAC or any other means, e.g. task scheduler or runas) to write his generated ssh-pubkey into the administrators_authorized_keys file. After doing this once an administrator user can continue to ssh from unelevated shells into elevated shells without UAC using freshly generated ssk-keys.

Something else I have not seen mentioned in this thread before is that the Windows OpenSSH server allows password authentication by default, so any administrator user can simply ssh localhost and log in with their password instead of an ssh-key and they will also land in an elevated session without a UAC prompt.

Summarizing so far:

  1. UAC is not a security boundary. UAC makes sure users who have administrative power anyway do not use it unintentionally for everything when it's not needed
  2. A UAC-bypass is therefore NOT a privilege escalation
  3. Any administrator can bypass UAC with the current configuration simply by logging into ssh localhost with their password
  4. The separate administrators_authorized_keys file does not solve the original concern, it simply makes it so that the administrator has to elevate once (via UAC or any other means, e.g. task scheduler or runas) if they want to edit sshd_config or administrators_authorized_keys.

So really, nothing changed. There was never a security-concern with the original configuration in the first place and there is none now. Administrators are administrators and they can do anything, with or without administrators_authorized_keys, with or without UAC.

However, let's consider some of the downsides of the current configuration with administrators_authorized_keys:

  1. It is unexpected behavior.
    Nobody who has used ssh before expects that administrative users would have a seperate shared authorized_keys file. This causes frustration, issues and uncertainty as the reason for the separate file is not documented in the sshd_config or in the pull-request that introduced it.
  2. It introduces a localization issue and even more unexpected behavior.
    The entry in the default sshd_config reads: Match Group administrators - but that is a localized group name that only applies to english Windows installations. This means that this Match statement only ever matches as intended on english Windows installs, in any other locale the translated name of the S-1-5-32-544 group will not match and the authorized_keys of administrative users will continue to be in their respective userprofile paths - what a mess!
  3. It introduces the very real issue of accidentally logging in as another administrative user.
    Because all administrator users share all administrators_authorized_keys, it is very easy to accidentally log in as someone else with a typo - e.g. ssh superadmin_jannet@server vs ssh superadmin_janet@server, or ssh superadmin_mk@server vs ssh superadmin_ml@server. Yes, as established, an administrator can create a local logontoken for any other user anyway, so this is once again not a privilege escalation or security vulnerability, BUT it should not be so easy to do this ACCIDENTALLY!

So please, reconsider this issue - especially with the glaring problems of the current implementation such as the localization bug, this is far from something that can be shrugged off as "wontfix - by design". Let's keep the discussion open.

Possible suggestions:

  1. Remove the special treatment of the administrators group
  2. Remove the special treatment of the administrators group and do not allow ssh to localhost by default
  3. Change the current Match rule to something like this:
Match Group *S-1-5-32-544
    AuthorizedKeysFile __PROGRAMDATA__/ssh/%u/authorized_keys

Thanks!

@TheBigBear
Copy link

@TheBigBear TheBigBear commented Feb 2, 2021

This is definitely a buggy default setting.

!!! That fails in a multi language setup. !!!

I just lost nearly half a day to understand that on my German windows machines the match rule needs to be
Change the current Match rule to something like this:

Match Group administratoren
    AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

Like @jantari 's suggestion of:

Change the current Match rule to something like this:

Match Group *S-1-5-32-544
    AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

This would be a much better and windows language install agnostic setting and should be the default, not a per language adapted string.

@nikos1988
Copy link

@nikos1988 nikos1988 commented Feb 5, 2021

This is definitely a buggy default setting.

!!! That fails in a multi language setup. !!!

I just lost nearly half a day to understand that on my German windows machines the match rule needs to be
Change the current Match rule to something like this:

Match Group administratoren
    AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

Like @jantari 's suggestion of:

Change the current Match rule to something like this:

Match Group *S-1-5-32-544
    AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

This would be a much better and windows language install agnostic setting and should be the default, not a per language adapted string.

Thanks a lot for this! It probably saved me a lot of time.

And also make sure your administrators_authorized_keys is UTF-8! In my first attempt it was UCS-2 LE BOM.

@mcx808
Copy link

@mcx808 mcx808 commented Mar 18, 2021

Anyone know what the resolution to this issue is? I stumbled on this thread developing an OpenSSH PSRemoting implementation on Windows and this issue is marked closed without any indication as to the proper resolution.

It seems to work on 7.7.2.2 by commenting out Match Group administrators and putting the key in ~/.ssh/authorized_keys but I haven't done a deep dive yet.

@joshudson
Copy link

@joshudson joshudson commented Mar 18, 2021

@mcx808 : Since the actual implementation is those lines telling sshd to look elsewhere for authorized_keys for administrators, commenting them out or deleting them makes an end of the problem.

@bagajjal
Copy link
Collaborator

@bagajjal bagajjal commented Mar 18, 2021

It's by design.

@poisonbl
Copy link

@poisonbl poisonbl commented Feb 5, 2022

So, here's another scenario that proves problematic. SSH on Windows is moderately non-standard as it is, so non-standard behavior FOR SSH at that point just amplifies the issues with adding it into managing systems. Because of this configuration decision, removing keys for people when they're being removed from an administrative role is a crapshoot. Deliberate, premeditated, attempts to maintain access (creating accounts, scripts/tasks/etc that put a user back into the Admins group, resetting passwords, tampering with per user keyfiles, etc) are one thing, and tend to stand out. Designing something into administrative tooling that hands that out like candy, with the added benefit of providing NO unique identification, is insane. Any administrative user can throw a key in that file and then impersonate any other into perpetuity WITHOUT their own account continuing to have administrative rights in any other way (including still being present or active in ANY way). Keys in that file are NOT uniquely identifiable to a particular user, since it's a shared list for all admin accounts (and the comment string tagging them with a name does not constitute a valid identity).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests