[8918] in bugtraq

home help back first fref pref prev next nref lref last post

Re: FreeBSD 2.2.5 Security problem

daemon@ATHENA.MIT.EDU (Eivind Eklund)
Mon Jan 4 02:32:38 1999

Date: 	Mon, 4 Jan 1999 00:42:37 +0100
Reply-To: Eivind Eklund <eivind@YES.NO>
From: Eivind Eklund <eivind@YES.NO>
X-To:         Missouri FreeNet Administration <measl@MFN.ORG>
To: BUGTRAQ@NETSPACE.ORG
In-Reply-To:  <Pine.BSF.3.96.990102155924.20783A-100000@greeves.mfn.org>; from
              Missouri FreeNet Administration on Sat, Jan 02,
              1999 at 04:14:22PM -0600

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-officer@FreeBSD.ORG.

> 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.

home help back first fref pref prev next nref lref last post