Distribution name and version: Net-SSH-Perl-1.34
Perl version: v5.10.0 built for i486-linux-gnu-thread-multi
Operating System vendor and version: Debian GNU/Linux 5.0.3 (Linux 2.6.24)
Description
Most SSH clients check the change of the host key for security reason.
These checks protect connections against the Man-in-the-middle attacks.
But, as for Net::SSH::Perl, this check doesn't work well.
This library silently accepts the changed key and connects to the host.
Example
Alice, connects to bob.example.org by the code like:
use Net::SSH::Perl;
my $ssh = Net::SSH::Perl->new("bob.example.org") or die;
...
Bob, the owner of the SSH host bob.example.org.
Mallory, an attacker.
(1) Before the change of the host key.
alice% cat ~/.ssh/known_hosts2
bob.example.org ssh-dss AAAA...(The key of Bob)
(2) Someday the host key of bob.example.org changed (e.g. cracked by the
attacker Mallory).
Net::SSH::Perl ignores this change, and silently adds a new entry.
alice% cat ~/.ssh/known_hosts2
bob.example.org ssh-dss AAAA...(The key of Bob)
bob.example.org ssh-dss AAAA...(The key of Mallory)
If Alice tries to connect to bbb.example.org with OpenSSH client 5.1p1
(instead of Net::SSH::Perl), she will be warned:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
The first call of _check_host_in_hostfile($host, $u_hostfile, $key)
returns HOST_CHANGED, but second call of _check_host_in_hostfile($host,
$s_hostfile, $key) overwrite it by HOST_NEW.
if ($status == HOST_OK) {
$ssh->debug("Host '$host' is known and matches the host key.");
}
elsif ($status == HOST_NEW) {
if ($ssh->{config}->get('interactive')) {
(snip)
}
$ssh->debug("Permanently added '$host' to the list of known hosts.");
_add_host_to_hostfile($host, $u_hostfile, $key);
}
else {
croak "Host key for '$host' has changed!";
}
So the second case is selected, silently added the changed key to
$u_hostfile if not "interactive" setting.
Suggested fix
In Net::SSH::Perl::check_host_key ,
my $status = _check_host_in_hostfile($host, $u_hostfile, $key);
This ticket was imported from rt.cpan.org 54161
Distribution name and version: Net-SSH-Perl-1.34 Perl version: v5.10.0 built for i486-linux-gnu-thread-multi Operating System vendor and version: Debian GNU/Linux 5.0.3 (Linux 2.6.24)
Most SSH clients check the change of the host key for security reason. These checks protect connections against the Man-in-the-middle attacks. But, as for Net::SSH::Perl, this check doesn't work well. This library silently accepts the changed key and connects to the host.
Alice, connects to bob.example.org by the code like:
Bob, the owner of the SSH host bob.example.org. Mallory, an attacker.
(1) Before the change of the host key.
(2) Someday the host key of bob.example.org changed (e.g. cracked by the attacker Mallory).
Net::SSH::Perl ignores this change, and silently adds a new entry.
If Alice tries to connect to bbb.example.org with OpenSSH client 5.1p1 (instead of Net::SSH::Perl), she will be warned:
In Net::SSH::Perl::check_host_key ,
The first call of _check_host_in_hostfile($host, $u_hostfile, $key) returns HOST_CHANGED, but second call of _check_host_in_hostfile($host, $s_hostfile, $key) overwrite it by HOST_NEW.
So the second case is selected, silently added the changed key to $u_hostfile if not "interactive" setting.
In Net::SSH::Perl::check_host_key , my $status = _check_host_in_hostfile($host, $u_hostfile, $key);
unless (defined $status && $status == HOST_OK) {
unless (defined $status && ($status == HOST_OK || $status == HOST_CHANGED)) { $status = _check_host_in_hostfile($host, $s_hostfile, $key); }
Additional comment
I think the default behavior for HOST_NEW (silently adding a new key) is very insecure.