--- Begin Message ---
- To: Debian Bug Tracking System <submit@bugs.debian.org>
- Subject: xboing is locally exploitable - can gain an setgid(games) shell.
- From: Steve Kemp <skx@tardis.ed.ac.uk>
- Date: Wed, 01 Jan 2003 16:17:19 +0000
- Message-id: <E18TlYV-0006rk-00@hell.my.flat>
Package: xboing
Version: 2.4-26
Severity: normal
Tags: security upstream patch
xboing
------
xboing is an attactive game based upon the old
breakout, or arkenoid type games.
It is available in both Debian stable, and unstable
distributions.
vulnerability
-------------
Due to improper bounds checking it is possible for
a malicious user to gain a shell with membership
group 'games'. (The binary is installed setgid games).
details
-------
Environmental variables are used without being
bounds-checked in any way, from the source code:
highscore.c:
/* Use the environment variable if it exists */
if ((str = getenv("XBOING_SCORE_FILE")) != NULL)
strcpy(filename, str);
else
strcpy(filename, HIGH_SCORE_FILE);
misc.c:
if ((ptr = getenv("HOME")) != NULL)
(void) strcpy(dest, ptr);
Neither of these checks are boundschecked, and will allow
arbitary shell code to be run.
There are other, similar, pieces of code. I believe the
enclosed patch spots them all.
demonstration
-------------
The following shell sessions shows the instruction pointer
'eip' being overwritten with user supplied data, taken from
the environmental variable(s).
skx@hell:~$ export XBOING_SCORE_FILE=`perl -e 'print "x" x 5000'`
skx@hell:~$ export HOME=`perl -e 'print "x" x 5000'`
skx@hell:~$ gdb /usr/games/xboing
GNU gdb 5.3-debian
Copyright 2002 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 "i386-linux"...(no debugging symbols found)...
(gdb) r
Starting program: /usr/games/xboing
(no debugging symbols found)...(no debugging symbols found)...
(no debugging symbols found)...(no debugging symbols found)...
(no debugging symbols found)...(no debugging symbols found)...
(no debugging symbols found)...(no debugging symbols found)...
XBoing - Please wait Steve Kemp, initialising xboing ...
int_snddev: Cannot open sound device
Can't init soundIt library. yech..
XBoing - Warning: Audio unavailable or not supported.
XBoing - Warning: Cannot open high score file for reading.
(no debugging symbols found)...(no debugging symbols found)...
Program received signal SIGSEGV, Segmentation fault.
0x78787878 in ?? ()
(gdb) info all
eax 0x0 0
ecx 0x0 0
edx 0x0 0
ebx 0x9 9
esp 0xbfffd1d0 0xbfffd1d0
ebp 0x78787878 0x78787878
esi 0x26e 622
edi 0x80f6f28 135229224
eip 0x78787878 0x78787878 <<<<<< Bingo. Ahem.
eflags 0x10246 66118
patch
-----
The enclosed patches fix up this improper uses.
Steve
---
# Debian Security Audit Project
http://www.steve.org.uk/Debian/
--- demo.c-orig 2003-01-01 16:11:27.000000000 +0000
+++ demo.c 2003-01-01 16:11:35.000000000 +0000
@@ -154,7 +154,7 @@
/* Construct the demo level filename */
if ((str = getenv("XBOING_LEVELS_DIR")) != NULL)
- sprintf(levelPath, "%s/demo.data", str);
+ snprintf(levelPath, sizeof(levelPath),"%s/demo.data", str);
else
sprintf(levelPath, "%s/demo.data", LEVEL_INSTALL_DIR);
--- editor.c-orig 2003-01-01 16:10:36.000000000 +0000
+++ editor.c 2003-01-01 16:11:15.000000000 +0000
@@ -213,7 +213,7 @@
/* Construct the Edit level filename */
if ((str = getenv("XBOING_LEVELS_DIR")) != NULL)
- sprintf(levelPath, "%s/editor.data", str);
+ snprintf(levelPath,sizeof(levelPath)-1, "%s/editor.data", str);
else
sprintf(levelPath, "%s/editor.data", LEVEL_INSTALL_DIR);
@@ -958,8 +958,8 @@
if ((num > 0) && (num <= MAX_NUM_LEVELS))
{
/* Construct the Edit level filename */
- if ((str2 = getenv("XBOING_LEVELS_DIR")) != NULL)
- sprintf(levelPath, "%s/level%02ld.data", str2, (u_long) num);
+ if ((str2 = getenv("XBOING_LEVELS_DIR")) != NULL)
+ snprintf(levelPath, sizeof(levelPath)-1,"%s/level%02ld.data", str2, (u_long) num);
else
sprintf(levelPath, "%s/level%02ld.data",
LEVEL_INSTALL_DIR, (u_long) num);
@@ -1017,9 +1017,9 @@
num = atoi(str);
if ((num > 0) && (num <= MAX_NUM_LEVELS))
{
- /* Construct the Edit level filename */
- if ((str2 = getenv("XBOING_LEVELS_DIR")) != NULL)
- sprintf(levelPath, "%s/level%02ld.data", str2, (u_long) num);
+ /* Construct the Edit level filename */
+ if ((str2 = getenv("XBOING_LEVELS_DIR")) != NULL)
+ snprintf(levelPath, sizeof(levelPath)-1,"%s/level%02ld.data", str2, (u_long) num);
else
sprintf(levelPath, "%s/level%02ld.data",
LEVEL_INSTALL_DIR, (u_long) num);
--- file.c-orig 2003-01-01 16:11:50.000000000 +0000
+++ file.c 2003-01-01 16:11:58.000000000 +0000
@@ -139,7 +139,7 @@
/* Construct the level filename */
if ((str = getenv("XBOING_LEVELS_DIR")) != NULL)
- sprintf(levelPath, "%s/level%02ld.data", str, newLevel);
+ snprintf(levelPath,sizeof(levelPath), "%s/level%02ld.data", str, newLevel);
else
sprintf(levelPath, "%s/level%02ld.data", LEVEL_INSTALL_DIR, newLevel);
--- highscore.c-orig 2003-01-01 16:08:42.000000000 +0000
+++ highscore.c 2003-01-01 16:09:22.000000000 +0000
@@ -1023,7 +1023,7 @@
{
/* Use the environment variable if it exists */
if ((str = getenv("XBOING_SCORE_FILE")) != NULL)
- strcpy(filename, str);
+ strncpy(filename, str, sizeof(filename)-1);
else
strcpy(filename, HIGH_SCORE_FILE);
}
@@ -1095,7 +1095,7 @@
{
/* Use the environment variable if it exists */
if ((str = getenv("XBOING_SCORE_FILE")) != NULL)
- strcpy(filename, str);
+ strncpy(filename, str, sizeof(filename)-1);
else
strcpy(filename, HIGH_SCORE_FILE);
}
@@ -1218,7 +1218,7 @@
/* Use the environment variable if it exists */
if ((str = getenv("XBOING_SCORE_FILE")) != NULL)
- strcpy(filename, str);
+ strncpy(filename, str, sizeof(filename)-1);
else
strcpy(filename, HIGH_SCORE_FILE);
--- misc.c-orig 2003-01-01 16:12:15.000000000 +0000
+++ misc.c 2003-01-01 16:12:35.000000000 +0000
@@ -431,7 +431,7 @@
*/
if ((ptr = getenv("HOME")) != NULL)
- (void) strcpy(dest, ptr);
+ (void) strncpy(dest, ptr,sizeof(dest)-1);
else
{
/* HOME variable is not present so get USER var */
--- preview.c-orig 2003-01-01 16:10:16.000000000 +0000
+++ preview.c 2003-01-01 16:10:23.000000000 +0000
@@ -139,7 +139,7 @@
/* Construct the Preview level filename */
if ((str = getenv("XBOING_LEVELS_DIR")) != NULL)
- sprintf(levelPath, "%s/level%02d.data", str, lnum);
+ snprintf(levelPath, sizeof(levelPath)-1, "%s/level%02d.data", str, lnum);
else
sprintf(levelPath, "%s/level%02d.data", LEVEL_INSTALL_DIR, lnum);
-- System Information:
Debian Release: testing/unstable
Architecture: i386
Kernel: Linux hell.my.flat 2.4.19 #7 Fri Aug 16 23:28:59 BST 2002 i686
Locale: LANG=C, LC_CTYPE=C
Versions of packages xboing depends on:
ii libc6 2.3.1-8 GNU C Library: Shared libraries an
ii xlibs 4.2.1-4 X Window System client libraries
-- no debconf information
--- End Message ---