Bug 28188

Summary: Cron is being started to early in /etc/rc (potential security hole)
Product: Base System Reporter: huntting
Component: miscAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Unspecified   
Hardware: Any   
OS: Any   

Description huntting 2001-06-16 00:00:02 UTC
Cron allows users to run jobs at boot time by specifying "@reboot".
While this is a very usefull feature, it is also a potential security
hole if these jobs are started before the kern.securelevel level is
raised.

Fix: in /etc/rc, start cron _after_ kern.securelevel is set:



thanx,
brad--IVbL0n4B0rhBKz5bfJQK5UO9W3rb8in7zPn1VM0TCoRDq359
Content-Type: text/plain; name="file.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="file.diff"

--- /etc/rc.orig        Fri Jun 15 16:42:02 2001
+++ /etc/rc     Fri Jun 15 16:42:06 2001
@@ -483,14 +483,6 @@
        ;;
 esac
 
-case ${cron_enable} in
-[Nn][Oo])
-       ;;
-*)
-       echo -n ' cron';        ${cron_program:-/usr/sbin/cron} ${cron_flags}
-       ;;
-esac
-
 case ${lpd_enable} in
 [Yy][Ee][Ss])
        echo -n ' printer';     ${lpd_program:-/usr/sbin/lpd} ${lpd_flags}
@@ -691,6 +683,14 @@
                echo 'Raising kernel security level: '
                sysctl -w kern.securelevel=${kern_securelevel}
        fi
+       ;;
+esac
+
+case ${cron_enable} in
+[Nn][Oo])
+       ;;
+*)
+       echo 'Starting cron';   ${cron_program:-/usr/sbin/cron} ${cron_flags}
        ;;
 esac
 
(forgive me, but the tabs->spaces thing will probably corrupt this patch,
but you get the idea).
How-To-Repeat: Put these in /etc/rc.conf

	kern_securelevel_enable="YES"
	kern_securelevel="0"

And put this in your (non-root) crontab file:

	@reboot /sbin/sysctl kern.securelevel

And reboot.  You should get a mail message indicating that your cron
job was run with kern.securelevel=-1.  Not something ordinary users
should really be doing.
Comment 1 dima 2001-06-16 01:38:37 UTC
Brad Huntting <huntting@glarp.com> writes:
> >Description:
> Cron allows users to run jobs at boot time by specifying "@reboot".
> While this is a very usefull feature, it is also a potential security
> hole if these jobs are started before the kern.securelevel level is
> raised.

