[8918] in bugtraq
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.