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