This is a general problem; cron just makes it easy to take advantage
of.  The problem is that the securelevel is raised as late as
possible; it is the last thing to happen in /etc/rc in -stable, and
second to last in -current (background fsck's are started after it).
The real solution[1] is to move the setting of securelevel up, above
the starting of most of the non-essential daemons (e.g., sshd, cron,
et al).  Anyone from -security care to comment on the feasibility of
this?  Any reason why it isn't already done like this?  OpenBSD sets
it quite early, FWIW.

Thanks,

					Dima Dorfman
					dima@unixfreak.org

[1] Actually, the real solution is to axe the entire concept of
securelevel.  Of course, this won't be done until a suitable
replacement is available (e.g., MAC).
Comment 2 Crist Clark 2001-06-16 22:34:13 UTC
Dima Dorfman wrote:
> 
> Brad Huntting <huntting@glarp.com> writes:
> > >Description:
> > Cron allows users to run jobs at boot time by specifying "@reboot".
> > While this is a very usefull feature, it is also a potential security
> > hole if these jobs are started before the kern.securelevel level is
> > raised.
> 
> This is a general problem; cron just makes it easy to take advantage
> of.  The problem is that the securelevel is raised as late as
> possible; it is the last thing to happen in /etc/rc in -stable, and
> second to last in -current (background fsck's are started after it).
> The real solution[1] is to move the setting of securelevel up, above
> the starting of most of the non-essential daemons (e.g., sshd, cron,
> et al).  Anyone from -security care to comment on the feasibility of
> this?  Any reason why it isn't already done like this?  OpenBSD sets
> it quite early, FWIW.

Can't comment on the history of it too much, but my guess is that
the usual assumption is that all of the steps in the startup process
are trusted (the rc-scripts), so there is no need to kick up the
securelevel until the end. I am familiar with the way OpenBSD does it.
You have to watch that you start "non-essential" daemons like NTP
before you notch up the securelevel and other little things.

But you are right of course, the most secure way to go is raise 
securelevel as early as possible in the boot sequence (although
off of the top of my head, I can't think of anything besides cron(8)
that would run non-"trusted" code). I will have a look at the -STABLE
scripts to see what we can do in the 4.x branch. As for -CURRENT,
it would be a good idea for the people working on importing the new
NetBSD rc-scripts to keep this in mind... Of course, maybe (hope, hope)
the NetBSD people already handled this intelligently? (I'll try to
peek at that too if I can bear to update my -CURRENT source over a
dial-up.)
-- 
Crist J. Clark                                Network Security Engineer
crist.clark@globalstar.com                    Globalstar, L.P.
(408) 933-4387                                FAX: (408) 933-4926
Comment 3 huntting 2001-06-17 00:06:33 UTC
> But you are right of course, the most secure way to go is raise 
> securelevel as early as possible in the boot sequence (although
> off of the top of my head, I can't think of anything besides cron(8)
> that would run non-"trusted" code).[...]

Sendmail (runs programs specified in .forward files), inetd (ftp,
telnet, etc) sshd (user shells), httpd (cgi-bin's)....  Cron's
@reboot is just the easiest one to exploit.


brad
Comment 4 Crist Clark 2001-06-18 20:49:52 UTC
Brad Huntting wrote:
> 
> > But you are right of course, the most secure way to go is raise
> > securelevel as early as possible in the boot sequence (although
> > off of the top of my head, I can't think of anything besides cron(8)
> > that would run non-"trusted" code).[...]
> 
> Sendmail (runs programs specified in .forward files), inetd (ftp,
> telnet, etc) sshd (user shells), httpd (cgi-bin's)....  Cron's
> @reboot is just the easiest one to exploit.

Right, those others would be some pretty tough races to win.

But anyway, I had a look at the -STABLE rc scripts to see what is
what. As for Dima's original question about the feasiblity, IMHO,
it will take a lot of work to do this. Rearranging the current 
startup so that securelevel can be raised earlier, will _probably_
not be a huge problem. However, the for -STABLE, I would expect
we would want to do _a lot_ of testing to verify rearranging 
something minor like the rc-scripts does not break anything before
it goes prime time. That's the easy part. The harder part will be
designing a new mechanism for local rc-scripts (hard as in "bikeshed 
alert"). It is quite feasible the local admin might have some scripts
that need to run before securelevel is notched up, while most scripts
do not. At present, all scripts in /usr/local/etc/rc.d, and the other
local scripts, are run at once. Do we make a new directory for 
pre-securelevel scripts (won't break stuff, but might not appeal
to many people's asthetics)? Have a naming convention in rc.d (different
asthetic problems and possible back-compatibility issues)?

Anyway, if we are to do this, this is how I would see partition 
things,

  Basic Startup (mounting filesystems, bringing up interfaces 
                 and network, etc.)
  Pre-Securelevel Daemons in Standard Startup
  Pre-Securelevel Daemons in Local Startup
  Raise Securelevel
  Post-Securelevel Daemons in Standard Startup
  Post-Securelevel Daemons in Local Startup

I say "daemons" above since that is the most common thing, but it
can be other code as well.

One other thing that I noticed, the log_in_vain sysctl(8)s are not
set until wa-ay at the end. I thought that this might be a problem
since I presumed that the log_in_vain's were CTLFLAG_SECURE. However,
they are not. Nor could I find any network related sysctl's that 
were. In fact,

  # cd /usr/src
  # fgrep -r 'CTLFLAG_SECURE' .
  ./sys/kern/kern_sysctl.c:       ((oid->oid_kind & CTLFLAG_SECURE) && securelevel > 0)))
  ./sys/sys/sysctl.h:#define CTLFLAG_SECURE   0x08000000      /* Permit set only if securelevel<=0 */
  #

Am I not looking in the right place? I sure thought that there are 
some sysctl's that are locked at elevated securelevel.

[Insert here the ususal disclaimer that securelevel(8) is lame and will 
someday be replaced by real MAC extensions to the OS so do not sweat
the details of securelevel(8) too much.]
-- 
Crist J. Clark                                Network Security Engineer
crist.clark@globalstar.com                    Globalstar, L.P.
(408) 933-4387                                FAX: (408) 933-4926

The information contained in this e-mail message is confidential,
intended only for the use of the individual or entity named above.  If
the reader of this e-mail is not the intended recipient, or the employee
or agent responsible to deliver it to the intended recipient, you are
hereby notified that any review, dissemination, distribution or copying
of this communication is strictly prohibited.  If you have received this
e-mail in error, please contact postmaster@globalstar.com
Comment 5 Jens Schweikhardt freebsd_committer freebsd_triage 2002-08-10 16:10:50 UTC
State Changed
From-To: open->analyzed

Conceptual securelevel problem.
Comment 6 Mike Makonnen freebsd_committer freebsd_triage 2003-02-23 22:17:34 UTC
State Changed
From-To: analyzed->closed

The new rc.d system takes care of the specific complaints in 
the PR, namely that cron was being run before securelevel. The 
other issues raised as a result of this are moot now that rc.d 
is in the tree and the default. An admin can very easily move the 
setting of the securelevel earlier or later according to his/her 
situation. Tools not policy :-)