Skip to content

Conversation

dwelch-r7
Copy link
Contributor

@dwelch-r7 dwelch-r7 commented Sep 15, 2025

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

docker run --rm -d \                                                                                                                                                                                                                      
  --name=openssh-server \
  --hostname=openssh-server \
  -e PUID=1000 \
  -e PGID=1000 \
  -e TZ=Etc/UTC \
  -e PUBLIC_KEY_FILE=/path/to/public_key.pub \ # key you just created
  -e PASSWORD_ACCESS=false \
  -e USER_PASSWORD=password \
  -e USER_NAME=username \
  -e LOG_STDOUT=true \
  -p 2222:2222 \
  -v /path/to/config/folder:/config \
  lscr.io/linuxserver/openssh-server:latest

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

ssh -i ./private_key [email protected] -p 2222

And ensure a password isn't required, you should get a shell

Testing

  • Spin up your ssh server
  • Verify you can connect manually
  • Startup msfconsole
  • 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
  • Verify both work and give you an interactable session

Copy link
Contributor

@smcintyre-r7 smcintyre-r7 left a 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]-----+

@github-project-automation github-project-automation bot moved this from In Progress to Waiting on Contributor in Metasploit Kanban Sep 18, 2025
@dwelch-r7 dwelch-r7 force-pushed the fix-ssh-login-pubkey branch 2 times, most recently from 802f7a8 to 4924626 Compare September 26, 2025 13:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Waiting on Contributor
Development

Successfully merging this pull request may close these issues.

2 participants