COMMAND
sshd
SYSTEMS AFFECTED
SSHd 1.2.x, F-Secure 1.3.x
PROBLEM
Following is based on a Bindview/RAZOR Advisory by Michal Zalewski
and Scott Blake. An integer-overflow problem is present in
common code of recent ssh daemons, deattack.c, which was developed
by Core SDI to protect against cryptographic attacks on SSH
protocol.
Insufficient range control calculations (16-bit unsigned variable
is used instead of 32-bit, which causes integer overflow) in the
detect_attack() function leads to table index overflow bug.
This effectively allows an attacker to overwrite arbitrary
portions of memory. The altered memory locations affect code that
is executed by the daemon with uid 0, and this can be leveraged to
obtain general root access to the system.
When the condition described above occurs, a 32-bit local
variable, which is set to 65536 for large input buffers, is
assigned to a 16-bit local variable, effectively causing it to be
set to 0. Due to specific malloc(0) behavior, memory allocation
routine will be passed, creating buffer of size
(malloc_usable_size) 12. Next:
for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED;
We can see n-1 here, and n is equal to 0. Because i is an
unsigned 32-bit integer, it would cause integer overflow. This
code will be equal to i = HASH(c) & 0xffffffff. Binary AND
operator reduces this to i = HASH(c). Pointer 'c' is referencing
client-provided cryptographic packet, and HASH function is simply
responsible for changing byte order in input stream.
Then, detect_attack() routine is trying to access h[i], causing
segmentation fault due to table index overflow bug.
To reproduce this condition, run your sshd server on localhost
under gdb with '-d' switch (to avoid forking). Then try (using
OpenSSH client - ssh.com client software crops the login name):
$ ssh -v -l `perl -e '{print "A"x88000}'` localhost
Program received signal SIGSEGV, Segmentation fault.
0x806cfbd in detect_attack ( ..., len=88016, IV=0x0) at deattack.c:138
136 for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED;
We can inspect the table index (SEGV happened during h[i] !=
HASH_UNSIGNED comparsion):
(gdb) printf "%x\n",i
Results may vary with every connection, depending on the entropy
seed used by the client, crypto keys, etc. You can easily produce
a wide 32-bit range of indexes by changing client parameters or
simply reconnecting. It is obvious there wouldn't be a problem to
specify very large index that would point outside our table, but
will cause address space wrap to point accessible memory (stack or
another segment). Then, few lines below, in the same loop, we can
find following statement:
h[i] = j;
...where j is a simple block counter.
SOLUTION
By carefully preparing encrypted data, an attacker can point used,
accessible memory (that would pass check in line 136 without
SEGV), and then, he will able to alter dword at chosen address,
replacing it with value of j. The attacker can alter stack
variables, alter malloc structures, etc, and attack later due to
improper execution of daemon code. This condition is relatively
difficult to exploit, but there are no technical reasons that
would make this impossible.
Note that the attacker needs to make a TCP connection from an IP
address for which sshd will enter into a key-exchange dialogue.
If the attacker's packets have a source IP address that is
disallowed by (for example) DenyHosts in the sshd configuration
file, the key exchange will not happen and the attacker will not
have an opportunity to compose the required exploit data.
- Bjorn Gronvall - OSSH
Fixed in version ossh-1.5.8
- AppGate
The default configuration of the AppGate server is not
vulnerable since it has SSH-1 support disabled. However
customers who need ssh1-support can contact their support to get
patches.
- Mindbright
The MindTerm client does not have this vulnerability.
- SSH
Current release 2.4.0 is not vulnerable. Previous versions of
SSH1 are not supported but a fix has been commited to the source
tree. SSH recommends customers upgrade to SSH2.
- F-Secure
Unfortunately, after many attempts to contact F-Secure via email
and telephone no response has been received.
For FreeBSD:
ftp://ftp.freebsd.org/pub/FreeBSD/CERT/patches/SA-01:24/sshd-4.2-release.patch
ftp://ftp.freebsd.org/pub/FreeBSD/CERT/patches/SA-01:24/sshd-4.2-release.patch.asc
ftp://ftp.freebsd.org/pub/FreeBSD/CERT/patches/SA-01:24/sshd-4.2-stable.patch
ftp://ftp.freebsd.org/pub/FreeBSD/CERT/patches/SA-01:24/sshd-4.2-stable.patch.asc
ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-3-stable/security/openssh-2.2.0_2.tgz
ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-4-stable/security/openssh-2.2.0_2.tgz
ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-5-current/security/openssh-2.2.0_2.tgz
ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-3-stable/security/ssh-1.2.27_3.tgz
ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-4-stable/security/ssh-1.2.27_3.tgz
ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-5-current/security/ssh-1.2.27_3.tgz
For NetBSD:
Package name Version Buffer O/flow /dev/urandom
------------------------------------------------------------------
ssh (ssh.com/f-secure) <=1.2.27 vulnerable Not Required
ssh6 (above with IPv6) <=1.2.27 vulnerable Not Required
ssh 1.2.27nb1 not vulnerable Not Required
ssh6 1.2.27nb1 not vulnerable Not Required
openssh <=2.2.0p1 vulnerable Recommended
openssh 2.3.0p1 not vulnerable Recommended
fressh 0.8 not vulnerable Required
Update exists.