home *** CD-ROM | disk | FTP | other *** search
- -----BEGIN PGP SIGNED MESSAGE-----
-
- =============================================================================
- FreeBSD-SA-96:21 Security Advisory
- FreeBSD, Inc.
-
- Topic: unauthorized access via buffer overrun in talkd
-
- Category: core
- Module: talkd
- Announced: 1997-01-18
- Affects: 1.0, 1.1, 2.1.0, 2.1.5, 2.1.6, 2.1.6.1
- Corrected: 2.2-current as of 1997-01-18
- 2.1-stable as of 1197-01-18
- FreeBSD only: no
-
- Patches: ftp://freebsd.org/pub/CERT/patches/SA-96:21/
- References: AUSCERT AA-97.01 (Australian CERT organization),
- SEI CERT VU#5942 (internal tracking reference only)
-
- =============================================================================
-
- I. Background
-
- Buffer overrun (aka stack overflow) exploits in system
- supplied and locally installed utilities are commonly
- used by individuals wishing to obtain unauthorized access to
- computer systems. The FreeBSD team has been reviewing and
- fixing the source code pool to eliminate potential exploits
- based on this technique.
-
- Recently, the Australian CERT organization received information
- of a buffer-overrun vulnerability in the talkd daemon shipped in
- most modern BSD based systems.
-
-
- II. Problem Description
-
- To quote AUSCERT:
-
- talk is a communication program which copies text from one
- users terminal to that of another, possibly remote, user.
- talkd is the daemon that notifies a user that someone else wishes
- to initiate a conversation.
-
- As part of the talk connection, talkd does a DNS lookup
- for the hostname of the host where the connection is being
- initiating from. Due to insufficient bounds checking on
- the buffer where the hostname is stored, it is possible to
- overwrite the internal stack space of talkd. By carefully
- manipulating the hostname information, it is possible to
- force talkd to execute arbitrary commands. As talkd runs
- with root privileges, this may allow intruders to remotely
- execute arbitrary commands with these privileges.
-
- This attack requires an intruder to be able to make a
- network connection to a vulnerable talkd program and provide
- corrupt DNS information to that host.
-
- This type of attack is a particular instance of the problem
- described in CERT advisory CA-96.04 "Corrupt Information
- from Network Servers". This advisory is available from:
-
- ftp://info.cert.org/pub/cert_advisories/
-
- Recent versions of FreeBSD 2.2 -current may not be affected
- with this vulnerability due to improved security in
- new versions of BIND, which sanity-check the results of
- reverse name lookups performed by the DNS system.
-
-
- III. Impact
-
-
- Intruders may be able to remotely execute arbitrary commands
- with root privileges.
-
- Access to a valid user account on the local system is not
- required.
-
-
- IV. Workaround
-
- Disable the ntalkd program found in /etc/inetd.conf by
- commenting the appropriate line out and reconfiguring inetd.
-
- # grep -i ntalk /etc/inetd.conf
- ntalk dgram udp wait root /usr/libexec/ntalkd ntalkd
-
- After editing /etc/inetd.conf, reconfigure inetd by sending
- it a HUP signal.
-
- # kill -HUP `cat /var/run/inetd.pid`
-
- V. Solution
-
- The patches found at the following URL fix this vulnerability.
- Patches are available for FreeBSD 2.1.x (-stable) and -current.
-
- Acknowledgment:
-
- These patches were based off of published work provided by
- BSDI, Inc.
-
- After applying these patches, recompile and re-install the
- affected utilities.
-
- For FreeBSD -current (2.2 prerelease and 3.0 prerelease)
- systems:
-
- Index: announce.c
- ===================================================================
- RCS file: /cvs/freebsd/src/libexec/talkd/announce.c,v
- retrieving revision 1.6
- diff -u -r1.6 announce.c
- --- announce.c 1997/01/14 06:20:58 1.6
- +++ announce.c 1997/01/18 08:27:04
- @@ -34,7 +34,7 @@
- */
-
- #ifndef lint
- -static char sccsid[] = "@(#)announce.c 8.2 (Berkeley) 1/7/94";
- +static char sccsid[] = "@(#)announce.c 8.3 (Berkeley) 4/28/95";
- #endif /* not lint */
-
- #include <sys/types.h>
- @@ -43,13 +43,17 @@
- #include <sys/time.h>
- #include <sys/wait.h>
- #include <sys/socket.h>
- +
- #include <protocols/talkd.h>
- +
- #include <errno.h>
- -#include <syslog.h>
- -#include <unistd.h>
- +#include <paths.h>
- #include <stdio.h>
- +#include <stdlib.h>
- #include <string.h>
- -#include <paths.h>
- +#include <syslog.h>
- +#include <unistd.h>
- +#include <vis.h>
-
- extern char hostname[];
-
- @@ -78,7 +82,7 @@
-
- #define max(a,b) ( (a) > (b) ? (a) : (b) )
- #define N_LINES 5
- -#define N_CHARS 120
- +#define N_CHARS 256
-
- /*
- * Build a block of characters containing the message.
- @@ -100,33 +104,37 @@
- char line_buf[N_LINES][N_CHARS];
- int sizes[N_LINES];
- char big_buf[N_LINES*N_CHARS];
- - char *bptr, *lptr, *ttymsg();
- + char *bptr, *lptr, *vis_user;
- int i, j, max_size;
-
- i = 0;
- max_size = 0;
- gettimeofday(&clock, &zone);
- localclock = localtime( &clock.tv_sec );
- - (void)sprintf(line_buf[i], " ");
- + (void)snprintf(line_buf[i], N_CHARS, " ");
- sizes[i] = strlen(line_buf[i]);
- max_size = max(max_size, sizes[i]);
- i++;
- - (void)sprintf(line_buf[i], "Message from Talk_Daemon@%s at %d:%02d ...",
- - hostname, localclock->tm_hour , localclock->tm_min );
- + (void)snprintf(line_buf[i], N_CHARS,
- + "Message from Talk_Daemon@%s at %d:%02d ...",
- + hostname, localclock->tm_hour , localclock->tm_min );
- sizes[i] = strlen(line_buf[i]);
- max_size = max(max_size, sizes[i]);
- i++;
- - (void)sprintf(line_buf[i], "talk: connection requested by %s@%s",
- - request->l_name, remote_machine);
- +
- + vis_user = malloc(strlen(request->l_name) * 4 + 1);
- + strvis(vis_user, request->l_name, VIS_CSTYLE);
- + (void)snprintf(line_buf[i], N_CHARS,
- + "talk: connection requested by %s@%s", vis_user, remote_machine);
- sizes[i] = strlen(line_buf[i]);
- max_size = max(max_size, sizes[i]);
- i++;
- - (void)sprintf(line_buf[i], "talk: respond with: talk %s@%s",
- - request->l_name, remote_machine);
- + (void)snprintf(line_buf[i], N_CHARS, "talk: respond with: talk %s@%s",
- + vis_user, remote_machine);
- sizes[i] = strlen(line_buf[i]);
- max_size = max(max_size, sizes[i]);
- i++;
- - (void)sprintf(line_buf[i], " ");
- + (void)snprintf(line_buf[i], N_CHARS, " ");
- sizes[i] = strlen(line_buf[i]);
- max_size = max(max_size, sizes[i]);
- i++;
- Index: talkd.c
- ===================================================================
- RCS file: /cvs/freebsd/src/libexec/talkd/talkd.c,v
- retrieving revision 1.5
- diff -u -r1.5 talkd.c
- --- talkd.c 1997/01/14 06:21:01 1.5
- +++ talkd.c 1997/01/18 08:26:44
- @@ -71,7 +71,7 @@
- void timeout();
- long lastmsgtime;
-
- -char hostname[MAXHOSTNAMELEN];
- +char hostname[MAXHOSTNAMELEN + 1];
-
- #define TIMEOUT 30
- #define MAXIDLE 120
-
- For FreeBSD 2.1 based systems:
-
- --- announce.c 1995/05/30 05:46:38 1.3
- +++ announce.c 1997/01/18 08:33:55 1.3.4.1
- @@ -32,7 +32,7 @@
- */
-
- #ifndef lint
- -static char sccsid[] = "@(#)announce.c 8.2 (Berkeley) 1/7/94";
- +static char sccsid[] = "@(#)announce.c 8.3 (Berkeley) 4/28/95";
- #endif /* not lint */
-
- #include <sys/types.h>
- @@ -41,15 +41,18 @@
- #include <sys/time.h>
- #include <sys/wait.h>
- #include <sys/socket.h>
- +
- #include <protocols/talkd.h>
- -#include <sgtty.h>
- +
- #include <errno.h>
- -#include <syslog.h>
- -#include <unistd.h>
- +#include <paths.h>
- #include <stdio.h>
- +#include <stdlib.h>
- #include <string.h>
- -#include <paths.h>
- -
- +#include <syslog.h>
- +#include <unistd.h>
- +#include <vis.h>
- +
- extern char hostname[];
-
- /*
- @@ -77,7 +80,7 @@
-
- #define max(a,b) ( (a) > (b) ? (a) : (b) )
- #define N_LINES 5
- -#define N_CHARS 120
- +#define N_CHARS 256
-
- /*
- * Build a block of characters containing the message.
- @@ -99,33 +102,37 @@
- char line_buf[N_LINES][N_CHARS];
- int sizes[N_LINES];
- char big_buf[N_LINES*N_CHARS];
- - char *bptr, *lptr, *ttymsg();
- + char *bptr, *lptr, *vis_user;
- int i, j, max_size;
-
- i = 0;
- max_size = 0;
- gettimeofday(&clock, &zone);
- localclock = localtime( &clock.tv_sec );
- - (void)sprintf(line_buf[i], " ");
- + (void)snprintf(line_buf[i], N_CHARS, " ");
- sizes[i] = strlen(line_buf[i]);
- max_size = max(max_size, sizes[i]);
- i++;
- - (void)sprintf(line_buf[i], "Message from Talk_Daemon@%s at %d:%02d ...",
- - hostname, localclock->tm_hour , localclock->tm_min );
- + (void)snprintf(line_buf[i], N_CHARS,
- + "Message from Talk_Daemon@%s at %d:%02d ...",
- + hostname, localclock->tm_hour , localclock->tm_min );
- sizes[i] = strlen(line_buf[i]);
- max_size = max(max_size, sizes[i]);
- i++;
- - (void)sprintf(line_buf[i], "talk: connection requested by %s@%s",
- - request->l_name, remote_machine);
- +
- + vis_user = malloc(strlen(request->l_name) * 4 + 1);
- + strvis(vis_user, request->l_name, VIS_CSTYLE);
- + (void)snprintf(line_buf[i], N_CHARS,
- + "talk: connection requested by %s@%s", vis_user, remote_machine);
- sizes[i] = strlen(line_buf[i]);
- max_size = max(max_size, sizes[i]);
- i++;
- - (void)sprintf(line_buf[i], "talk: respond with: talk %s@%s",
- - request->l_name, remote_machine);
- + (void)snprintf(line_buf[i], N_CHARS, "talk: respond with: talk %s@%s",
- + vis_user, remote_machine);
- sizes[i] = strlen(line_buf[i]);
- max_size = max(max_size, sizes[i]);
- i++;
- - (void)sprintf(line_buf[i], " ");
- + (void)snprintf(line_buf[i], N_CHARS, " ");
- sizes[i] = strlen(line_buf[i]);
- max_size = max(max_size, sizes[i]);
- i++;
- Index: talkd.c
- ===================================================================
- RCS file: /home/ncvs/src/libexec/talkd/talkd.c,v
- retrieving revision 1.3
- retrieving revision 1.3.4.1
- diff -u -r1.3 -r1.3.4.1
- --- talkd.c 1995/05/30 05:46:44 1.3
- +++ talkd.c 1997/01/18 08:33:56 1.3.4.1
- @@ -69,7 +69,7 @@
- void timeout();
- long lastmsgtime;
-
- -char hostname[MAXHOSTNAMELEN];
- +char hostname[MAXHOSTNAMELEN + 1];
-
- #define TIMEOUT 30
- #define MAXIDLE 120
-
-
- =============================================================================
- FreeBSD, Inc.
-
- Web Site: http://www.freebsd.org/
- Confidential contacts: security-officer@freebsd.org
- PGP Key: ftp://freebsd.org/pub/CERT/public_key.asc
- Security notifications: security-notifications@freebsd.org
- Security public discussion: security@freebsd.org
-
- Notice: Any patches in this document may not apply cleanly due to
- modifications caused by digital signature or mailer software.
- Please reference the URL listed at the top of this document
- for original copies of all patches if necessary.
- =============================================================================
-
- -----BEGIN PGP SIGNATURE-----
- Version: 2.6.3ia
- Charset: noconv
-
- iQCVAwUBMuCVAVUuHi5z0oilAQGx7gQAiiptKNx7xoeHec1jmBFLsoGBrxO9H3TC
- 0FHl4n3p/MQEO3OEfChepC5coTAe00SjOEpnAZIinHbtVzNaodPs0hyMbQ7UnpPq
- wIRlxsPhxVuS+rbrY62pvn1Iagr4SaMAaseGK18f+Tq2Lbwc6//1bTOBn+Ms980F
- VaXsIaKYinQ=
- =yj1H
- -----END PGP SIGNATURE-----
-
-