COMMAND

    ccdconfig

SYSTEMS AFFECTED

    FreeBSD, NetBSD, OpenBSD

PROBLEM

    Niall  Smart  found  vulnerability  in  ccdconfig.   FreeBSD   and
    NetBSD's ccdconfig doesn't do  proper checking of the  argument to
    -f:

        [nsmart@ginseng ~]$ ccdconfig -U -f /dev/mem 2>&1 | strings | grep Charlie
        root:iDeLeTeDiT:0:0::0:0:Charlie: No such file or directory
        ^C

    You have to cat /etc/master.passwd  in another window to get  this
    to work though so perhaps its not very easily exploitable, but  is
    worth fixing nonetheless.

    Jess Kitchen added following that if you are persistent with  chfn
    in the background while grepping  the ccdconfig output for :0:  or
    something similar, you will encounter chunks of /etc/master.passwd
    which you  can reconstruct  gradually after  a bit  of tidying up.
    It seems to be a bit hit and miss but root does eventually make an
    appearance  along  with  the  majority  of  the  other users under
    FreeBSD 2.2 and 3.0.

SOLUTION

    This  bug  was  also  spotted  by  olivier@secnet.com and fixed in
    OpenBSD some time ago.  Quick fix should be:

        chmod g-s /sbin/ccdconfig

    FreeBSD and  NetBSD have  been notified  of the  problem and  have
    fixed it in their source tree's (FreeBSD-current,  FreeBSD-stable,
    NetBSD-current).   Retrieve  the  patched  ccdconfig.c and compile
    yourself a new  ccdconfig.  Here  are the changes  that applied to
    FreeBSD.  They  are taken from  the OpenBSD source  base, possibly
    with minor formatting  tweaks, and seem  to represent the  work of
    Theo de Raadt and oliver@secnet.com.  These problems were fixed in
    OpenBSD somewhere at start of 1997.

    Index: ccdconfig.c
    ===================================================================
    RCS file: /home/imp/FreeBSD/CVS/src/sbin/ccdconfig/ccdconfig.c,v
    retrieving revision 1.7
    diff -u -r1.7 ccdconfig.c
    --- ccdconfig.c       1997/06/10 11:04:50     1.7
    +++ ccdconfig.c 1997/12/30 05:08:24
    @@ -161,6 +161,15 @@
            if (options > 1)
                    usage();

    +       /*
    +        * Discard setgid privileges if not the running kernel so that bad
    +        * guys can't print interesting stuff from kernel memory.
    +        */
    +       if (core != NULL || kernel != NULL || action != CCD_DUMP) {
    +               setegid(getgid());
    +               setgid(getgid());
    +       }
    +
            switch (action) {
                    case CCD_CONFIG:
                    case CCD_UNCONFIG:
    @@ -307,11 +316,16 @@
            char line[_POSIX2_LINE_MAX];
            char *cp, **argv;
            int argc, rval;
    +       gid_t egid;

    +       egid = getegid();
    +       setegid(getgid());
            if ((f = fopen(ccdconf, "r")) == NULL) {
    +               setegid(egid);
                    warn("fopen: %s", ccdconf);
                    return (1);
            }
    +       setegid(egid);

            while (fgets(line, sizeof(line), f) != NULL) {
                    argc = 0;