This may be old news, but here it is anyway...
While working of a port of "lpr/lpd" to Windows95 I noticed some
weaknesses in the implementation of the LPR protocol. Mostly it
appears to affect BSD based UNIX's. I found it using the source for
BSD4.4, and tested it on "Linux Slackware 2.2.0". I have also tested it
on AIX 4.1.5 and it seems to be OK. Unfortunately, (or Fortunately
depending on how you look at it), I only have access to these two
operating systems.
Explaining this assumes that you are familiar with [RFC-1179 Line Pinter
Daemon Protocol]. If you are not familiar or have not read it, it may
be obtained via FTP from ftp://nic.ddn.mil/rfc/rfc1179.txt
The possibilities are as follows:
1.) Obtaining hard (or possibly soft) copies of any file on the system.
2.) Deleting any file on the system.
3.) Creating a file on the system.
4.) Mail bombing.
There are a few requirements that need to be met in order to perform
these actions.
1.) Must be 'root' on the source machine.
NOTE: Under Windows95 the user already has 'root' status. This means
that anyone on a Win95 box
can bind network sockets to the reserved ports.
2.) Must have or obtain permission to print to the target machine.
Usually machines on the same network will have permission to print to
each other, but that may not always be the case.
3.) Must have or obtain access to the target printer. Otherwise how
will you get your printout?
HOW IT WORKS...
When lpd sends a file to a remote machine it creates a control file used
to instruct the remote machine on how to process the incoming print
job. These commands are outlined in [RFC-1179]. It is the
implementation of the control commands that provide the weakness.
1.) Obtaining hard (or possibly soft) copies of any file on the system.
The control command 'f' causes a file to be printed as text.
The syntax is: f filename [LF]
Therefore, by inserting the line: "f/etc/shadow" into the control file
you will cause the
Shadow password file to be printed. (Hard copy)
If the print queue points to a network printer then it would be possible
to capture the packets. (Soft copy)
2.) Delete any file on the system.
The control command 'U' instructs the remote machine to "unlink" the
file upon completion of the job.
The syntax is: U filename [LF]
Therefore, by inserting the line: "U/vmlinuz" into the control file you
will cause the Linux kernel to be
removed from the file system.
3.) Create a file on the remote system.
This is a little trickier, in that BSD4.4 takes the filename that you
specify and appends its view of the calling machine's hostname to it.
However, BSD4.4 starts at the sixth character.
The syntax is 2 size [SP] filename [LF]. Where '2' is the octet 2 not
the character, size is the size of the file in bytes, filename is ...
(DUH).
- From RECVJOB.C
case '\2': /* read cf file */
size = 0;
while (*cp >= '0' && *cp <= '9')
size = size * 10 + (*cp++ - '0');
if (*cp++ != ' ')
break;
/*
* host name has been authenticated, we use our
* view of the host name since we may be passed
* something different than what gethostbyaddr()
* returns
*/
HERE -----------> strcpy(cp + 6, from);
strcpy(tfname, cp);
tfname[0] = 't';
if (!chksize(size)) {
(void) write(1, "\2", 1);
continue;
}
if (!readfile(tfname, size)) {
rcleanup(0);
continue;
}
if (link(tfname, cp) < 0)
frecverr("%s: %m", tfname);
(void) unlink(tfname);
tfname[0] = '\0';
nfiles++;
continue;
The result is this:
/rc becomes /rc
/etc/passwd becomes /etc/passwd.www.yourhost.com
This is accomplished by using the printer command of '2' (receive
control file)
Therefore by sending the printer command '2/rc' and then sending our
file, we have created a file in the root directory called 'rc'.
By sending '2/home/yourfriend/somefile' and the your file you will have
sent somefile to yourfriend ... and even put it in their home
directory. Of course it will have the name somefile.www.yourhost.com,
but he got it none the less.
4.) Mail bombing.
The control command 'M' instructs lpd to mail the user when the job is
finished.
The syntax is: M username [LF]
Therefore by adding the line: "Mjoeuser@www.somewhere.com" you will
cause joeuser to receive mail notification about the print job. By
adding several thousand of these lines, well you get the idea.
SOLUTIONS ???
These holes are due to the implementation of the lpr protocol and the
fact that lpd runs as root. I am sure that there may be many solutions
to this, but At first glance I think that by checking for a '/' in the
filenames would cause the program to react when someone tries to print
files from outside of the queue directory.
As far as the mail bomb, maybe by checking the destination host with
lpd's view of the caller, but that wouldn't allow for someone to print
from one account and get the mail at another. IE the boss getting
notices when the report is finished.
Let me know if I have miss-stated something.
Bennett