-
Notifications
You must be signed in to change notification settings - Fork 14.5k
Fix ssh login pubkey module #20546
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
base: master
Are you sure you want to change the base?
Fix ssh login pubkey module #20546
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I noticed a few issues:
Stack Trace when CreateSession=true
When I run the module with CreateSession=true
, it does authenticate but then there's this stack trace and no session is opened.
msf auxiliary(scanner/ssh/ssh_login_pubkey) > run CreateSession=true
[*] 192.168.159.128:2222 SSH - Testing Cleartext Keys
[*] 192.168.159.128:2222 - Testing 1 key from /home/smcintyre/.ssh/id_ed25519
[+] 192.168.159.128:2222 - Success: 'username:-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACAaxchV/ZDiDi2xNIXxWNiZvKjfI0dE1RzY0MhPg/oHSQAAAJjnF+5c5xfu
XAAAAAtzc2gtZWQyNTUxOQAAACAaxchV/ZDiDi2xNIXxWNiZvKjfI0dE1RzY0MhPg/oHSQ
AAAECpJJ0W7Yh7eBXIHpVh8EM3qXbPUiPVjIUMnCBj2dnNjhrFyFX9kOIOLbE0hfFY2Jm8
qN8jR0TVHNjQyE+D+gdJAAAAEWVtYWlsQGV4YW1wbGUuY29tAQIDBA==
-----END OPENSSH PRIVATE KEY-----
' 'uid=1000(username) gid=1000(users) groups=1000(users) Linux openssh-server 6.16.4-200.fc42.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Aug 28 19:47:10 UTC 2025 x86_64 GNU/Linux '
[!] 192.168.159.128:2222 - LOGIN FAILED: {:private_data=>"-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW\nQyNTUxOQAAACAaxchV/ZDiDi2xNIXxWNiZvKjfI0dE1RzY0MhPg/oHSQAAAJjnF+5c5xfu\nXAAAAAtzc2gtZWQyNTUxOQAAACAaxchV/ZDiDi2xNIXxWNiZvKjfI0dE1RzY0MhPg/oHSQ\nAAAECpJJ0W7Yh7eBXIHpVh8EM3qXbPUiPVjIUMnCBj2dnNjhrFyFX9kOIOLbE0hfFY2Jm8\nqN8jR0TVHNjQyE+D+gdJAAAAEWVtYWlsQGV4YW1wbGUuY29tAQIDBA==\n-----END OPENSSH PRIVATE KEY-----\n", :private_type=>:ssh_key, :username=>"username", :realm_key=>nil, :realm_value=>nil} - Unhandled error - scan may not produce correct results: class or module required - ["/home/smcintyre/Repositories/metasploit-framework.pr/modules/auxiliary/scanner/ssh/ssh_login_pubkey.rb:186:in `is_a?'", "/home/smcintyre/Repositories/metasploit-framework.pr/modules/auxiliary/scanner/ssh/ssh_login_pubkey.rb:186:in `block in run_host'", "/home/smcintyre/Repositories/metasploit-framework.pr/lib/metasploit/framework/login_scanner/base.rb:237:in `block in scan!'", "/home/smcintyre/Repositories/metasploit-framework.pr/lib/metasploit/framework/login_scanner/base.rb:182:in `block in each_credential'", "/home/smcintyre/Repositories/metasploit-framework.pr/modules/auxiliary/scanner/ssh/ssh_login_pubkey.rb:307:in `block in each'", "/home/smcintyre/Repositories/metasploit-framework.pr/modules/auxiliary/scanner/ssh/ssh_login_pubkey.rb:314:in `block in each_key'", "/home/smcintyre/.rvm/rubies/ruby-3.3.8/lib/ruby/3.3.0/set.rb:501:in `each_key'", "/home/smcintyre/.rvm/rubies/ruby-3.3.8/lib/ruby/3.3.0/set.rb:501:in `each'", "/home/smcintyre/Repositories/metasploit-framework.pr/modules/auxiliary/scanner/ssh/ssh_login_pubkey.rb:313:in `each_key'", "/home/smcintyre/Repositories/metasploit-framework.pr/modules/auxiliary/scanner/ssh/ssh_login_pubkey.rb:306:in `each'", "/home/smcintyre/Repositories/metasploit-framework.pr/lib/metasploit/framework/login_scanner/base.rb:144:in `each_credential'", "/home/smcintyre/Repositories/metasploit-framework.pr/lib/metasploit/framework/login_scanner/base.rb:208:in `scan!'", "/home/smcintyre/Repositories/metasploit-framework.pr/modules/auxiliary/scanner/ssh/ssh_login_pubkey.rb:171:in `run_host'", "/home/smcintyre/Repositories/metasploit-framework.pr/lib/msf/core/auxiliary/scanner.rb:116:in `block (2 levels) in run'", "/home/smcintyre/Repositories/metasploit-framework.pr/lib/msf/core/thread_manager.rb:105:in `block in spawn'"]
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(scanner/ssh/ssh_login_pubkey) >
Stack Trace with KEY_PASS
I tested password-protected ECDSA keys too. When the KEY_PASS argument is incrorrect, it fails with a relatively useful error that it couldn't decrypt the key. When the password is correct however it crashes and doesn't authenticate:
msf auxiliary(scanner/ssh/ssh_login_pubkey) > run
[*] 192.168.159.128:2222 SSH - Testing Cleartext Keys
[*] 192.168.159.128:2222 - Testing 1 key from /home/smcintyre/.ssh/id_ed25519.pass
[!] 192.168.159.128:2222 - LOGIN FAILED: {:private_data=>"-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABCvE4pTM0\nHno3zH/A1CYleUAAAAGAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIFeuhu9e9BoQQjtK\nK7eN/zLeeWhpdRvEFQV/9OUsgzInAAAAoNCdDU1msaZKALnDx5+8ormsglTi9B4YUjDTnm\n8bVMXyFWCBlTfFMxThXNE/tE0c+UhAPqyBSP8DwyvHH5rE9cO7mAZXUzzMGjRojtQxvbqi\nRIb0gnzKOeUL6TlSVWT17zc9uNhi4ljBJpGmR4c8eLWL2pYShm4cAH0AmcmHXkj1uVs5iP\nCkI7uwPUKg6zwpXBilwwCbxfFxxJqpto3xzrA=\n-----END OPENSSH PRIVATE KEY-----\n", :private_type=>:ssh_key, :username=>"username", :realm_key=>nil, :realm_value=>nil} - Unhandled error - scan may not produce correct results: Decrypt failed on private key - ["/home/smcintyre/.rvm/gems/ruby-3.3.8@metasploit-framework/gems/net-ssh-7.3.0/lib/net/ssh/authentication/ed25519.rb:92:in `read'", "/home/smcintyre/.rvm/gems/ruby-3.3.8@metasploit-framework/gems/net-ssh-7.3.0/lib/net/ssh/key_factory.rb:124:in `read'", "/home/smcintyre/.rvm/gems/ruby-3.3.8@metasploit-framework/gems/net-ssh-7.3.0/lib/net/ssh/key_factory.rb:58:in `load_data_private_key'", "/home/smcintyre/.rvm/gems/ruby-3.3.8@metasploit-framework/gems/net-ssh-7.3.0/lib/net/ssh/authentication/key_manager.rb:293:in `block in load_identities'", "/home/smcintyre/.rvm/gems/ruby-3.3.8@metasploit-framework/gems/net-ssh-7.3.0/lib/net/ssh/authentication/key_manager.rb:281:in `map'", "/home/smcintyre/.rvm/gems/ruby-3.3.8@metasploit-framework/gems/net-ssh-7.3.0/lib/net/ssh/authentication/key_manager.rb:281:in `load_identities'", "/home/smcintyre/.rvm/gems/ruby-3.3.8@metasploit-framework/gems/net-ssh-7.3.0/lib/net/ssh/authentication/key_manager.rb:137:in `each_identity'", "/home/smcintyre/.rvm/gems/ruby-3.3.8@metasploit-framework/gems/net-ssh-7.3.0/lib/net/ssh/authentication/methods/publickey.rb:18:in `authenticate'", "/home/smcintyre/.rvm/gems/ruby-3.3.8@metasploit-framework/gems/net-ssh-7.3.0/lib/net/ssh/authentication/session.rb:88:in `block in authenticate'", "/home/smcintyre/.rvm/gems/ruby-3.3.8@metasploit-framework/gems/net-ssh-7.3.0/lib/net/ssh/authentication/session.rb:72:in `each'", "/home/smcintyre/.rvm/gems/ruby-3.3.8@metasploit-framework/gems/net-ssh-7.3.0/lib/net/ssh/authentication/session.rb:72:in `authenticate'", "/home/smcintyre/.rvm/gems/ruby-3.3.8@metasploit-framework/gems/net-ssh-7.3.0/lib/net/ssh.rb:262:in `start'", "/home/smcintyre/Repositories/metasploit-framework.pr/lib/metasploit/framework/login_scanner/ssh.rb:77:in `block in attempt_login'", "/home/smcintyre/.rvm/gems/ruby-3.3.8@metasploit-framework/gems/timeout-0.4.3/lib/timeout.rb:185:in `block in timeout'", "/home/smcintyre/.rvm/gems/ruby-3.3.8@metasploit-framework/gems/timeout-0.4.3/lib/timeout.rb:38:in `handle_timeout'", "/home/smcintyre/.rvm/gems/ruby-3.3.8@metasploit-framework/gems/timeout-0.4.3/lib/timeout.rb:194:in `timeout'", "/home/smcintyre/Repositories/metasploit-framework.pr/lib/metasploit/framework/login_scanner/ssh.rb:76:in `attempt_login'", "/home/smcintyre/Repositories/metasploit-framework.pr/lib/metasploit/framework/login_scanner/base.rb:234:in `block in scan!'", "/home/smcintyre/Repositories/metasploit-framework.pr/lib/metasploit/framework/login_scanner/base.rb:182:in `block in each_credential'", "/home/smcintyre/Repositories/metasploit-framework.pr/modules/auxiliary/scanner/ssh/ssh_login_pubkey.rb:307:in `block in each'", "/home/smcintyre/Repositories/metasploit-framework.pr/modules/auxiliary/scanner/ssh/ssh_login_pubkey.rb:314:in `block in each_key'", "/home/smcintyre/.rvm/rubies/ruby-3.3.8/lib/ruby/3.3.0/set.rb:501:in `each_key'", "/home/smcintyre/.rvm/rubies/ruby-3.3.8/lib/ruby/3.3.0/set.rb:501:in `each'", "/home/smcintyre/Repositories/metasploit-framework.pr/modules/auxiliary/scanner/ssh/ssh_login_pubkey.rb:313:in `each_key'", "/home/smcintyre/Repositories/metasploit-framework.pr/modules/auxiliary/scanner/ssh/ssh_login_pubkey.rb:306:in `each'", "/home/smcintyre/Repositories/metasploit-framework.pr/lib/metasploit/framework/login_scanner/base.rb:144:in `each_credential'", "/home/smcintyre/Repositories/metasploit-framework.pr/lib/metasploit/framework/login_scanner/base.rb:208:in `scan!'", "/home/smcintyre/Repositories/metasploit-framework.pr/modules/auxiliary/scanner/ssh/ssh_login_pubkey.rb:171:in `run_host'", "/home/smcintyre/Repositories/metasploit-framework.pr/lib/msf/core/auxiliary/scanner.rb:116:in `block (2 levels) in run'", "/home/smcintyre/Repositories/metasploit-framework.pr/lib/msf/core/thread_manager.rb:105:in `block in spawn'"]
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(scanner/ssh/ssh_login_pubkey) > show options
Module options (auxiliary/scanner/ssh/ssh_login_pubkey):
Name Current Setting Required Description
---- --------------- -------- -----------
ANONYMOUS_LOGIN false yes Attempt to login with a blank username and password
BRUTEFORCE_SPEED 5 yes How fast to bruteforce, from 0 to 5
CreateSession false no Create a new session for every successful login
DB_ALL_USERS false no Add all users in the current database to the list
KEY_PASS Password1! no Passphrase for SSH private key(s)
KEY_PATH /home/smcintyre/.ssh/id_ed25519.p no Filename or directory of cleartext private keys. Filenames
ass beginning with a dot, or ending in ".pub" will be skipped
. Duplicate private keys will be ignored.
PRIVATE_KEY no The string value of the private key that will be used. If
you are using MSFConsole, this value should be set as file
:PRIVATE_KEY_PATH. OpenSSH, RSA, DSA, and ECDSA private ke
ys are supported.
RHOSTS 192.168.159.128 yes The target host(s), see https://docs.metasploit.com/docs/u
sing-metasploit/basics/using-metasploit.html
RPORT 2222 yes The target port
STOP_ON_SUCCESS false yes Stop guessing when a credential works for a host
THREADS 1 yes The number of concurrent threads (max one per host)
USERNAME username no A specific username to authenticate as
USER_FILE no File containing usernames, one per line
VERBOSE true yes Whether to print output for all attempts
View the full module info with the info, or info -d command.
You can't see the password but the key was generated using:
sh-keygen -t ed25519 -C "[email protected]"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/smcintyre/.ssh/id_ed25519): /home/smcintyre/.ssh/id_ed25519.pass
Enter passphrase for "/home/smcintyre/.ssh/id_ed25519.pass" (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/smcintyre/.ssh/id_ed25519.pass
Your public key has been saved in /home/smcintyre/.ssh/id_ed25519.pass.pub
The key fingerprint is:
SHA256:OFmdpdSl16sQgjHqpD+MV9w71DuQbzOR7GYPL6WNI/g [email protected]
The key's randomart image is:
+--[ED25519 256]--+
| o ..... |
| . +o +.. . |
| o ...+.. . .|
| + .+. = o. .|
| . .+oS= * . |
| + ... = +.. |
| . = .o %=. |
| . .. .==B. |
| .E. oo |
+----[SHA256]-----+
802f7a8
to
4924626
Compare
4924626
to
961c7eb
Compare
In draft until rapid7/metasploit-credential#191 is landed/releases
Fixes multiple issues with the ssh_login_pubkey module where logging in and/or getting a session from an sshkey would fail
Testing setup
I used a docker container to run the module against, feel free to use it or any other ssh instance you like, I'll leave instructions for the docker box below
First you'll need an ssh key
ssh-keygen -t ed25519 -C "[email protected]"
saveit somewhere you'll remember
sometimes the public key isn't added to authorized hosts so you may need to do that manually
cat /path/to/public_key.pub >> ./authorized_keys
Now verify it works with
And ensure a password isn't required, you should get a shell
Testing
use auxiliary/scanner/ssh/ssh_login_pubkey
run RHOSTS=127.0.0.1 RPORT=2222 PRIVATE_KEY=file:/path/to/private_key USERNAME=username createsession=true
run RHOSTS=127.0.0.1 RPORT=2222 KEY_PATH=/path/to/private_key USERNAME=username createsession=true