|
COMMAND talkd format string vulnerability SYSTEMS AFFECTED All versions based on announce.cpp from 1983 PROBLEM GOBBLES people found following bug in many vendors implementation of talkd: Technical details ***************** In print_mesg(), located in announce.cpp GOBBLES see this piece of newbie code: void print_mesg(FILE * tf, NEW_CTL_MSG * request, const char * remote_machine, int usercfg, int force_no_sound) { .. const char *remotename = gethostbyname(remotemach)->h_name; .. snprintf(buffer, N_CHARS, \"%s@%s\", request->l_name, remotename); snprintf(line_buf[i], N_CHARS, Options.announce2, buffer); .. if (!(strcmp(localname,remotename))) { snprintf(line_buf[i], N_CHARS, Options.announce3, request->l_name); } else { snprintf(line_buf[i], N_CHARS, Options.announce3, buffer); } .. bptr = big_buf; if (!force_no_sound) /* set if a X announce has been done */ if (sound_or_beep(usercfg)) /* if no sound then : */ *bptr++ = \'^G\'; /* send something to wake them up */ *bptr++ = \'\\r\'; /* add a \\r in case of raw mode */ *bptr++ = \'\\n\'; for (i = 0; i < N_LINES; i++) { /* copy the line into the big buffer */ lptr = line_buf[i]; while (*lptr != \'\\0\') *(bptr++) = *(lptr++); .. fprintf(tf, big_buf); .. Unless reader havent spotted offending code yet, it\'s the fprintf() line! In top of file announce.cpp GOBBLES read: * Copyright (c) 1983 Regents of the University of California. * All rights reserved. License go on to say crap about \"no code based off this can be promoted without the prior consent of the copyright holder. . .\" and other junk, so GOBBLES will not do promotion of exploit code for this vulnerability, just will make fun of sloppy code. The Origin of syslog() Bug ************************** During extensive grep syslog stuff of code, GOBBLES search back and discover some thing of historical importance concerning where original syslog() bug come from, and here is what GOBBLES Security did discover. The test code that comes with sysklogd-1.4.1 contains unformatted syslog() calls. syslog_tst.c: ... if (argc > 1) { if ( (*argv[1] == \'-\') && (*(argv[1]+1) == \'\\0\') ) { while (!feof(stdin)) if ( fgets(bufr, sizeof(bufr), stdin) != (char *) 0 ) { if ( (nl = strrchr(bufr, \'\\n\')) != (char *) 0) *nl = \'\\0\'; syslog(LOG_INFO, bufr); logged += strlen(bufr); if ( logged > 1024 ) { sleep(1); logged = 0; } } } else while (argc-- > 1) syslog(LOG_INFO, argv++[1]); } ... SOLUTION 1. Find and chmod -x all *talkd*-binaries until official patch is released. 2. sed \'s/fprintf\\(tf, big_buf\\);/fprintf\\(tf, \"%s\", big_buf\\);/\'