| Summary: | Cron is being started to early in /etc/rc (potential security hole) | ||
|---|---|---|---|
| Product: | Base System | Reporter: | huntting |
| Component: | misc | Assignee: | freebsd-bugs (Nobody) <bugs> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | Unspecified | ||
| Hardware: | Any | ||
| OS: | Any | ||
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). 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 > 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
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 State Changed From-To: open->analyzed Conceptual securelevel problem. 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 :-) |
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.