From owner-freebsd-bugs Wed Apr 12 00:30:02 1995 Return-Path: bugs-owner Received: (from majordom@localhost) by freefall.cdrom.com (8.6.10/8.6.6) id AAA00440 for bugs-outgoing; Wed, 12 Apr 1995 00:30:02 -0700 Received: (from gnats@localhost) by freefall.cdrom.com (8.6.10/8.6.6) id AAA00432 ; Wed, 12 Apr 1995 00:30:01 -0700 Date: Wed, 12 Apr 1995 00:30:01 -0700 Message-Id: <199504120730.AAA00432@freefall.cdrom.com> From: pritc003@maroon.tc.umn.edu Reply-To: pritc003@maroon.tc.umn.edu To: freebsd-bugs Subject: bin/338: Cron allows users to obtain root access In-Reply-To: Your message of Wed, 12 Apr 1995 02:23:32 -0500 <199504120723.CAA04652@mpp.com> Sender: bugs-owner@FreeBSD.org Precedence: bulk >Number: 338 >Category: bin >Synopsis: Cron allows users to obtain root access >Confidential: no >Severity: serious >Priority: high >Responsible: freebsd-bugs (FreeBSD bugs mailing list) >State: open >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Apr 12 00:30:01 1995 >Originator: Mike Pritchard >Organization: >Release: FreeBSD 2.1.0-Development i386 >Environment: >Description: Cron can allow users to obtain root access the same way that the atrun command allowed. >How-To-Repeat: See all of the relavent "atrun" mail for a detailed description. Basically, just modify the MAILTO variable in a users crontab file in the same way that the atrun mail information was changed to spoof sendmail. >Fix: Cron was changed to only accept MAILTO variables that point to user names that actually exist in the password file. This disallows users from passing arguments to sendmail and spoofing it into running as root and giving them root access. If cron detected that a user name did not exist, and it is able to find a user name to send the mail to, it will add a: X-Cron-Err: User specified in MAILTO variable does not exist header line to the mail message to give the user some idea of why their mail isn't going where they wanted. Here is the patch to /usr/src/usr.sbin/cron/cron/do_command.c to fix the problem: *** orig/do_command.c Wed Apr 12 01:31:00 1995 --- do_command.c Wed Apr 12 01:58:28 1995 *************** *** 28,33 **** --- 28,34 ---- #if defined(SYSLOG) # include #endif + #include static void child_process __P((entry *, user *)), *************** *** 76,81 **** --- 77,83 ---- int stdin_pipe[2], stdout_pipe[2]; register char *input_data; char *usernm, *mailto; + int badmailto = 0; int children = 0; Debug(DPROC, ("[%d] child_process('%s')\n", getpid(), e->cmd)) *************** *** 358,366 **** --- 360,385 ---- /* if we are supposed to be mailing, MAILTO will * be non-NULL. only in this case should we set * up the mail command and subjects and stuff... + * + * Verify that the username we are being asked to + * mail to actually exists. This is to prevent + * spoofing the mail delivery program. */ if (mailto) { + struct passwd *pwd; + + if ((pwd = getpwnam(mailto)) == NULL) { + Debug(DPROC, ("[%d] MAILTO user (%s) does not exist\n", + getpid(), mailto)) + badmailto = 1; + if ((pwd = getpwnam(usernm)) != NULL) + mailto = usernm; + else + mailto = NULL; + } + } + if (mailto) { register char **env; auto char mailcmd[MAX_COMMAND]; auto char hostname[MAXHOSTNAMELEN]; *************** *** 384,389 **** --- 403,415 ---- for (env = e->envp; *env; env++) fprintf(mail, "X-Cron-Env: <%s>\n", *env); + /* + * Give the user some idea of why their mail + * didn't go where they expected if we + * rejected their MAILTO variable. + */ + if (badmailto) + fprintf(mail, "X-Cron-Err: User specified in MAILTO variable does not exist\n"); fprintf(mail, "\n"); /* this was the first char from the pipe >Audit-Trail: >Unformatted: