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)