1

I want to be able to attempt to connect to a host using password authentication and store the server's response in a variable. This is to see what hosts in my list accept passwords for their ssh services.

The problem is that I can not redirect this response to a variable: root@ip's password:

The objective is to capture "root@ip's password:" as a string and store that in a variable.

Instead, the script hangs on root@ip's password: and expects input, preventing the loop from continuing to iterate.

Code:

#!/bin/bash

usernames=( root admin Administrator '' guest Anonymous )
response=

while read ip; do
    for user in "${usernames[@]}"; do
        response="$(ssh -o StrictHostKeyChecking=no -o PreferredAuthentications=password -o PubkeyAuthentication=no $user@$ip)" 
        printf "The response is $response"
    done
done <ssh_telnet_open_ip_list

Edit, the code has been improved and this is what I have now:

#!/bin/bash
printf "\nProbing SSH services:\n\n"
while read ip; do
    printf "Response from $ip:\n"
    ssh -v root@$ip -o "StrictHostKeyChecking=no" -o "PreferredAuthentications=publickey" -I /dev/null 2>&1 | \
        grep "debug1: Authentications that can continue" | \
        cut -d : -f 3
    echo "------------------------------------------"
done <ssh_telnet_open_ip_list.txt

Example output:

Probing SSH services:

Response from ip:
 publickey,gssapi-with-mic,password
------------------------------------------
Response from ip:
------------------------------------------
Response from ip:
 publickey,password
------------------------------------------
Response from ip:
 publickey,gssapi-with-mic,password
------------------------------------------
Response from ip:
 publickey,gssapi-keyex,gssapi-with-mic,password
------------------------------------------
Response from ip:
 publickey,password

etc...

  • 1
    Your actual problem can be solved by redirecting stderr of ssh to stdout so you can pipe it. This is what the accepted answer does with 2>&1. – eckes Nov 18 '18 at 20:52
1

The command

ssh -v user@ip -o "PreferredAuthentications=publickey" -I /dev/null 2>&1 | \
    grep "debug1: Authentications that can continue" | \
    cut -d : -f 3

The output

publickey,gssapi-keyex,gssapi-with-mic,keyboard-interactive,hostbased

How it works

  • The SSH command connects, but only uses Public Key authentication, using /dev/null as the key
  • The grep command extracts the log line with the supported ciphers
  • The cut command extracts only the supported ciphers
  • As the SSH connection cannot be made with no key, it closes, returning from the command straight away

How to interpret the output

  • If you see keyboard-interactive, then password auth is likely accepted
  • If you see publickey, key based authentication is accepted
  • Your code seemed to work. I modified it because I was still getting prompts such as: The authenticity of host '111.222.333.444 (111.222.333.444)' can't be established. RSA key fingerprint is f3:cf:58:ae:71:0b:c8:04:6f:34:a3:b2:e4:1e:0c:8b. Are you sure you want to continue connecting (yes/no)? as shown in superuser.com/questions/125324/… so my code is now edited in my post. Issue now is that some hosts are not giving me a response – Fingers Nov 18 '18 at 20:31
0

In bash, you will need a helper such as sshpass to do this. You can see this detailed in @CSPei's answer to Pass a password to ssh in pure bash at StackOverflow.

You would probably get a cleaner implementation using something like Paramiko in Python. The Client call will raise a more concise exception for you:

exception paramiko.ssh_exception.BadAuthenticationType(explanation, types)

Exception raised when an authentication type (like password) is used, but the server isn’t allowing that type. (It may only allow public-key, for example.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.