[4102] in bugtraq
Re: libX11
daemon@ATHENA.MIT.EDU (Paul Szabo)
Thu Feb 27 19:39:05 1997
Date: Fri, 28 Feb 1997 08:16:50 +1100
Reply-To: Paul Szabo <szabo_p@MATHS.SU.OZ.AU>
From: Paul Szabo <szabo_p@MATHS.SU.OZ.AU>
X-To: auscert@auscert.org.au
To: BUGTRAQ@NETSPACE.ORG
A few days ago SNI released an advisory concerning buffer overrun problems
in libX11. Their "fix advice" was to upgrade to X11R6.3, or to remove
setuid/setgid privileges from vulnerable programs (e.g. xload and xterm).
I do not think I can upgrade to the current release of X11: how would I
integrate that into Digital Unix (a.k.a. OSF/1)? And I could not give up the
functionality of xterm...
So instead I wrote the following wrapper, and used it to wrap xload, xterm
and xconsole. My wrapper, and the SNI advisory, included below.
Paul Szabo - System Manager // School of Mathematics and Statistics
psz@maths.usyd.edu.au // University of Sydney, NSW 2006, Australia
-----
/*
sec_wrapper.c -- Wrap setuid program to prevent command line or
environment variable buffer overrun.
Only tested on DUnix V4.0
Does NOT check the values of the arguments and/or environment
(other than checking their lengths), though that functionality
could (should?) be added.
This program is based loosely on the lpr wrapper released with
AUSCERT Advisory AA-96.12. Any errors are my own.
DISCLAIMER: Anything you do with this is at your own risk.
V1.0 26 Feb 97 PSz
Installation instructions
~~~~~~~~~~~~~~~~~~~~~~~~~
1. su to root
2. Determine the full path of the prog you want to wrap, and
its permissions, owner, and group:
# ls -lg /usr/bin/badprog
3. Copy badprog to badprog.real, and change the permissions on it:
# cd /usr/bin
# cp -ip badprog badprog.real
# chmod 711 badprog.real
4. Edit (a copy of) this program and define REAL_PROG (an absolute
pathname), check the settings of MAX_ and GOOD_ variables, then
compile:
# cc -o badprog badprog_wrapper.c
5. Copy this new wrapper program into the directory originally
containing badprog, replacing the existing badprog program.
Use the information found in step #2 and set the same
owner, group, permissions on the new badprog program:
# cp badprog /usr/bin
# cd /usr/bin
# chown root badprog
# chgrp daemon badprog
# chmod 6711 badprog
Check that the permissions, owner and group exactly
match those noted in step #2:
# ls -lg /usr/bin/badprog
6. Check that badprog still works!
*/
/* Make sure REAL_PROG points to the right location */
/* The MAX_ values should be appropriate to the program being wrapped. */
/* The GOOD_ values should be appropriate, leave undefined to skip check. */
/* (Beware: $TERMCAP often contains weird characters.) */
/* #define REAL_PROG "/usr/bin/badprog.real" */
#define MAX_ARGC 50
#define MAX_ARG_LENGTH 1000
#define MAX_ENV_LENGTH 1000
/* #define GOOD_ARG_CHARS "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/_.-" */
/* #define GOOD_ENV_CHARS "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/_.,:+-=" */
#define SYSLOG 1
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef SYSLOG
#include <syslog.h>
#endif
#ifdef SYSLOG
#define sysl(msg) syslog(LOG_ERR,"Possible %s attack by uid %d: %s\n",REAL_PROG,getuid(),msg)
#else
#define sysl(msg)
#endif
#define ZAP(x,err) if (x) { printf("Sorry: %s\n",err); sysl(err); exit(-1); }
#ifndef REAL_PROG
Cannot compile: you do not have REAL_PROG defined
#endif
#if MAX_ARGC > 1000 || MAX_ARGC < 1
Cannot compile: you have a crazy value for MAX_ARGC
#endif
#if MAX_ARG_LENGTH > BUFSIZ || MAX_ARG_LENGTH < 10
Cannot compile: you have a crazy value for MAX_ARG_LENGTH
#endif
#if MAX_ENV_LENGTH > BUFSIZ || MAX_ENV_LENGTH < 10
Cannot compile: you have a crazy value for MAX_ENV_LENGTH
#endif
void main( int argc, char* argv[] /* , char *envp[] */ )
{
int iii, jjj;
char **ccc, *ddd;
extern char **environ;
ZAP( argc<1, "too few arguments" );
ZAP( argc>MAX_ARGC, "too many arguments" );
for( iii=1; iii<argc; iii++ )
{
jjj = strlen(argv[iii]);
ZAP( jjj<1, "argument too short" );
ZAP( jjj>MAX_ARG_LENGTH, "argument too long" );
#ifdef GOOD_ARG_CHARS
ZAP( strspn(argv[iii],GOOD_ARG_CHARS) != jjj, "bad char in argument" );
#endif
}
/* Which one: environ and/or envp ?? */
for( ccc = environ; *ccc; ccc++ )
{
jjj = strlen(*ccc);
ZAP( jjj<2, "environment component too short" );
ZAP( jjj>MAX_ENV_LENGTH, "environment component too long" );
ZAP( !strncmp(*ccc,"LD_",3), "suspicious environment component LD_" );
ddd = strchr(*ccc,'=');
ZAP( (int)ddd < (int)*ccc || (int)ddd >= ((int)*ccc)+jjj || *ddd != '=',
"badly formed environment component" );
#ifdef GOOD_ENV_CHARS
ZAP( strspn(*ccc,GOOD_ENV_CHARS) != jjj, "bad char in environment component" );
#endif
}
/* execve( REAL_PROG, argv, envp ); */
execv( REAL_PROG, argv );
perror( REAL_PROG );
exit( 1 );
}
-----
> From owner-bugtraq@NETSPACE.ORG Tue Feb 25 11:22:38 1997
> Date: Mon, 24 Feb 1997 16:06:43 -0700
> From: David Sacerdote <davids@SECNET.COM>
> Subject: libX11
> To: BUGTRAQ@NETSPACE.ORG
>
> ###### ## ## ######
> ## ### ## ##
> ###### ## # ## ##
> ## ## ### ##
> ###### . ## ## . ######.
>
> Secure Networks Inc.
>
> Security Advisory
> February 24, 1997
>
> Environment Variable Problems in X11
>
>
> While examining the differences between X11R6.1 and X11R6.3, it has come to
> our attention that a number of serious security problems in libX11 were fixed
> between releases. These problems permit unprivileged users to obtain elevated
> access, including group sys, group kmem, and root privileges, depending on the
> operating system and the X11 release. Administrators should be aware that
> these problems are actively being exploited, and should take the precautions
> outlined below to ensure they are not susceptible to these problems.
>
>
> Technical Details
> ~~~~~~~~~~~~~~~~~
>
> In X11R6.1 and earlier, there are many places where libX11 looks at
> environment variables, and then performs string operations on them. X11R6.1
> and earlier, however, perform no bounds checking when doing these string
> operations. Setuid and setgid programs which use functions provided by libX11
> may allow users to obtain elevated privileges.
>
> One of the many examples of flawed code in X11R6.1, in this case from
> GetDflt.c reads:
>
> if (ptr = getenv("HOME"))
> (void) strcpy(dest, ptr);
>
> While the corrected code for this particular exammple in X11R6.3 reads:
>
> if (ptr = getenv("HOME")) {
> (void) strncpy(dest, ptr, len);
> dest[len-1] = '\0';
>
> Note that this code correctly adds a null character at the end of the
> string after the strncpy.
>
>
> Impact
> ~~~~~~
> Depending on platform and X11 release, individuals with shell access can
> obtain elevated access, including group sys, group kmem, and root
> privileges.
>
>
> Vulnerable Systems
> ~~~~~~~~~~~~~~~~~~
> Any system which is running X11R6.1 or earlier, and has at least one setuid or
> setgid program which uses libX11 is vulnerable.
>
> You can perform a simple test to determine whether your system is vulnerable.
> First, set the HOME environment variable to a string at least 2500 characters
> long. Using a sh compatible shell, do this by issuing the commands:
>
> $ HOME=jjjjjjj...jjjjj (2500 repititions of 'j')
> $ export HOME
>
> Using csh or tcsh, use the command:
>
> % setenv HOME jjjjj...jjjjjjj (2500 repititions of 'j')
>
> Then, run a setuid or setgid X program, such as xload. If you are running a
> vulnerable release of X11, you will get an error message including either the
> words "Segmentation Fault" or "Bus error." If the words "Segmentation Fault"
> and "Bus Error" do not appear, and the program operates correctly, you are not
> vulnerable to this problem.
>
> Be aware that if you use a string much shorter than 2500 characters, this test
> will not produce meaningful results, because the length of the buffer in
> question is 2048 characters. Also, if your DISPLAY environment variable does
> not point to a display which you have authorization to connect to, the test
> will not be able to connect to a valid display and therefore will not work.
>
>
> Fix Information
> ~~~~~~~~~~~~~~~
> To fix these problems without loss of functionality, upgrade to the current
> release of X11. You can obtain X11R6.3 by referring to
> http://www.x.org/consortium/GettingX.html
>
> As an alternative workaround, administrators may want to remove setuid and
> setgid bits from vulnerable programs. To find all setuid and setgid programs,
> in the X11 distribution, the following command can be executed:
>
> % cd /usr/X11/bin
> % find . \( -perm -02000 -o -perm -04000 \) -exec ls -l {} \;
> % find . \( -perm -02000 -o -perm -04000 \) -exec chmod ug-s {} \;
>
> Remember to perform the same command if you wish to remove permissions from
> programs stored in other system directories. Keep in mind that that the
> use of this workaround will result in reduced functionality for non-root
> users.
>
>
> Additional Information
> ~~~~~~~~~~~~~~~~~~~~~~
>
> If you have any questions about this advisory, feel free to contact me,
> David Sacerdote, at davids@secnet.com. If you should wish to encrypt
> traffic for me, my pgp key is:
>
> -----BEGIN PGP PUBLIC KEY BLOCK-----
> Version: 2.6.2
>
> mQCNAzJ4qJAAAAEEAOgB7mooQ6NgzcUSIehKUufGsyojutC7phVXZ+p8FnHLLZNB
> BLQEtj5kmfww2A2pR29q4rgPeqEUOjWPlLNdSLby3NI8yKz1AQSQLHAwIDXt/lku
> 8QXClaV6pNIaQSN8cnyyvjH6TYF778yZhYz0mwLqW6dU5whHtP93ojDw1UhtAAUR
> tCtEYXZpZCBTYWNlcmRvdGUgPGRhdmlkc0BzaWxlbmNlLnNlY25ldC5jb20+
> =LtL9
> -----END PGP PUBLIC KEY BLOCK-----
>
> Many thanks to the unknown individual who undertook to fix this set
> of holes in the final days of the X Consortium.
>
> Additional information about the X Windowing System can be found at
> http://www.x.org
>
> You can find Secure Networks papers at ftp://ftp.secnet.com/pub/papers
> and advisories at ftp://ftp.secnet.com/advisories
>
> You can browse our web site at http://www.secnet.com
>
> You can subscribe to our security advisory mailing list by sending mail to
> majordomo@secnet.com with the line "subscribe sni-advisories" in the body of
> the message.
>
>
> Copyright Notice
> ~~~~~~~~~~~~~~~~
> The contents of this advisory are Copyright (C) 1997 Secure Networks Inc,
> and may be distributed freely provided that no fee is charged for
> distribution, and that proper credit is given.