26th Sep 2002 [SBWID-5299]
COMMAND
OpenSSH AFS/Kerberos remote and local buffer overflow
SYSTEMS AFFECTED
Remote users may gain privileged access for OpenSSH < 2.9.9
Local users may gain privileged access for OpenSSH < 3.3
PROBLEM
As posted by Niels Provos and found by 'kurt' :
A buffer overflow exists in OpenSSH's sshd if sshd has been compiled
with Kerberos/AFS support and KerberosTgtPassing or AFSTokenPassing has
been enabled in the sshd_config file.
Ticket and token passing is not enabled by default.
Update (25 April 2002)
======
Exploit available at :
http://www.freeweb.hu/mantra/04_2002/tgt_v1_x86Lnx.tar.gz
SOLUTION
Apply the following patch and replace radix.c with
http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/radix.c?rev=1.18
Index: bufaux.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/bufaux.c,v
retrieving revision 1.24
diff -u -r1.24 bufaux.c
--- bufaux.c 26 Mar 2002 15:23:40 -0000 1.24
+++ bufaux.c 19 Apr 2002 12:55:29 -0000
@@ -137,10 +137,18 @@
BN_bin2bn(bin, len, value);
xfree(bin);
}
-
/*
- * Returns an integer from the buffer (4 bytes, msb first).
+ * Returns integers from the buffer (msb first).
*/
+
+u_short
+buffer_get_short(Buffer *buffer)
+{
+ u_char buf[2];
+ buffer_get(buffer, (char *) buf, 2);
+ return GET_16BIT(buf);
+}
+
u_int
buffer_get_int(Buffer *buffer)
{
@@ -158,8 +166,16 @@
}
/*
- * Stores an integer in the buffer in 4 bytes, msb first.
+ * Stores integers in the buffer, msb first.
*/
+void
+buffer_put_short(Buffer *buffer, u_short value)
+{
+ char buf[2];
+ PUT_16BIT(buf, value);
+ buffer_append(buffer, buf, 2);
+}
+
void
buffer_put_int(Buffer *buffer, u_int value)
{
Index: bufaux.h
===================================================================
RCS file: /cvs/src/usr.bin/ssh/bufaux.h,v
retrieving revision 1.17
diff -u -r1.17 bufaux.h
--- bufaux.h 18 Mar 2002 17:25:29 -0000 1.17
+++ bufaux.h 19 Apr 2002 12:55:56 -0000
@@ -23,6 +23,9 @@
void buffer_get_bignum(Buffer *, BIGNUM *);
void buffer_get_bignum2(Buffer *, BIGNUM *);
+u_short buffer_get_short(Buffer *);
+void buffer_put_short(Buffer *, u_short);
+
u_int buffer_get_int(Buffer *);
void buffer_put_int(Buffer *, u_int);