9

If I go inside the file /etc/ssh/ssh_config, I can see "$OpenBSD" at the top of file. However, if I change the default port to a different value, it doesn't seem to work. A colleague informed me that's because Dropbear is the software server here, not OpenSSH.

Is there a way to be sure? I can't find an answer googling that.

Peter Mortensen
  • 2,319
  • 5
  • 23
  • 24
AhmedWas
  • 361
  • 2
  • 10
  • You can use netstat or ss with the -p option to see the PID and then you can check the running process for the path and command line. – eckes Aug 04 '21 at 07:36

4 Answers4

24

Connect to the ssh port (e.g. 22) and inspect the banner.

$ nc 10.0.0.10 22
SSH-2.0-OpenSSH_8.6
Michael Hampton
  • 237,123
  • 42
  • 477
  • 940
  • 8
    In the interest of completeness, Dropbear's banner starts with `SSH-2.0-dropbear`. – Mark Aug 04 '21 at 00:30
  • For those who don't feel like playing with a raw connection, the same information can be extracted by connecting with `ssh -v localhost` and looking for `remote software version dropbear` or `remote software version OpenSSH_something`. – TooTea Aug 05 '21 at 12:41
6

Most (if not all?) SSH servers send some sort of version string immediately upon connecting. In a small research project of mine I tried to map SSH server version across a large IPv4 space, and what I did was basically nc address port.

I baked it into a perl script with a timeout for easier processing on my side, as well as an optional timeout with a default value:

#!/usr/bin/perl
use warnings;
use strict;

unless ($ARGV[0] && $ARGV[1]) {  die "Usage: ./raw hostname port [timeout]\n" }
my $timeout = '10s';
if ($ARGV[2]) {  $timeout = $ARGV[2] }

my $response = `timeout $timeout nc $ARGV[0] $ARGV[1]`;
print $response;

Testing it against a server on my network:

./sshbanner.pl 172.16.16.11 22
SSH-2.0-OpenSSH_5.3
Jarmund
  • 535
  • 1
  • 6
  • 16
  • 1
    "Most (if not all?) SSH servers send some sort of version string immediately upon connecting." Because it is right mandatory per the standard, see §4.2 of RFC 4253: "When the connection has been established, both sides MUST send an identification string.". A software not doing this is not implementing SSH properly (and will fail to interoperate with other tools speaking SSH most probably) – Patrick Mevzek Aug 03 '21 at 23:36
  • 1
    @PatrickMevzek You need to send some string, but I guess a random or empty string would also work, and not identify much. – Paŭlo Ebermann Aug 03 '21 at 23:52
  • @PaŭloEbermann "You need to send some string" yes that is exactly what the standard says and I quoted the RFC. So the "if not all?" in answer is redundant/unneeded. Any SSH server not sending this (nothing at all), is NOT implementing the SSH protocol – Patrick Mevzek Aug 04 '21 at 00:31
  • @SnakeDoc Just because Perl is absolutely not needed here, you can just run the `timeout ...` inner command directly in your shell, Perl does not add anything there (but if it pleases the user, it is not really a problem... the `Usage` though does not match the example given :-)), and I would always advise NOT TO shell out from Perl (or any other language for that matter) especially if you shell out to do things that the language can do natively/through libraries. Perl has `Net::Socket` which would be the proper way to do `nc` and also has everything needed to implement timeouts. – Patrick Mevzek Aug 04 '21 at 00:32
  • 1
    To expand on @PatrickMevzek's comment, the RFC states the id string much be of the form "SSH-protoversion-softwareversion SP comments CR LF" where the protoversion is "2.0" and only the comments are optional. - Now as they're open-source and someone could in theory build OpenSSH with a DropBear id, you can't be 100% sure via this, but that'd be the way to bet! – Gwyn Evans Aug 04 '21 at 10:26
  • bash has everything you need `read a < /dev/tcp/127.0.0.1/22 ; echo "$a"` – Jasen Aug 04 '21 at 11:50
3

If you are on the server, look at the process attached to the network port where ssh is expected (22 or something else).

You can use netstat or ss for that. You will then be able to find the full command line of the running server which may be enough to identify it or else you may use to other options:

  • running strings on it is really the last course of actions but can yield results (you will most certainly find back also the string that is reported by the server remotely, as other answers show)
  • you can find the open files the process has (look in /proc/$PID/fd) which may yield either a link to a configuration file, or a logfile, and ideally the logfile would give enough information to pinpoint what process this is.

Or depending on your system and setup, for example you can use systemctl list-units to see exactly what runs currently, and what is the ssh server (then by inspecting systemd unit file you will see what command line it is, and other information)

If you are external to the server, then see other answers, but there is no guarantee that was is returned from remote server is the truth, it can displays itself as whatever it wants.

Another option remotely would be to do some "SSH fingerprinting". I haven't seen that directly, but I am sure it exists. Basically by testing various types of connections, one can determine some info from the remote part, besides what it claims to be. I guess multiple vulnerability scanners have things like that.

Patrick Mevzek
  • 9,273
  • 7
  • 29
  • 42
1

You can use ps to get the list of processes and grep the output for sshd.
With this, you will get the path to the executable binary {{ eg /usr/sbin/sshd or something like that }}.
You can then execute this binary with -? to get the help & usage information. This output will contain the Definitive Name of the Package {{ eg OpenSSH or Dropbear or something like that }}.

Prem
  • 141
  • 1
  • 7