The OpenNET Project
 
Search (keywords):  SOFT ARTICLES TIPS & TRICKS SECURITY
LINKS NEWS MAN DOCUMENTATION


PATCH to BIND-8.2.3 to get rid of the, unnecessary, and potentially dangerous fchown() calls


<< Previous INDEX Search src Set bookmark Go to bookmark Next >>
Date: Sat,  8 Sep 2001 14:56:24 -0400 (EDT)
From: (Greg A. Woods) <woods@weird.com>
To: bind-workers@isc.org
Subject: PATCH to BIND-8.2.3 to get rid of the, unnecessary, and potentially dangerous fchown() calls
Cc: (BUGTRAQ: Full Disclosure Security Mailing List) <bugtraq@securityfocus.com>

[[ note this posting is CC'ed to BUGTRAQ.  I know of no current exploits
in BIND-8.2.3, but even so since I'm also enclosing a fix there may be
quite a few people who might want to be able to fix their own versions. ]]

The so-called "support" fix in change 999 of BIND-8.2.3 introduces some
unnecessary, and potentially very dangerous fchown() calls to named.

The worst one is the one that leaves the pid-file writable by the
supposedly untrusted user named has been asked to run as.

The pid-file does not need to be owned, or indeed accessible in any way,
by the user named is running as.  If named is to be restarted through
any means but exec(), when it is running with low privileges, then it
must be restarted by root anyway!

One of the problems with leaving the pid-file writable by the
unprivileged user is of course that on many systems there are vendor
supplied (and sometimes home-grown) administrative control scripts
commonly used to manage daemon processes.  These scripts use the pid
stored in the pid-file to stop the daemon, trigger it to reload its
config, etc.  If the pid-file is writable by the user named is running
as then it is vulnerable should any remote exploit be found for named.
This means a successful remote exploit of named could be used to trick
the sys-admin into killing arbitrary processes, and indeed maybe even
crashing the system.  Some of these scripts naively put at least the
first whole line, and sometimes even the entire contents, from the
pid-file on the command-line they use to invoke kill.  The potential for
danger is probably even higher for these scripts.  [Note that asking the
vendor to fix their scripts is silly and pointless -- there's no way for
the script to know intuitively whether a PID has the "right" value
because if they did then they wouldn't need the pid-file in the first
place, and indeed these scripts rightfully assume that only a privileged
user could have created the pid-file in the first place!]

Another problem is that the pid-file may be located on a very important
file system, and even with low privileges a vulnerability in named could
allow the attacker to fill that file system.

There's also a call to change the ownership of any logging file (which
would only occur if named is explicitly configured to write to its own
log files instead of using syslog).  I don't know yet whether this
happens before named drops its privileges or not, but if so then the
fchown() results in leaving the log file writable by any successful
attacker!

The other calls to fchown() are probably just unnecessary and pointless
since they seem occur only after the file has just been newly created,
and if my quick analysis is correct only ever after named has
permanently given up root privileges too (though my analysis of this
aspect so far is rather incomplete).

If named is intentionally running as root (though I can't imagine why
anyone would still be doing that, except out of laziness) then these
calls will do nothing if the file did not previously exist, but if the
file did exist then these calls will change its ownership to be root,
which is potentially dangerous because although fchown() is used no
checks are made to ensure the file that was opened is indeed freshly
created and/or not tricked into pointing at some other existing file by
a symlink.  Yes normally anyone with any concern about security will
have pointed named into a private directory that's intended to be
writable only by the unprivileged user named is normally expected to run
as.  However that very same user is the one which would be compromised
by a remote vulnerability, and as such there still no protection against
a rogue symlink being created by a successful attacker.

