Re: FreeBSD 2.2.5 Security problem

From: Eivind Eklund (eivindat_private)
Date: Sun Jan 03 1999 - 15:42:37 PST

  • Next message: debian-security-announceat_private: "[SECURITY] New versions of netstd fixes buffer overflows"

    On Sat, Jan 02, 1999 at 04:14:22PM -0600, Missouri FreeNet Administration wrote:
    > Greetings, how is everyone after the 30 day pig-out? ;-0
    >
    > We originally posted this problem to the FreeBSD GNATS system on
    > December 20th, and still haven't heard so much as an acknowledgement
    > of the report (GNATS#: i386/9141).  I figured with the holidays, they
    > were all busy, and would [eventually] get to it, but today I checked
    > and saw that several GNATS reports on either side of this one (some
    > as recent as today) have been looked at, processed, and even closed!
    > So...
    
    The PR was misfiled; it was filed as a i386 PR (meaning a bug
    in the i386-specific code of FreeBSD).
    
    Apart from this, the PR system is not an effective way of reporting
    security problems.  The right way to report a security problem is to
    mail security-officerat_private
    
    > FreeBSD 2.2.5-R (other rev's not tested) fail to log penetration attempts
    > on quiescent systems properly when using syslog (to any target).  Failed
    > login attempts (*any* number of them) will not be reported until a user name
    > which is *different* from the failed name is entered.  For example, I can
    > attempt to penetrate the root password *all day long* without getting a
    > syslog report, provided a name other than root is not entered.  The reson
    > for this is that there is an attempt to de-verbosify syslog reporting in
    > FBSD which accumulates a counter for events, and then reports a cumulative
    > total.  In this attempt to save verbiage, they are tallying all the failed
    > attempts, *rather* than *reporting* them!
    
    Your "*any* number" is incorrect.  The correct answer is "10", unless
    you've changed the default for your login class in /etc/login.conf.
    After 10 attempted logins, the problem will be logged by the part of
    login that check for attacks.
    
    > This is (obviously) not going to be an issue on a busy system, as
    > *someone* other than the target account is likely to log in and flush the
    > counter report, but on a selected system, such as a name server, this
    > could be a devastating flaw...
    
    The limit is on a per-login-execution basis.  As long as the attacker
    has the tty for that execution of login, it will not matter if
    somebody else log in.
    
    However, looking carefully at the code, I do notice that there is a
    bug whereby a 'silent attack' could be done (though not at all like
    you've stated above).  I think I fixed this problem in rev 1.44 of
    login.c:
    
    Index: login.c
    ===================================================================
    RCS file: /home/ncvs/src/usr.bin/login/login.c,v
    retrieving revision 1.43
    diff -u -r1.43 -r1.44 login.c
    --- login.c     1998/11/21 02:22:14     1.43
    +++ login.c     1999/01/03 23:22:05
    @@ -111,6 +111,9 @@
      */
     u_int  timeout = 300;
    
    +/* Buffer for signal handling of timeout */
    +jmp_buf timeout_buf;
    +
     struct passwd *pwd;
     int    failures;
     char   *term, *envinit[1], *hostname, *username, *tty;
    @@ -132,15 +135,23 @@
            time_t warntime;
            uid_t uid, euid;
            char *domain, *p, *ttyn;
    -       char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10];
    +       char tbuf[MAXPATHLEN + 2];
    +       char tname[sizeof(_PATH_TTY) + 10];
            char localhost[MAXHOSTNAMELEN];
            char *shell = NULL;
            login_cap_t *lc = NULL;
    
    -       (void)signal(SIGALRM, timedout);
    -       (void)alarm(timeout);
            (void)signal(SIGQUIT, SIG_IGN);
            (void)signal(SIGINT, SIG_IGN);
    +       if (setjmp(timeout_buf)) {
    +               if (failures)
    +                       badlogin(tbuf);
    +               (void)fprintf(stderr,
    +                             "Login timed out after %d seconds\n", timeout);
    +               exit(0);
    +       }
    +       (void)signal(SIGALRM, timedout);
    +       (void)alarm(timeout);
            (void)setpriority(PRIO_PROCESS, 0, 0);
    
            openlog("login", LOG_ODELAY, LOG_AUTH);
    @@ -250,7 +261,6 @@
                    if (failures && strcmp(tbuf, username)) {
                            if (failures > (pwd ? 0 : 1))
                                    badlogin(tbuf);
    -                       failures = 0;
                    }
                    (void)strncpy(tbuf, username, sizeof tbuf-1);
                    tbuf[sizeof tbuf-1] = '\0';
    @@ -769,8 +779,7 @@
     timedout(signo)
            int signo;
     {
    -       (void)fprintf(stderr, "Login timed out after %d seconds\n", timeout);
    -       exit(0);
    +       longjmp(timeout_buf, signo);
     }
    
    
    @@ -829,6 +838,7 @@
                        "%d LOGIN FAILURE%s ON %s, %s",
                        failures, failures > 1 ? "S" : "", tty, name);
            }
    +       failures = 0;
     }
    
     #undef UNKNOWN
    
    
    Eivind.
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:27:11 PDT