From owner-freebsd-hackers Thu Jul 11 3:51:52 2002 Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 5342937B400 for ; Thu, 11 Jul 2002 03:51:45 -0700 (PDT) Received: from milla.ask33.net (milla.ask33.net [217.197.166.60]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4A8F043E42 for ; Thu, 11 Jul 2002 03:51:44 -0700 (PDT) (envelope-from nick@milla.ask33.net) Received: by milla.ask33.net (Postfix, from userid 1001) id D420D3ABB4D; Thu, 11 Jul 2002 12:52:14 +0200 (CEST) Date: Thu, 11 Jul 2002 12:52:14 +0200 From: Pawel Jakub Dawidek To: freebsd-hackers@freebsd.org Subject: No suid crontab(1). Message-ID: <20020711105214.GJ12920@garage.freebsd.pl> Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-2 Content-Disposition: inline X-PGP-Key-URL: http://garage.freebsd.pl/jules.pgp X-OS: FreeBSD 4.6-STABLE i386 User-Agent: Mutt/1.5.1i Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Hello there. On end of this post You got diif how to remove set-uid-root bit from crontab(1). What You think about it? Some directory and files perms changes: leila:root:~# ls -l /usr/bin/crontab -r-xr-sr-x 1 root crontab 24804 11 Lip 12:37 /usr/bin/crontab leila:root:~# ls -ld /var/cron drwxr-x--- 3 root crontab 512 22 Maj 2001 /var/cron leila:root:~# ls -l /var/cron total 3 -rw-r----- 1 root crontab 5 11 Lip 12:33 allow -rw-r----- 1 root crontab 6 11 Lip 12:33 deny drwxrwx--- 2 root crontab 512 11 Lip 12:37 tabs leila:root:~# ls -lo /var/cron/tabs total 3 ----rw---- 1 giaur crontab uchg 254 11 Lip 12:23 giaur ----rw---- 1 nick crontab uchg 255 11 Lip 12:37 nick -rw------- 1 root crontab uchg 274 11 Lip 12:03 root Of course You have to have crontab group defined in Your /etc/group. If crontab will be broken, attacker can change ONLY his own file, cause of uchg flags on files (yes, uchg, not schg, couse of securelevel). Attacker can't remove any files too cause of uchg too in spite of he has gid of directory /var/cron/tabs owner. Oke, here You got patch: 11 Lip 12:36 2002 diff -lu /usr/src/usr.sbin/cron/crontab/Makefile projects/crontab/Makefile Page 1 --- /usr/src/usr.sbin/cron/crontab/Makefile Wed Apr 25 14:09:24 2001 +++ projects/crontab/Makefile Thu Jul 11 12:25:06 2002 @@ -8,7 +8,8 @@ BINDIR= /usr/bin BINOWN= root -BINMODE=4555 +BINGRP= crontab +BINMODE=2555 INSTALLFLAGS=-fschg .include 11 Lip 12:36 2002 diff -lu /usr/src/usr.sbin/cron/crontab/crontab.c projects/crontab/crontab.c Page 1 --- /usr/src/usr.sbin/cron/crontab/crontab.c Sat Jun 16 05:18:37 2001 +++ projects/crontab/crontab.c Thu Jul 11 12:36:23 2002 @@ -101,7 +101,6 @@ setlinebuf(stderr); #endif parse_args(argc, argv); /* sets many globals, opens a file */ - set_cron_uid(); set_cron_cwd(); if (!allowed(User)) { warnx("you (%s) are not allowed to use this program", User); @@ -280,7 +279,7 @@ log_it(RealUser, Pid, "DELETE", User); (void) sprintf(n, CRON_TAB(User)); - if (unlink(n)) { + if (chflags(n, 0) || unlink(n)) { if (errno == ENOENT) errx(ERROR_EXIT, "no crontab for %s", User); else @@ -328,14 +327,6 @@ goto fatal; } (void) umask(um); -#ifdef HAS_FCHOWN - if (fchown(t, getuid(), getgid()) < 0) { -#else - if (chown(Filename, getuid(), getgid()) < 0) { -#endif - warn("fchown"); - goto fatal; - } if (!(NewCrontab = fdopen(t, "r+"))) { warn("fdopen"); goto fatal; @@ -402,8 +393,8 @@ goto fatal; case 0: /* child */ - if (setuid(getuid()) < 0) - err(ERROR_EXIT, "setuid(getuid())"); + if (setgid(getgid()) < 0) + err(ERROR_EXIT, "setgid(getgid())"); if (chdir("/tmp") < 0) err(ERROR_EXIT, "chdir(/tmp)"); if (strlen(editor) + strlen(Filename) + 2 >= MAX_TEMPSTR) @@ -493,7 +484,7 @@ replace_cmd() { char n[MAX_FNAME], envstr[MAX_ENVSTR], tn[MAX_FNAME]; FILE *tmp; - int ch, eof; + int ch, eof, perm; entry *e; time_t now = time(NULL); char **envp = env_init(); @@ -563,24 +554,18 @@ return (-1); 11 Lip 12:36 2002 diff -lu /usr/src/usr.sbin/cron/crontab/crontab.c projects/crontab/crontab.c Page 2 } -#ifdef HAS_FCHOWN - if (fchown(fileno(tmp), ROOT_UID, -1) < OK) -#else - if (chown(tn, ROOT_UID, -1) < OK) -#endif - { - warn("chown"); - fclose(tmp); unlink(tn); - return (-2); - } - + if (getuid() == ROOT_UID) + perm = 0600; + else + perm = 0060; + #ifdef HAS_FCHMOD - if (fchmod(fileno(tmp), 0600) < OK) + if (fchmod(fileno(tmp), perm) < OK) #else - if (chmod(tn, 0600) < OK) + if (chmod(tn, perm) < OK) #endif { - warn("chown"); + warn("chmod"); fclose(tmp); unlink(tn); return (-2); } @@ -592,11 +577,19 @@ } (void) sprintf(n, CRON_TAB(User)); + chflags(n, 0); if (rename(tn, n)) { warn("error renaming %s to %s", tn, n); unlink(tn); return (-2); } + if (chflags(n, UF_IMMUTABLE) < OK) + { + warn("chflags"); + unlink(n); + return (-2); + } + log_it(RealUser, Pid, "REPLACE", User); poke_daemon(); -- Pawel Jakub Dawidek UNIX Systems Administrator http://garage.freebsd.pl Am I Evil? Yes, I Am. To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message