If named is not running as root (as it should not ever be!) then these
calls cannot likely ever do anything (since unlike the pid-file call,
all happen, as far as I can tell with a quick analysis, after named has
relinquished its privileges, so are pointless and unnecessary (which is
perhaps indicated implicitly by the way they are not checked for
failures).

Note the same problem occurs, but in a much more insidious way, in
BIND-9.  I do not yet have a patch to fix BIND-9 [I'm not running it in
production anywhere yet].

-- 
							Greg A. Woods

+1 416 218-0098      VE3TCP      <gwoods@acm.org>     <woods@robohack.ca>
Planix, Inc. <woods@planix.com>;   Secrets of the Weird <woods@weird.com>


Index: src/bin/named/ns_config.c

RCS file: /cvs/misc/bind8/src/bin/named/ns_config.c,v retrieving revision 1.1.1.5 diff -c -r1.1.1.5 ns_config.c *** src/bin/named/ns_config.c 31 Jan 2001 21:03:33 -0000 1.1.1.5 --- src/bin/named/ns_config.c 8 Sep 2001 03:40:31 -0000 *************** *** 1454,1460 **** --- 1454,1462 ---- S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); if (fd < 0) return (NULL); + #if 0 /* ARGH!!!! Making the pid file writable by user_id is a major security hole!!!! */ (void) fchown(fd, user_id, group_id); + #endif stream = fdopen(fd, "w"); if (stream == NULL) (void)close(fd); Index: src/bin/named/ns_main.c
RCS file: /cvs/misc/bind8/src/bin/named/ns_main.c,v retrieving revision 1.1.1.5 diff -c -r1.1.1.5 ns_main.c *** src/bin/named/ns_main.c 31 Jan 2001 21:03:37 -0000 1.1.1.5 --- src/bin/named/ns_main.c 8 Sep 2001 03:29:07 -0000 *************** *** 621,627 **** --- 621,629 ---- return; case EBADF: case ENOTSOCK: + #if 1 /* Note I didn't have this one listed for some reason.... -GAW */ case EFAULT: + #endif /* * If one these happens, we're broken. */ Index: src/bin/named/ns_maint.c
RCS file: /cvs/misc/bind8/src/bin/named/ns_maint.c,v retrieving revision 1.1.1.4 diff -c -r1.1.1.4 ns_maint.c *** src/bin/named/ns_maint.c 31 Jan 2001 21:03:37 -0000 1.1.1.4 --- src/bin/named/ns_maint.c 8 Sep 2001 18:30:52 -0000 *************** *** 667,673 **** --- 667,675 ---- name); return(-1); } + #if 0 /* ARGH!!! this one's totally unnecessary given the file is guaranteed brand new!!! */ (void) fchown(tsig_fd, user_id, group_id); + #endif } memset(secret_buf, 0, sizeof(secret_buf)); Index: src/bin/named/ns_stats.c
RCS file: /cvs/misc/bind8/src/bin/named/ns_stats.c,v retrieving revision 1.1.1.4 diff -c -r1.1.1.4 ns_stats.c *** src/bin/named/ns_stats.c 31 Jan 2001 21:03:41 -0000 1.1.1.4 --- src/bin/named/ns_stats.c 8 Sep 2001 03:49:45 -0000 *************** *** 122,128 **** --- 122,130 ---- server_options->stats_filename); } if (f != NULL) { + #if 0 /* ARGH!!!! */ (void) fchown(fileno(f), user_id, group_id); + #endif fprintf(f, "+++ Host Statistics Cleared +++ (%ld) %s", (long)timenow, checked_ctime(&timenow)); (void) my_fclose(f); *************** *** 143,149 **** --- 145,153 ---- server_options->stats_filename); return; } + #if 0 /* ARGH!!!! */ (void) fchown(fileno(f), user_id, group_id); + #endif fprintf(f, "+++ Statistics Dump +++ (%ld) %s", (long)timenow, checked_ctime(&timenow)); *************** *** 170,176 **** --- 174,182 ---- server_options->memstats_filename); return; } + #if 0 /* ARGH!!!! */ (void) fchown(fileno(f), user_id, group_id); + #endif fprintf(f, "+++ Memory Statistics Dump +++ (%ld) %s", (long)timenow, checked_ctime(&timenow)); Index: src/bin/named/ns_update.c
RCS file: /cvs/misc/bind8/src/bin/named/ns_update.c,v retrieving revision 1.1.1.4 diff -c -r1.1.1.4 ns_update.c *** src/bin/named/ns_update.c 31 Jan 2001 21:03:41 -0000 1.1.1.4 --- src/bin/named/ns_update.c 8 Sep 2001 03:50:10 -0000 *************** *** 145,151 **** --- 145,153 ---- strerror(errno)); return (NULL); } + #if 0 /* ARGH!!!! */ (void) fchown(fileno(fp), user_id, group_id); + #endif if (fseek(fp, 0L, SEEK_END) != 0) { ns_error(ns_log_update, "can't fseek(%s, 0, SEEK_END)", zp->z_updatelog); *************** *** 170,176 **** --- 172,180 ---- strerror(errno)); return (NULL); } + #if 0 /* ARGH!!!! */ (void) fchown(fileno(fp), user_id, group_id); + #endif if (fseek(fp, 0L, SEEK_END) != 0) { ns_error(ns_log_update, "can't fseek(%s, 0, SEEK_END)", zp->z_ixfr_base); Index: src/lib/isc/logging.c
RCS file: /cvs/misc/bind8/src/lib/isc/logging.c,v retrieving revision 1.1.1.4 diff -c -r1.1.1.4 logging.c *** src/lib/isc/logging.c 31 Jan 2001 21:04:45 -0000 1.1.1.4 --- src/lib/isc/logging.c 8 Sep 2001 18:32:45 -0000 *************** *** 156,162 **** --- 156,164 ---- chan->flags |= LOG_CHANNEL_BROKEN; return (NULL); } + #if 0 /* ARGH!!! Don't leave the audit trail writable by the attacker!!! */ (void) fchown(fd, chan->out.file.owner, chan->out.file.group); + #endif chan->out.file.stream = stream; return (stream);

<< Previous INDEX Search src Set bookmark Go to bookmark Next >>



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру