Casinos Not On GamstopNon Gamstop CasinosCasinos Not On GamstopOnline Casinos UKNon Gamstop Casino
1st Jan 1996 [SBWID-215]
COMMAND
	    talkd
SYSTEMS AFFECTED
	    FreeBSD 1.0, 1.1, 2.1.0, 2.1.5, 2.1.6, 2.1.6.1
PROBLEM
	    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.   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.  Credit
	    for this goes to AUSCERT.
SOLUTION
	    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.
	    Workaround  would  be  to  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`
	
	Patches that follows 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
	
	

Internet highlights