Bugtraq mailing list archives
Re: Xserver stack smashed -- wrapper
From: ulianov () MECANICA MATH UNIBUC RO (Cotfas Vladimir-Marian)
Date: Wed, 14 Jan 1998 17:32:02 +0200
Summary:
On a system where X11R6-based Xserver (R5 is probably affected too) is
installed setuid or setgid (e.g. typical XFree86 installation has XF86_*
setuid root), local users can exploit a buffer overrun in its code and
gain extra privileges (e.g. root privileges when Xserver is setuid root).
Quick vulnerability check:
X :00000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000009
(add -nolock for XFree86, change X to whatever name your Xserver has)
Vulnerable Xserver will crash (Segmentation fault).
(Note: machines immunized against stack smashing--e.g. Linux boxes with
Solar Designer's kernel patch--are probably not vulnerable.)
Quick fix:
* remove setuid/setgid bit from all installed Xservers
* use xdm or a safe setuid wrapper to start Xserver
Details:
X11R6.x Xserver recognizes a runtime argument specifying the desired
display (e.g. X :1). It accepts ANY value regardless of its length
and contents (save from the initial colon).
Excerpt from xc/programs/Xserver/os/access.c (X11R6.3)
/* Reset access control list to initial hosts */
void
ResetHosts (display)
char *display;
{
register HOST *host;
char lhostname[120], ohostname[120];
char *hostname = ohostname;
char fname[100];
[snip]
strcpy (fname, "/etc/X");
strcat (fname, display);
strcat (fname, ".hosts");
if (fd = fopen (fname, "r"))
[snip]
}
Xserver calls ResetHosts() during its startup. A very long value of
"display" (100 + 2*120 + delta bytes) overflows "fname" and corrupts
the stack.
An actual exploit is left as an exercise for the reader. :)
There are probably other vulnerable places in Xserver code. (I have
spotted another buffer overrun in LockServer() (os/utils.c, XFree86
specific) but this one seems to be benign.) Anyone willing to pay me
big bucks for an exhaustive audit is welcome. :)
--Pavel Kankovsky aka Peak (troja.mff.cuni.cz network administration)
[ Boycott Microsoft -- http://www.vcnet.com/bms ]
Here's a wrapper for this bug and for the older XF86 security vulnerability
(i.e. XF86_XX -config /etc/shadow)
Vladimir
----------------------------cut from here-------------------------------
/*
Description: X server wrapper
Goals:
1. wrap the "-config" security vulnerabillity
2. wrap the :000000000000...00000000000000009 potential buffer overflow
Instalation steps:
0. Become root (su -)
1. Modify the X_Server program variable according to your taste
(i.e. the X server true path, not the link to it!)
2. Compile this program as
cc Xserver.c -O4 -o Xserver
3. Copy the resulting binary to /usr/X11/bin, or whatever path you may have
4. chmod 04711 Xserver
5. Suppose your X server is called "XF86_S3"; issue a command
chmod 0711 XF86_S3
6. Remove the old link for X (e.g X -> /usr/X11/bin/XF86_S3)
7. Make a new link
ln -s /usr/X11/bin/Xserver /usr/X11/bin/X
Copyright policy: the GNU Public License.
This program is intended as a temporary patch for an existing X server;
it is provided "as is", the author is not responsible for any
direct/indirect damage(s) caused by its use.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <syslog.h>
#include <pwd.h>
#include <sys/types.h>
/*
This is intended for debugging porposes only.
Do NOT define this for a normal usage!!
*/
#define _DEBUG
#define SIZE 1024
/* guaranteed filled with NULLs by UNIX */
char* args[SIZE];
int argsCount = 0;
char* sccsID =
"@(#) X wrapper 1.0 Copyright (C) 1998 by Vadimir COTFAS (ulianov () mecanica math unibuc ro), Jan 14th 1998";
char *X_Server = "/usr/X11/bin/XF86_S3";
int main(int argc, char* argv[])
{
int i;
uid_t uid, euid;
struct passwd* pass;
openlog("Xserver", LOG_CONS|LOG_NDELAY|LOG_PERROR|LOG_PID, LOG_AUTHPRIV);
uid = getuid(); euid = geteuid();
if(!((uid==0) || (euid==0))){
fprintf(stderr,"Xserver: this program must be run as (setuid) root\n");
exit(1);
}
pass = getpwuid(uid);
for(i=0; i<argc; i++){
char* p;
if((index(argv[i],':') != NULL) && (strlen(argv[i]) > 2)){
syslog(LOG_NOTICE, "potential buff ovrflw at arg #%d user %s",
i, pass->pw_name);
continue;
}
if(strstr(argv[i], "-config")){
syslog(LOG_NOTICE, "security vulnerability at arg #%d user %s \n",
i, pass->pw_name);
i++;
continue;
}
if(argsCount >= SIZE){
syslog(LOG_NOTICE, "too many args (>1024) user %s \n", pass->pw_name);
exit(1);
}
args[argsCount++] = argv[i];
}
args[argsCount] = NULL; /* just to be sure */
#ifdef DEBUG
for(i=0; i<argsCount; i++) printf("%s ", args[i]);
printf("\n");
#endif
if(execv(X_Server, args) < 0){
fprintf(stderr,"Xserver: could not execute the X server ``%s''\n", X_Server);
exit(1);
}
/*NOTREACHED*/
return 0;
}
/* EOF */----
Network Guru Administrator
http://www.mecanica.math.unibuc.ro/~ulianov
Alternate e-mail ulianov () unibuc ro
Home Phone: 40-01-7776598, 40-068-181613
Current thread:
- Re: Xserver stack smashed -- wrapper Cotfas Vladimir-Marian (Jan 14)
- Re: Xserver stack smashed -- wrapper Scott A Crosby (Jan 14)
- <Possible follow-ups>
- Re: Xserver stack smashed -- wrapper John Goerzen (Jan 14)
