Add ssh_keys module to extract SSH keys from Windows registry#1112
Add ssh_keys module to extract SSH keys from Windows registry#1112mverschu wants to merge 2 commits intoPennyw0rth:mainfrom
Conversation
|
Thanks for the PR, looks cool! Parts of it look AI generated, could you describe to which extend you have used AI and what parts are done by human hand? |
|
Hi that is completely true, I use cursor as my IDE, it's able to take my current tooling and transform this in to a NetExec module. I use this all the time for several projects, ofcourse understanding the code and pointing it in to the direction I want it to behave. I'm not a software developer, can read code well. Enough information? |
Yes thank you. The reason I am asking is that AI tends to be very verbose, recreates code (by its nature) that already exists and does other very weird things (also see #1109). The PR looks not too bad tho and adds a nice technique! |
NeffIsBack
left a comment
There was a problem hiding this comment.
I am definitely not an expert on dpapi but we have some implementations to decrypt stuff from remote. Possibly looking into that, so that command execution is not required would probably be nice as well. If you have the time feel free to look into it.
nxc/modules/ssh_keys.py
Outdated
| @@ -0,0 +1,396 @@ | |||
| #!/usr/bin/env python3 | |||
There was a problem hiding this comment.
Please remove, isn't needed.
nxc/modules/ssh_keys.py
Outdated
| r""" | ||
| Module to extract unencrypted private SSH keys from Windows OpenSSH ssh-agent registry entries. | ||
|
|
||
| When adding private keys to ssh-agent, Windows protects the private keys with DPAPI and stores | ||
| them as registry entries under HKCU:\Software\OpenSSH\Agent\Keys | ||
|
|
||
| With elevated privileges, it is possible to pull out the binary blobs from the registry and | ||
| unprotect them using DPAPI. These blobs can then be restructured into the original, unencrypted | ||
| private RSA keys. | ||
|
|
||
| Original Python implementation credit: soleblaze | ||
| https://github.com/NetSPI/sshkey-grab/blob/master/parse_mem.py | ||
| """ | ||
|
|
There was a problem hiding this comment.
Please move/merge this with the class doc string.
nxc/modules/ssh_keys.py
Outdated
| try: | ||
| from pyasn1.type import univ | ||
| from pyasn1.codec.der import encoder | ||
| HAS_PYASN1 = True | ||
| except ImportError: | ||
| HAS_PYASN1 = False |
There was a problem hiding this comment.
Pyasn1 is a dependency, so just assume it exists
nxc/modules/ssh_keys.py
Outdated
| if not HAS_PYASN1: | ||
| context.log.fail("pyasn1 package is required. Install it with: pip install pyasn1") | ||
| return |
nxc/modules/ssh_keys.py
Outdated
| def _get_int(self, buf): | ||
| """Convert bytes to big-endian integer.""" | ||
| return int.from_bytes(buf, byteorder='big') |
There was a problem hiding this comment.
I don't think that has to be a function as it just executes one line
nxc/modules/ssh_keys.py
Outdated
| return output | ||
| except Exception as e: | ||
| context.log.debug(f"Error executing PowerShell decryption: {e}") | ||
| import traceback |
There was a problem hiding this comment.
Please do Imports at the top of the file
nxc/modules/ssh_keys.py
Outdated
|
|
||
| except Exception as e: | ||
| context.log.fail(f"Error extracting SSH keys: {e}") | ||
| import traceback |
There was a problem hiding this comment.
Please move imports to the top of the file
|
Understood, I tried to take as much information from already implemented modules. |
|
The code this is based on from NetSPI (https://github.com/NetSPI/sshkey-grab/blob/master/parse_mem.py) is 11 years old. @zblurx would this be useful to implement inside DPloot itself or nah? |
|
I don't think it will be usefull to implement it in dploot, imo nxc module is the way to go |
- Fixed all review comments. - Added remote DPAPI dumping looking at wifi.py module. - Removed local DPAPI dumping for stealth. - Formatted the output the be more nicely looking using intend. Signed-off-by: B3AR <69352107+mverschu@users.noreply.github.com>

Description
This PR adds the
ssh_keysmodule over SMB which extracts unencrypted private SSH keys from Windows OpenSSH ssh-agent registry entries stored inHKCU:\Software\OpenSSH\Agent\Keys.Type of change
Note: Requires
pyasn1package (pip install pyasn1)Testing Requirements:
pyasn1package must be installedTest Commands:
Extract SSH keys (display only):
Extract SSH keys and save to file:
Extract SSH keys and save to file with tilde expansion:
netexec smb TARGET_HOST -u ADMIN_USER -p ADMIN_PASSWORD -M ssh_keys -o OUTPUTFILE=~/id_rsa_testExpected Behavior:
HKCU:\Software\OpenSSH\Agent\Keys\registry pathVerification:
After running the module, verify the extracted keys:
-----BEGIN RSA PRIVATE KEY-----)Notes:
on_admin_loginhook)ssh-add)~) expansion in OUTPUTFILE pathScreenshots (if appropriate):
Example Output:
Checklist:
Insert an "x" inside the brackets for completed and relevant items (do not delete options)
poetry run python -m ruff check . --preview, use--fixto automatically fix what it can)tests/e2e_commands.txtfile if necessary (new modules or features are required to be added to the e2e tests)