9 ms·
Extracting SSH Private Keys from Windows 10 ssh-agent
- organicmultiloc 8y agoSo ssh private keys are stored in plain base64 encoding in the windows registry? How is that even possible?
- eat_veggies 8y agoIt's protected by DPAPI [0] which uses the user's password to encrypt the keys. Any other programs running under that user can theoretically access it (just like how any program can access your ~/.ssh/id_rsa) but other users shouldn't be able to access it. [0] https://msdn.microsoft.com/en-us/library/ms995355.aspx https://msdn.microsoft.com/en-us/library/ms995355.aspx
- simias 8y ago~/.ssh/id_rsa can be protected by a password, you'll want to access the running ssh-agent process memory to get the key in cleartext (unless the person use some security token in which case you can't access the key, just try to login on a remote computer directly while the HSM is available).
- jkaplowitz 8y agoBut while ssh-agent has the key unlocked on a Linux system, any process running as that user can use the key without knowing the passphrase the ssh-agent. That's the more direct comparison.
- jkaplowitz 8y agoNo, part of this involved using Windows's Data Protection API to decrypt it. Other non-administrator users can't read these registry keys, it's encrypted with the login password (as is common with macOS Keychain and GNOME/KDE's credential stores) so even other administrators can't decrypt it. On Linux, administrators (root) can extract the keys from ssh-agent. This is actually no less secure and usually more secure. This is a cool demo of how to do it on Windows, and there's a reason the author didn't call it a vulnerability - it's working as designed and this form of attack is outside the intended threat model.
- simias 8y ago>On Linux, administrators (root) can extract the keys from ssh-agent. I don't understand how the situation is different. Of course you can extract the keys from a running ssh-agent since the whole point is not having to provide your password every time so they have to have access to the private key one way or an other. How is the situation different on Windows? Surely when the user is logged an administrator with access to the full RAM and storage will be able to piece everything together (like TFA does for instance)? On the other hand if you really can't trust your admin you have a huge problem anyway, even with a HSM you could be phished very easily. Actually overall I'd say that this Windows method is slightly less secure because it means that the Windows keychain thingy is a single point of failure, if somebody compromises it they have access to everything including the ssh keys in the registry.
- jkaplowitz 8y agoI don't think Windows gives an administrator account unfettered access to the full RAM, no. And without that or the user's login password, all they could get from the registry is the encrypted version, just as on disk. The encryption is separate per-user with that user's password. Of course there may be ways to get an even more advanced level of access than administrator, such as the system account, but honestly Windows does lock some things down really hard at the kernel level and Data Protection decryption based on in-RAM credentials might be one. I don't know modern Windows internals to that level.
- simias 8y ago>I don't think Windows gives an administrator account unfettered access to the full RAM, no. Are you sure? Typically root has access to the full RAM on an unx system. Unless this is linked to a hardware TPM module I'm not sure why and how it would be protected. Maybe I'm wrong to assume that Windows Administrator == unx root? Anyway, if the OS has a way to hide some of its state from even the admin then surely it could use it to hide the unencrypted SSH key in RAM instead of hiding the key-to-the-registry-key? My main argument is that at some point if the OS doesn't want to prompt the user for a password it must have access to the private key one way or an other, so I'm not convinced that Windows is more (or less) secure than Linux in this situation.
- slrz 8y agoFrom [1], cited and linked to in TFA: > To do that, we simply start the ssh-agent service (as Administrator) and use ssh-add to store our private key. Did Microsoft do some major surgery on the ssh-agent program or am I missing something else? If the agent is started as Administrator, why can I connect to it with my user privileges? And if I do, can other users on the same system do so, too, accessing the same set of keys? [1] https://blogs.msdn.microsoft.com/powershell/2017/12/15/using-the-openssh-beta-in-windows-10-fall-creators-update-and-windows-server-1709/ https://blogs.msdn.microsoft.com/powershell/2017/12/15/using...
- Amezarak 8y ago> And if I do, can other users on the same system do so, too, accessing the same set of keys? No, that's what DPAPI handles. His DPAPI call works because he's decrypting his own credentials.
- Someone1234 8y agoUnprivileged processes can communicate with privileged services. The service itself sometimes controls which user can access which data, but in this case since the encrypted keys are stored in the Current User Registry Hive (NTUSER.DAT) it likely doesn't need to, filesystem permissions handle that. Plus even if another user gained access to your registry hive, the data is encrypted with your context via the Data Protection APIs.
- simias 8y agoI'm sure they have a good reason to do it that way but why run a privileged process when per-user processes could do the job just fine? You'd reduce the surface of attack tremendously that way. If somebody finds a flaw in their admin ssh-agent process they potentially have a way to access other people's key or maybe even escalate their privileges.
- Someone1234 8y ago> I'm sure they have a good reason to do it that way but why run a privileged process when per-user processes could do the job just fine? I actually don't know. I was thinking the same thing. Hopefully they have a good reason, because you're right about the attack surface issue.
- meredydd 8y agoJust a heads-up - the pixelation used to hide the keys in the final screenshot is not safe! There aren't that many possible characters in each of those 10x10px blocks, and ~256 levels of average brightness is enough to distinguish between them. (Here's a simplistic demo: https://dheera.net/projects/blur https://dheera.net/projects/blur) Stick to the block-of-constant-colour method used in the first few screenshots. It's ugly but safer!
- discreditable 8y agoAs I read the article I thought it was more silly they didn't simply use burner keys as PoC.
- kevin_thibedeau 8y agoThey are burner keys. The red boxes are pointless.
- EpicEng 8y agoYeah... why wouldn't you simply black it out? Easier and safer. I guess it doesn't look as fancy...
- ropnop 8y agoCool thanks for sharing! They were all burner keys anyway, just blurred/obfuscated for "best practice"
- e40 8y agoSo, good reason to use the Cygwin version of ssh-agent? I assume it doesn't suffer from the same thing.
- EvanAnderson 8y agoI don't understand what it "suffers" from. It's performing as-intended. A user needs to be able to retrieve the plaintext of their SSH private keys. There's nothing that seems architecturally unsound about how Microsoft implemented this. DPAPI is a reasonable way to protect the keys "at rest" in the registry. The OP was able to extract the keys because he has the credentials for the user from whom he is extracting the keys. Short of storing the keys in the memory of a dedicated crypto-processor outside the host computer (and performing the cryptographic operations there) the plaintext of the private keys will have to be recoverable to the user.
- throwaway2048 8y agothe entire point of agents is that they DON'T just hand you key plaintext, otherwise what would the point of them be compared to just an un-encrypted file. ssh-agent signs requests, tokens, etc on your behalf. You never see the private key.
- Arnavion 8y ago... which is why the blog post is about figuring out how to decrypt the underlying storage that ssh-agent reads from to get to the private key. Edit: If your point was specifically about this from EvanAnderson's comment >A user needs to be able to retrieve the plaintext of their SSH private keys. then the "user" there is the abstract identity used to locate and decrypt the private key, not the human invoking ssh-agent.
- ropnop 8y agoI haven't looked at Cygwin's ssh-agent but I'm sure it's possible to achieve the same thing. The unencrypted private keys have to be stored somewhere (either in memory or protected on disk). Could probably just dump Cygwin's memory and extract from there.
- DangerousPie 8y agoAm I correct in thinking that this is working as intended, and not actually a vulnerability? Many people seem to be sharing this as "look at Microsoft screwing up ssh-agent security", but I can't actually see any evidence of this in the article.
- deleted 8y ago[deleted]
- EvanAnderson 8y agoYou are correct. There is no "vulnerability" here. The plaintext of the user's private keys must be accessible to the CPU performing the cryptographic operations. DPAPI is a reasonable method to keep the keys encrypted "at rest" while allowing the keys to be decrypted w/o the requiring password entry each time the keys are used. It is helpful for post-exploitation toolkits to have this functionality.
- vesinisa 8y agoAFAIK the whole point of ssh-agent is that the private keys are NOT extractable by other processes. https://man.openbsd.org/ssh-agent https://man.openbsd.org/ssh-agent: > The agent will never send a private key over its request channel. Instead, operations that require a private key will be performed by the agent, and the result will be returned to the requester. This way, private keys are not exposed to clients using the agent. This sounds like a pretty gaping security hole by Microsoft. I would not assume loading private keys to an "ssh-agent" means giving any process (browser, email client etc.) running on the same machine access to the unencrypted values!
- EvanAnderson 8y agoThe SSH agent isn't divulging the keys. The OP is decrypting the keys from the underlying storage. The API used to protect the keys allows the keys to be decrypted without explicit password entry. The OP has the necessary password to decrypt the keys, so the API allows it. The SSH agent isn't involved.
- netinstructions 8y agoThe author of this blog must have uploaded an image without the big red block to mask the private key, realized their error, and replaced it with an image of it blocked. However they didn't remove the unblocked image first. Ghost (the blog engine here) just appends a number to the image when you replace it without changing the filename, so it's easy to find. See the two URLs below: https://blog.ropnop.com/content/images/2018/05/base64_decode_openssh.png https://blog.ropnop.com/content/images/2018/05/base64_decode... https://blog.ropnop.com/content/images/2018/05/base64_decode_openssh-1.png https://blog.ropnop.com/content/images/2018/05/base64_decode... This is probably a good reason to use burner keys for proof of concepts.
- e1ven 8y agoWhile I agree it's good to use a burner key, you could have emailed him instead of posting links to both keys on HN...
- netinstructions 8y agoI read that they were burner keys. With people discussing reverse-engineering the pixelated images to access the keys, the merits of masks, security, etc it seemed like a lesson worth sharing for everyone's benefit here that an email wouldn't have accomplished.
- ropnop 8y agoAuthor here...heh nice find. All keys used were burner keys anyway. The only reason I blurred and obfuscated where I could was just for "best practice" not for real security. I knew if I didn't people would comment that I should've ;)
- dspillett 8y ago> I knew if I didn't people would comment that I should've ;) That and following good practise even when not actually necessary due to other mitigations, you obviously hint to less experienced readers what good practise is.
- 8y ago
- vbezhenar 8y agoWith Linux if I'm a program running under target user, I can use unlocked ssh-agent to perform crypto operations with private key, but I can't extract the key itself. With Windows I can just steal the key itself. I think Windows is worse here. Am I misunderstanding something? What's the point of password protection if key is stored unprotected by this password in the registry?
- gnopgnip 8y agoThe keys are protected in the registry with the current user context. You need administrator permissions on Windows to get the private keys, comparable to OSX or Linux
- EvanAnderson 8y agoThe private key is stored password-protected in the registry. DPAPI, the API used to protect the private key, encrypted based on the user's Windows account password, and allows decryption without further password entry by the already-logged-on user. There isn't an equivalent API in the Unix world that I'm aware of. When you fire-up the Windows SSH agent no password entry is necessary, because the password used to logon to Windows is also used to decrypt the stored private key. In a Unix environment you'd need to enter a passphrase to allow the SSH agent to decrypt the key.
- bennofs 8y agoThe equavilent in the unix world is gnome keyring (or any other Secret Service spec implementation) unlocked by a PAM module on login.
- kbumsik 8y agoI don't know if I missed your point but right now I can export a private key using seahorse, a key manager program, very easily not using its password.
- hirsin 8y ago> I have no idea how the original author soleblaze figured out the correct format of the binary data, but I am so thankful he did and shared. Good time to point out that we open sourced [0] all of this so I have some guesses as to how soleblaze might have "reverse engineered" it :-) 0. https://github.com/PowerShell/openssh-portable https://github.com/PowerShell/openssh-portable
- ww520 8y agoI assume the author doing these under the Administrator account or had admin privilege.
- EvanAnderson 8y agoThey had the credentials for the user account under which the private keys were stored. This is a post-exploitation concern, not a vulnerability.
- kuroguro 8y agoYou can read them with or without admin access on the same user. On the other hand a different user's admin account wouldn't help unless you can dump the first user's password. https://msdn.microsoft.com/en-us/library/ms995355.aspx#windataprotection-dpapi_topic02 https://msdn.microsoft.com/en-us/library/ms995355.aspx#winda...
- a-dub 8y agoOT: Does the existence of this openssh port mean that the Windows command window is now a fully functioning terminal?
- janci 8y agoSo basically the article is saying Windows protects the keys much better than linux, where the key sits unencrypted in ~/.ssh folder?
- _ikke_ 8y agoNo: 1. You can choose to have the keys encrypted with a password (same for Windows as for Linux) 2. The key, whether encrypted or unencrypted, are for both platforms stored on disk in the user profile (see first screenshot) 3. This talks about ssh-agent, which you can use to cache the the unencrypted key so that you don't have to type the encryption password every time you want to use the key. On Linux, this is just stored in memory, whereas in Windows, it's stored (encrypted) in the registry as well.